AWS - Lambda Layers Persistence
Lambda Layers
Warstwa Lambda to archiwum .zip, które może zawierać dodatkowy kod lub inne treści. Warstwa może zawierać biblioteki, niestandardowe środowisko uruchomieniowe, dane lub pliki konfiguracyjne.
Możliwe jest dołączenie do pięciu warstw na funkcję. Gdy dołączasz warstwę do funkcji, zawartość jest wypakowywana do katalogu /opt
w środowisku wykonawczym.
Z domyślnie, warstwy, które tworzysz, są prywatne dla twojego konta AWS. Możesz zdecydować się na udostępnienie warstwy innym kontom lub uczynić warstwę publiczną. Jeśli twoje funkcje korzystają z warstwy opublikowanej przez inne konto, twoje funkcje mogą nadal korzystać z wersji warstwy po jej usunięciu lub po cofnięciu twojego dostępu do warstwy. Jednak nie możesz utworzyć nowej funkcji ani zaktualizować funkcji korzystających z usuniętej wersji warstwy.
Funkcje wdrożone jako obraz kontenera nie używają warstw. Zamiast tego pakujesz swoje preferowane środowisko uruchomieniowe, biblioteki i inne zależności do obrazu kontenera podczas budowania obrazu.
Python load path
Ścieżka ładowania, której Python użyje w lambda, jest następująca:
Sprawdź, jak drugie i trzecie pozycje są zajmowane przez katalogi, w których lambda layers dekompresują swoje pliki: /opt/python/lib/python3.9/site-packages
i /opt/python
Jeśli atakujący zdołałby wprowadzić tylne drzwi do używanej warstwy lambda lub dodać jedną, która będzie wykonywać dowolny kod, gdy załadowana zostanie wspólna biblioteka, będzie mógł wykonywać złośliwy kod przy każdym wywołaniu lambda.
Dlatego wymagania są następujące:
Sprawdź biblioteki, które są ładowane przez kod ofiary
Stwórz bibliotekę proxy z warstwami lambda, która będzie wykonywać niestandardowy kod i ładować oryginalną bibliotekę.
Wstępnie załadowane biblioteki
Podczas nadużywania tej techniki napotkałem trudność: Niektóre biblioteki są już załadowane w czasie działania Pythona, gdy twój kod jest wykonywany. Spodziewałem się znaleźć takie rzeczy jak os
czy sys
, ale nawet biblioteka json
była załadowana.
Aby nadużyć tę technikę utrzymywania, kod musi załadować nową bibliotekę, która nie jest załadowana, gdy kod jest wykonywany.
Dzięki kodowi Pythona takiemu jak ten, możliwe jest uzyskanie listy bibliotek, które są wstępnie załadowane w czasie działania Pythona w lambda:
A oto lista (sprawdź, czy takie biblioteki jak os
lub json
są już dostępne)
I oto lista bibliotek, które lambda zawiera zainstalowane domyślnie: https://gist.github.com/gene1wood/4a052f39490fae00e0c3
Backdooring warstwy Lambda
W tym przykładzie załóżmy, że kod docelowy importuje csv
. Będziemy wprowadzać backdoor w imporcie biblioteki csv
.
Aby to zrobić, stworzymy katalog csv z plikiem __init__.py
w ścieżce, która jest ładowana przez lambda: /opt/python/lib/python3.9/site-packages
Następnie, gdy lambda zostanie wykonana i spróbuje załadować csv, nasz plik __init__.py
zostanie załadowany i wykonany.
Ten plik musi:
Wykonać nasz ładunek
Załadować oryginalną bibliotekę csv
Możemy zrobić to obie rzeczy za pomocą:
Then, create a zip with this code in the path python/lib/python3.9/site-packages/__init__.py
and add it as a lambda layer.
You can find this code in https://github.com/carlospolop/LambdaLayerBackdoor
The integrated payload will wysłać dane uwierzytelniające IAM na serwer PIERWSZY RAZ, gdy zostanie wywołany lub PO zresetowaniu kontenera lambda (zmiana kodu lub zimna lambda), ale inne techniki takie jak poniższe mogą być również zintegrowane:
External Layers
Note that it's possible to use lambda layers from external accounts. Moreover, a lambda can use a layer from an external account even if it doesn't have permissions. Also note that the maksymalna liczba warstw, które może mieć lambda, to 5.
Therefore, in order to improve the versatility of this technique an attacker could:
Backdoor an existing layer of the user (nothing is external)
Utworzyć warstwę w swoim koncie, dać konto ofiary dostęp do używania warstwy, skonfigurować warstwę w Lambdzie ofiary i usunąć uprawnienia.
Lambda nadal będzie mogła używać warstwy, a ofiara nie będzie miała łatwego sposobu na pobranie kodu warstwy (oprócz uzyskania powłoki rev wewnątrz lambdy)
Ofiara nie zobaczy zewnętrznych warstw używanych z
aws lambda list-layers
Last updated