AWS - Lambda Privesc
lambda
Más información sobre lambda en:
AWS - Lambda Enumiam:PassRole
, lambda:CreateFunction
, (lambda:InvokeFunction
| lambda:InvokeFunctionUrl
)
iam:PassRole
, lambda:CreateFunction
, (lambda:InvokeFunction
| lambda:InvokeFunctionUrl
)Los usuarios con los permisos iam:PassRole
, lambda:CreateFunction
y lambda:InvokeFunction
pueden escalar sus privilegios.
Pueden crear una nueva función Lambda y asignarle un rol IAM existente, otorgando a la función los permisos asociados con ese rol. El usuario puede luego escribir y subir código a esta función Lambda (con un rev shell, por ejemplo).
Una vez que la función está configurada, el usuario puede activar su ejecución y las acciones previstas invocando la función Lambda a través de la API de AWS. Este enfoque permite efectivamente al usuario realizar tareas indirectamente a través de la función Lambda, operando con el nivel de acceso otorgado al rol IAM asociado a ella.\
Un atacante podría abusar de esto para obtener un rev shell y robar el token:
También podrías abusar de los permisos del rol de lambda desde la propia función lambda. Si el rol de lambda tenía suficientes permisos, podrías usarlo para otorgarte derechos de administrador:
También es posible filtrar las credenciales del rol de la lambda sin necesidad de una conexión externa. Esto sería útil para Lambdas aisladas de red utilizadas en tareas internas. Si hay grupos de seguridad desconocidos filtrando tus shells inversos, este fragmento de código te permitirá filtrar directamente las credenciales como la salida de la lambda.
Impacto Potencial: Privesc directo al rol de servicio lambda arbitrario especificado.
Ten en cuenta que, aunque pueda parecer interesante, lambda:InvokeAsync
no permite por sí solo ejecutar aws lambda invoke-async
, también necesitas lambda:InvokeFunction
iam:PassRole
, lambda:CreateFunction
, lambda:AddPermission
iam:PassRole
, lambda:CreateFunction
, lambda:AddPermission
Al igual que en el escenario anterior, puedes otorgarte el permiso lambda:InvokeFunction
si tienes el permiso lambda:AddPermission
Impacto Potencial: Privesc directo al rol de servicio lambda arbitrario especificado.
iam:PassRole
, lambda:CreateFunction
, lambda:CreateEventSourceMapping
iam:PassRole
, lambda:CreateFunction
, lambda:CreateEventSourceMapping
Los usuarios con permisos de iam:PassRole
, lambda:CreateFunction
y lambda:CreateEventSourceMapping
(y potencialmente dynamodb:PutItem
y dynamodb:CreateTable
) pueden escalar privilegios de manera indirecta incluso sin lambda:InvokeFunction
.
Pueden crear una función Lambda con código malicioso y asignarle un rol IAM existente.
En lugar de invocar directamente la Lambda, el usuario configura o utiliza una tabla DynamoDB existente, vinculándola a la Lambda a través de un mapeo de fuente de eventos. Esta configuración asegura que la función Lambda se active automáticamente al ingresar un nuevo elemento en la tabla, ya sea por la acción del usuario o por otro proceso, invocando indirectamente la función Lambda y ejecutando el código con los permisos del rol IAM pasado.
Si DynamoDB ya está activo en el entorno de AWS, el usuario solo necesita establecer el mapeo de la fuente de eventos para la función Lambda. Sin embargo, si DynamoDB no está en uso, el usuario debe crear una nueva tabla con la transmisión habilitada:
Ahora es posible conectar la función Lambda a la tabla DynamoDB creando un mapeo de origen de eventos:
Con la función Lambda vinculada al flujo de DynamoDB, el atacante puede activar indirectamente la Lambda al activar el flujo de DynamoDB. Esto se puede lograr insertando un elemento en la tabla de DynamoDB:
Impacto Potencial: Privesc directo al rol de servicio de lambda especificado.
lambda:AddPermission
lambda:AddPermission
Un atacante con este permiso puede otorgarse a sí mismo (o a otros) cualquier permiso (esto genera políticas basadas en recursos para otorgar acceso al recurso):
Impacto Potencial: Privesc directo al rol de servicio de lambda utilizado al otorgar permiso para modificar el código y ejecutarlo.
lambda:AddLayerVersionPermission
lambda:AddLayerVersionPermission
Un atacante con este permiso puede otorgarse a sí mismo (o a otros) el permiso lambda:GetLayerVersion
. Podría acceder a la capa y buscar vulnerabilidades o información sensible.
Impacto Potencial: Acceso potencial a información sensible.
lambda:UpdateFunctionCode
lambda:UpdateFunctionCode
Los usuarios que poseen el permiso lambda:UpdateFunctionCode
tienen el potencial de modificar el código de una función Lambda existente que está vinculada a un rol de IAM.
El atacante puede modificar el código de la lambda para exfiltrar las credenciales de IAM.
Aunque el atacante puede no tener la capacidad directa de invocar la función, si la función Lambda ya existe y está operativa, es probable que se active a través de flujos de trabajo o eventos existentes, facilitando así indirectamente la ejecución del código modificado.
Impacto Potencial: Privesc directo al rol de servicio de lambda utilizado.
lambda:UpdateFunctionConfiguration
lambda:UpdateFunctionConfiguration
RCE a través de variables de entorno
Con estos permisos es posible agregar variables de entorno que harán que Lambda ejecute código arbitrario. Por ejemplo, en python es posible abusar de las variables de entorno PYTHONWARNING
y BROWSER
para hacer que un proceso de python ejecute comandos arbitrarios:
Para otros lenguajes de scripting, hay otras variables de entorno que puedes usar. Para más información, consulta las subsecciones de lenguajes de scripting en:
RCE a través de Lambda Layers
Lambda Layers permite incluir código en tu función lambda pero almacenándolo por separado, de modo que el código de la función puede permanecer pequeño y varias funciones pueden compartir código.
Dentro de lambda, puedes verificar las rutas desde donde se carga el código de python con una función como la siguiente:
Estos son los lugares:
/var/task
/opt/python/lib/python3.7/site-packages
/opt/python
/var/runtime
/var/lang/lib/python37.zip
/var/lang/lib/python3.7
/var/lang/lib/python3.7/lib-dynload
/var/lang/lib/python3.7/site-packages
/opt/python/lib/python3.7/site-packages
/opt/python
Por ejemplo, la biblioteca boto3 se carga desde /var/runtime/boto3
(4ª posición).
Explotación
Es posible abusar del permiso lambda:UpdateFunctionConfiguration
para agregar una nueva capa a una función lambda. Para ejecutar código arbitrario, esta capa necesita contener alguna biblioteca que la lambda va a importar. Si puedes leer el código de la lambda, podrías encontrar esto fácilmente, también ten en cuenta que podría ser posible que la lambda ya esté usando una capa y podrías descargar la capa y agregar tu código allí.
Por ejemplo, supongamos que la lambda está usando la biblioteca boto3, esto creará una capa local con la última versión de la biblioteca:
Puedes abrir ./lambda_layer/boto3/__init__.py
y agregar la puerta trasera en el código global (una función para exfiltrar credenciales o obtener un shell inverso, por ejemplo).
Luego, comprime ese directorio ./lambda_layer
y sube la nueva capa de lambda en tu propia cuenta (o en la de la víctima, pero puede que no tengas permisos para esto).
Ten en cuenta que necesitas crear una carpeta de python y poner las bibliotecas allí para sobrescribir /opt/python/boto3. Además, la capa debe ser compatible con la versión de python utilizada por la lambda y si la subes a tu cuenta, debe estar en la misma región:
Ahora, haz que la capa lambda subida sea accesible por cualquier cuenta:
Y adjunta la capa de lambda a la función lambda de la víctima:
El siguiente paso sería invocar la función nosotros mismos si podemos o esperar hasta que se invoque por medios normales, que es el método más seguro.
Una manera más sigilosa de explotar esta vulnerabilidad se puede encontrar en:
AWS - Lambda Layers PersistenceImpacto Potencial: Privesc directo al rol de servicio de lambda utilizado.
iam:PassRole
, lambda:CreateFunction
, lambda:CreateFunctionUrlConfig
, lambda:InvokeFunctionUrl
iam:PassRole
, lambda:CreateFunction
, lambda:CreateFunctionUrlConfig
, lambda:InvokeFunctionUrl
Quizás con esos permisos puedas crear una función y ejecutarla llamando a la URL... pero no pude encontrar una manera de probarlo, ¡así que házmelo saber si lo haces!
Lambda MitM
Algunas lambdas van a estar recibiendo información sensible de los usuarios en parámetros. Si obtienes RCE en una de ellas, puedes exfiltrar la información que otros usuarios le están enviando, revísalo en:
AWS - Steal Lambda RequestsReferencias
Last updated