AWS - Lambda Layers Persistence
Warstwy Lambda
Warstwa Lambda to archiwum plików .zip, które może zawierać dodatkowy kod lub inne treści. Warstwa może zawierać biblioteki, niestandardowy środowisko uruchomieniowe, dane lub pliki konfiguracyjne.
Można dołączyć do pięciu warstw na funkcję. Gdy dołączysz warstwę do funkcji, zawartość jest wypakowywana do katalogu /opt
w środowisku wykonawczym.
Domyślnie warstwy, które tworzysz, są prywatne dla twojego konta AWS. Możesz wybrać, aby udostępnić warstwę innym kontom lub udostępnić warstwę publicznie. 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 uprawnienia do dostępu do warstwy. Nie można jednak utworzyć nowej funkcji ani aktualizować funkcji przy użyciu usuniętej wersji warstwy.
Funkcje wdrożone jako obraz kontenerowy nie korzystają z warstw. Zamiast tego pakujesz preferowane środowisko uruchomieniowe, biblioteki i inne zależności do obrazu kontenerowego podczas budowania obrazu.
Ścieżka ładowania Pythona
Ścieżka ładowania, którą Python użyje w lambdzie, jest następująca:
Sprawdź, jak drugi i trzeci pozycje są zajmowane przez katalogi, w których warstwy lambdy rozpakowują swoje pliki: /opt/python/lib/python3.9/site-packages
i /opt/python
Jeśli atakujący zdoła wstawić używaną warstwę lambdy lub dodać taką, która będzie wykonywać arbitralny kod podczas ładowania wspólnej biblioteki, będzie mógł wykonać złośliwy kod przy każdym wywołaniu lambdy.
Dlatego wymagane są:
Sprawdź biblioteki, które są ładowane przez kod ofiary
Utwórz bibliotekę proxy z warstwami lambdy, 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 wykonania kodu w pythonie. Spodziewałem się znaleźć rzeczy takie jak os
lub sys
, ale nawet biblioteka json
była załadowana.
Aby nadużyć tej techniki trwałego dostępu, kod musi załadować nową bibliotekę, która nie jest załadowana podczas wykonywania kodu.
Z pomocą takiego kodu w pythonie można uzyskać listę bibliotek, które są wstępnie załadowane w czasie wykonania pythona w lambdzie:
A to jest lista (sprawdź, czy biblioteki takie jak os
lub json
są już tam)
Oto lista bibliotek, które są domyślnie zainstalowane w lambdzie: [https://gist.github.com/gene1wood/4a052f39490fae00e0c3]
Infekowanie warstw Lambdy
W tym przykładzie załóżmy, że docelowy kod importuje csv
. Zamierzamy zainfekować import biblioteki csv
.
Aby to zrobić, utworzymy katalog csv z plikiem __init__.py
w ścieżce wczytywanej przez lambdę: /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 to zrobić za pomocą:
Następnie utwórz archiwum zip z tym kodem w ścieżce python/lib/python3.9/site-packages/__init__.py
i dodaj go jako warstwę lambdy.
Kod można znaleźć tutaj
Zintegrowany ładunek wyśle dane uwierzytelniające IAM do serwera PIERWSZY RAZ, gdy zostanie wywołany lub PO zresetowaniu kontenera lambdy (zmiana kodu lub zimna lambda), ale inne techniki takie jak poniższe mogą również zostać zintegrowane:
Zewnętrzne warstwy
Zauważ, że można używać warstw lambdy z zewnętrznych kont. Ponadto, lambda może używać warstwy z zewnętrznego konta nawet jeśli nie ma uprawnień. Zauważ również, że maksymalna liczba warstw, jakie może mieć lambda, to 5.
Dlatego, aby zwiększyć wszechstronność tej techniki, atakujący mógłby:
Zainfekować istniejącą warstwę użytkownika (nic nie jest zewnętrzne)
Utworzyć warstwę w swoim koncie, dać dostęp kontu ofiary do użycia 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