AWS - Lambda Layers Persistence
Capas de Lambda
Una capa de Lambda es un archivo de archivo .zip que puede contener código adicional u otro contenido. Una capa puede contener bibliotecas, un tiempo de ejecución personalizado, datos o archivos de configuración.
Es posible incluir hasta cinco capas por función. Cuando incluyes una capa en una función, los contenidos se extraen al directorio /opt
en el entorno de ejecución.
Por defecto, las capas que creas son privadas para tu cuenta de AWS. Puedes optar por compartir una capa con otras cuentas o hacer la capa pública. Si tus funciones consumen una capa que publicó una cuenta diferente, tus funciones pueden seguir utilizando la versión de la capa después de que se haya eliminado, o después de que se haya revocado tu permiso para acceder a la capa. Sin embargo, no puedes crear una nueva función o actualizar funciones utilizando una versión de capa eliminada.
Las funciones implementadas como una imagen de contenedor no utilizan capas. En su lugar, empaquetas tu tiempo de ejecución preferido, bibliotecas y otras dependencias en la imagen del contenedor cuando construyes la imagen.
Ruta de carga de Python
La ruta de carga que Python utilizará en lambda es la siguiente:
Verifique cómo los directorios en las posiciones segunda y tercera están ocupados por los directorios donde se descomprimen los archivos de las capas de Lambda: /opt/python/lib/python3.9/site-packages
y /opt/python
Si un atacante logra instalar un backdoor en una capa de Lambda utilizada o agregar una que ejecute código arbitrario cuando se cargue una biblioteca común, podrá ejecutar código malicioso en cada invocación de la lambda.
Por lo tanto, los requisitos son:
Verificar las bibliotecas que son cargadas por el código de las víctimas
Crear una biblioteca proxy con capas de Lambda que ejecutará código personalizado y cargará la biblioteca original.
Bibliotecas precargadas
Al abusar de esta técnica, encontré una dificultad: Algunas bibliotecas ya están cargadas en el tiempo de ejecución de Python cuando se ejecuta su código. Esperaba encontrar cosas como os
o sys
, pero incluso la biblioteca json
estaba cargada.
Para abusar de esta técnica de persistencia, el código necesita cargar una nueva biblioteca que no esté cargada cuando se ejecute el código.
Con un código Python como este, es posible obtener la lista de bibliotecas que están precargadas dentro del tiempo de ejecución de Python en Lambda:
Y esta es la lista (verifica que las bibliotecas como os
o json
ya estén allí)
Y esta es la lista de bibliotecas que lambda incluye instaladas por defecto: https://gist.github.com/gene1wood/4a052f39490fae00e0c3
Infiltración en Capas de Lambda
En este ejemplo supongamos que el código objetivo está importando csv
. Vamos a estar infiltrando la importación de la biblioteca csv
.
Para hacer eso, vamos a crear el directorio csv con el archivo __init__.py
en él en una ruta que es cargada por lambda: /opt/python/lib/python3.9/site-packages
Entonces, cuando se ejecute la lambda e intente cargar csv, nuestro archivo __init__.py
será cargado y ejecutado.
Este archivo debe:
Ejecutar nuestra carga útil
Cargar la biblioteca csv original
Podemos hacer ambas cosas con:
Luego, crea un zip con este código en la ruta python/lib/python3.9/site-packages/__init__.py
y agrégalo como una capa lambda.
Puedes encontrar este código en https://github.com/carlospolop/LambdaLayerBackdoor
La carga útil integrada enviará las credenciales IAM a un servidor LA PRIMERA VEZ que se invoque o DESPUÉS de reiniciar el contenedor lambda (cambio de código o lambda fría), pero también se podrían integrar otras técnicas como las siguientes:
Capas Externas
Ten en cuenta que es posible usar capas lambda de cuentas externas. Además, una lambda puede usar una capa de una cuenta externa incluso si no tiene permisos. También ten en cuenta que el número máximo de capas que una lambda puede tener es 5.
Por lo tanto, para mejorar la versatilidad de esta técnica un atacante podría:
Inyectar un backdoor en una capa existente del usuario (nada es externo)
Crear una capa en su cuenta, dar acceso a la cuenta de la víctima para usar la capa, configurar la capa en la Lambda de la víctima y eliminar el permiso.
La Lambda seguirá pudiendo usar la capa y la víctima no tendrá una forma sencilla de descargar el código de las capas (aparte de obtener una reverse shell dentro de la lambda)
La víctima no verá las capas externas utilizadas con
aws lambda list-layers
Última actualización