AWS - Lambda Enum

Apoya a HackTricks

Lambda

Amazon Web Services (AWS) Lambda se describe como un servicio de cómputo que permite la ejecución de código sin la necesidad de provisionar o gestionar servidores. Se caracteriza por su capacidad de manejar automáticamente la asignación de recursos necesarios para la ejecución del código, asegurando características como alta disponibilidad, escalabilidad y seguridad. Un aspecto significativo de Lambda es su modelo de precios, donde los cargos se basan únicamente en el tiempo de cómputo utilizado, eliminando la necesidad de inversiones iniciales o compromisos a largo plazo.

Para llamar a una lambda es posible llamarla tan frecuentemente como se desee (con Cloudwatch), exponer un URL endpoint y llamarla, llamarla a través de API Gateway o incluso basado en eventos como cambios en datos en un bucket S3 o actualizaciones en una tabla DynamoDB.

El código de una lambda se almacena en /var/task.

Pesos de Aliases de Lambda

Una Lambda puede tener varias versiones. Y puede tener más de 1 versión expuesta a través de aliases. Los pesos de cada una de las versiones expuestas dentro de un alias decidirán qué alias recibe la invocación (puede ser 90%-10% por ejemplo). Si el código de uno de los aliases es vulnerable puedes enviar solicitudes hasta que la versión vulnerable reciba el exploit.

Políticas de Recursos

Las políticas de recursos de Lambda permiten dar acceso a otros servicios/cuentas para invocar la lambda, por ejemplo. Por ejemplo, esta es la política para permitir que cualquiera acceda a una lambda expuesta vía URL:

O esta para permitir que un API Gateway la invoque:

Proxies de Base de Datos de Lambda

Cuando hay cientos de solicitudes concurrentes de lambda, si cada una de ellas necesita conectar y cerrar una conexión a una base de datos, simplemente no va a funcionar (las lambdas son sin estado, no pueden mantener conexiones abiertas). Entonces, si tus funciones Lambda interactúan con RDS Proxy en lugar de tu instancia de base de datos. Maneja el agrupamiento de conexiones necesario para escalar muchas conexiones simultáneas creadas por funciones Lambda concurrentes. Esto permite que tus aplicaciones Lambda reutilicen conexiones existentes, en lugar de crear nuevas conexiones para cada invocación de función.

Sistemas de Archivos EFS de Lambda

Para preservar e incluso compartir datos, las Lambdas pueden acceder a EFS y montarlos, por lo que Lambda podrá leer y escribir desde él.

Capas de Lambda

Una capa de Lambda es un archivo comprimido .zip que puede contener código adicional u otro contenido. Una capa puede contener bibliotecas, un runtime 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 elegir 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 continuar usando la versión de la capa después de que se haya eliminado, o después de que se revoque tu permiso para acceder a la capa. Sin embargo, no puedes crear una nueva función o actualizar funciones usando una versión de capa eliminada.

Las funciones desplegadas como una imagen de contenedor no usan capas. En su lugar, empaquetas tu runtime preferido, bibliotecas y otras dependencias en la imagen del contenedor cuando construyes la imagen.

Extensiones de Lambda

Las extensiones de Lambda mejoran las funciones al integrarse con diversas herramientas de monitoreo, observabilidad, seguridad y gobernanza. Estas extensiones, añadidas a través de archivos .zip usando capas de Lambda o incluidas en despliegues de imágenes de contenedor, operan en dos modos: interno y externo.

  • Las extensiones internas se fusionan con el proceso de runtime, manipulando su inicio usando variables de entorno específicas del lenguaje y scripts wrapper. Esta personalización se aplica a una variedad de runtimes, incluyendo Java Correto 8 y 11, Node.js 10 y 12, y .NET Core 3.1.

  • Las extensiones externas se ejecutan como procesos separados, manteniendo la alineación operativa con el ciclo de vida de la función Lambda. Son compatibles con varios runtimes como Node.js 10 y 12, Python 3.7 y 3.8, Ruby 2.5 y 2.7, Java Corretto 8 y 11, .NET Core 3.1, y runtimes personalizados.

Enumeración

aws lambda get-account-settings

# List functions and get extra config info
aws lambda list-functions
aws lambda get-function --function-name <function_name>
aws lambda get-function-configuration --function-name <function_name>
aws lambda list-function-event-invoke-configs --function-name <function_name>
## Check for creds in env vars
aws lambda list-functions | jq '.Functions[].Environment'
## Download & check the source code
aws lambda get-function --function-name "<func_name>" --query 'Code.Location'
wget -O lambda-function.zip <url-from-previous-query>

# Get Lambda URL (if any)
aws lambda list-function-url-configs --function-name <function_name>
aws lambda get-function-url-config --function-name <function_name>

# Get who has permissions to invoke the Lambda
aws lambda get-policy --function-name <function_name>

# Versions and Aliases
aws lambda list-versions-by-function --function-name <func_name>
aws lambda list-aliases --function-name <func_name>

# List layers
aws lambda list-layers
aws lambda list-layer-versions --layer-name <name>
aws lambda get-layer-version --layer-name <name> --version-number <ver>
aws lambda get-layer-version-by-arn --arn <name> #Get external ARNs

# List other metadata
aws lambda list-event-source-mappings
aws lambda list-code-signing-configs
aws lambda list-functions-by-code-signing-config --code-signing-config-arn <arn>

Invocar una lambda

Manual

# Invoke function
aws lambda invoke --function-name FUNCTION_NAME /tmp/out
## Some functions will expect parameters, they will access them with something like:
## target_policys = event['policy_names']
## user_name = event['user_name']
aws lambda invoke --function-name <name> --cli-binary-format raw-in-base64-out --payload '{"policy_names": ["AdministratorAccess], "user_name": "sdf"}' out.txt

Via exposed URL

Si la función Lambda está expuesta a través de una URL, puedes intentar enumerar la función Lambda directamente a través de la URL expuesta. Esto puede proporcionar información sobre la configuración de la función, los permisos y otros detalles relevantes.

curl -X GET <exposed-lambda-url>

Via AWS CLI

La AWS CLI proporciona comandos para interactuar con los servicios de AWS, incluidas las funciones Lambda. Puedes usar la AWS CLI para enumerar las funciones Lambda en una cuenta.

aws lambda list-functions --region <region>

Via IAM Roles

Si tienes acceso a las credenciales de IAM, puedes usarlas para enumerar las funciones Lambda a las que el rol tiene acceso.

aws lambda list-functions --region <region> --profile <profile>

Via CloudTrail

CloudTrail registra todas las llamadas a la API de AWS, incluidas las relacionadas con Lambda. Puedes buscar en los registros de CloudTrail para encontrar información sobre las funciones Lambda.

aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=CreateFunction

Via CloudFormation

Si las funciones Lambda se crean a través de CloudFormation, puedes enumerarlas inspeccionando las pilas de CloudFormation.

aws cloudformation describe-stacks --region <region>

Via Serverless Framework

El Serverless Framework es una herramienta popular para implementar funciones Lambda. Puedes enumerar las funciones Lambda inspeccionando los archivos de configuración del Serverless Framework.

sls info --verbose

Via Terraform

Terraform es otra herramienta popular para implementar infraestructura como código. Puedes enumerar las funciones Lambda inspeccionando los archivos de configuración de Terraform.

terraform state list | grep aws_lambda_function
aws lambda list-function-url-configs --function-name <function_name> #Get lambda URL
aws lambda get-function-url-config   --function-name <function_name> #Get lambda URL

Call Lambda function via URL

Ahora es el momento de descubrir posibles funciones lambda para ejecutar:

aws --region us-west-2 --profile level6 lambda list-functions

Una función lambda llamada "Level6" está disponible. Vamos a averiguar cómo llamarla:

aws --region us-west-2 --profile level6 lambda get-policy --function-name Level6

Ahora, que sabes el nombre y el ID, puedes obtener el Nombre:

aws --profile level6 --region us-west-2 apigateway get-stages --rest-api-id "s33ppypa75"

Y finalmente llama a la función accediendo (nota que el ID, Nombre y nombre de la función aparecen en la URL): https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6

URL:https://<rest-api-id>.execute-api.<region>.amazonaws.com/<stageName>/<funcName>

Otros Triggers

Hay muchas otras fuentes que pueden activar una lambda

Privesc

En la siguiente página puedes ver cómo abusar de los permisos de Lambda para escalar privilegios:

AWS - Lambda Privesc

Acceso No Autenticado

AWS - Lambda Unauthenticated Access

Post Explotación

AWS - Lambda Post Exploitation

Persistencia

AWS - Lambda Persistence

Referencias

Apoya HackTricks

Last updated