Wstęp
W ramach testów bezpieczeństwa trafiają się błędy, które nie zawsze umożliwiają w sposób jednoznaczny pokazanie wpływu na bezpieczeństwo testowanego systemu. Szczególnymi przypadkami są błędy z podklasy typu Blind – niejawne, gdzie informacja zwrotna, potwierdzająca występowanie danej podatności w postaci enumeracji wewnętrznych zasobów jest zawarta np. w czasie odpowiedzi serwera czy pojedynczym statusie błędu bazującym na wartości przesyłanej typu prawda/fałsz.
Jednym z takich przypadków, na które zespół pentesterów TestArmy natknął się podczas prac była podatność Blind Server Side Request Forgery.
Czym jest klasa podatności Server Side Request Forgery?
W wielkim skrócie – błędy typu Server Side Request Forgery umożliwiają zmuszenie danej aplikacji do wykonania żądania – najczęściej z wykorzystaniem protokołu HTTP(S) pod konkretny zasób w celu zwrócenia jego zawartości.
Atakowana zawartość może być dowolna – kwestia ograniczenia w postaci przetwarzania odpowiedzi przez aplikację.
W ramach zobrazowania i pokazania wpływu na bezpieczeństwo aplikacji można wykonać:
- odczyt wrażliwych informacji z metadanych instancji chmurowych np. EC2, Lambda,
- enumerację wewnętrznych zasobów sieciowych,
- odczyt lokalnych plików przechowywanych na dysku.
Studium przypadku – opis
Wykorzystując czas zwrotny oraz lakoniczny komunikat odpowiedzi pod konkretny zasób, testerom bezpieczeństwa udało się namierzyć instancję usługi Redis, która jest znana z tego, że w konkretnej wersji była podatna na atak umożliwiający wykonanie zdalnej komendy systemowej (RCE) wykorzystując technikę Rogue Server – Master/Slave Replication.
Wyzwaniem okazało się przygotowanie prawidłowego, złośliwego ładunku (ang. payload), który wykorzystałby lukę w instancji Redis w celu nawiązania tzw. połączenia zwrotnego powłoki systemu (ang. reverse shell), tym samym uzyskując dostęp do serwera aplikacji oraz łut szczęścia (podatna wersja Redis).
Studium przypadku – przygotowanie środowiska
Ze względu na typ błędu – Blind – należało w pewien sposób lokalnie, na maszynie pentestera odwzorować usługę Redis w podatnej wersji w celu jej eksploitacji i otrzymania potwierdzenia, że skrypt generujący payload działa prawidłowo.
Pobranie usługi Redis w formie obrazu dockerowego:
docker pull redis:5.0.7
Uruchomienie usługi Redis:
docker run -it -p 6379:6379 redis:5.0.7
Studium przypadku – przygotowanie oprogramowania
Mając na uwadze, że usługą nie korzysta z protokołu HTTP(S), zdecydowano się na wykorzystanie protokołu Gopher, który jak się okazało był poprawnie rozpoznawany i wykorzystywany zarówno przez podatną aplikację webową jak i oprogramowanie Redis.
Technika RogueServer Master/Slave Replication była powszechnie wykorzystywana, dlatego korzystając z serwisu Github można znaleźć przygotowane wcześniej skrypty generujące złośliwy payload z wykorzystaniem wspomnianego protokołu.
Niestety, nie są one w 100% działające dlatego należało je zmodyfikować z małą pomocą ChatGPT w celu poprawnej kompilacji biblioteki .so oraz udoskonalenia funkcji odpowiadającej za wykonanie reverse shell – oryginalna powodowała zamknięcie usługi Redis w przypadku wyjścia z shell-a.
W ramach prac powstało narzędzie dostępne pod adresem: https://github.com/michalo21/tweaked-redis-ssrf.
Studium przypadku – eksploitacja
W celu zaatakowania usługi Redis z wykorzystaniem podatności SSRF należy:
- Zbudować bibliotekę exp.so korzystając ze zmodyfikowanego pliku exp.c dostępnego w repozytorium https://github.com/michalo21/tweaked-redis-ssrf. Reszta wymaganych plików znajduje się w repozytorium https://github.com/n0b0dyCN/redis-rogue-server w katalogu RedisModulesSDK. Należy pamiętać by wykonać komendę make clean przed zbudowaniem
- Zbudowaną bibliotekę exp.so należy przenieść do katalogu tweaked-redis-ssrf
- Uruchomić serwer rogue-server.py na zdefiniowanym przez siebie porcie:
- Wygenerować payload typu: reverse shell programem ssrf-redis.py określając adres podatnej usługi, rogue server, oraz nawiązania reverse shell:
- Włączyć nasłuchiwanie
- Wysłać wygenerowany payload do instancji Redis. Ważne jest, by wykonać to podwójnie
- Zwrócona powłoka systemowa hosta, na którym działa usługa Redis:
Studium przypadku – zakończenie
Odwzorowanie potencjalnej podatności w środowisku lokalnym dało potwierdzenie, że przygotowany exploit działa poprawnie.
Pentesterzy dostosowali adresy w celu wygenerowania ładunku i przesłali go z wykorzystaniem podatnego miejsca w aplikacji.
Po chwili otrzymano powłokę zwrotną hosta na którym działała aplikacja klienta jak i usługa Redis pokazując realny wpływ podatności SSRF na środowisko aplikacji.
Warto wspomnieć, że sama funkcjonalność jak i usługa Redis, nie były w żaden sposób ograniczone przez formę uwierzytelnienia.
Podsumowanie
W przypadku błędów typu Server Side Request Forgery zaleca się by dane zawsze były odpowiednio walidowane pod kątem domen jak i wykorzystywanych protokołów zgodnie z wymaganiem biznesowym. Warto również zaimplementować serwer proxy, tak, żeby pełnił funkcję nadzorcy oraz nie zdradzał bezpośrednio adresu IP aplikacji.
Dodatkowo wszelkie lokalne usługi przetwarzające dane powinny mieć zaimplementowany mechanizm uwierzytelniania wraz z odpowiednią granulacją ról oraz uprawnień dla konkretnych użytkowników w myśl zasady Principle of least privilege.
Źródła:
- https://github.com/michalo21/tweaked-redis-ssrf
- https://github.com/xmsec/redis-ssrf
- https://github.com/n0b0dyCN/redis-rogue-server
- https://github.com/assetnote/blind-ssrf-chains
- https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md
- https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/index.html