Читать книгу Na tropie błędów. Przewodnik hakerski - Peter Yaworski - Страница 32

4.
CROSS-SITE REQUEST FORGERY
Przejęcie konta Badoo

Оглавление

Poziom trudności: Średni

URL: https://www.badoo.com/

Źródło: https://hackerone.com/reports/127703/

Data zgłoszenia: 1 kwietnia 2016

Nagroda: 852 $

Mimo że deweloperzy często używają tokenów CSRF, by chronić strony przed podatnościami CSRF, w niektórych przypadkach atakujący mogą kraść tokeny, co zaraz zobaczysz. Jeśli wejdziesz na portal społecznościowy https://www.badoo.com/, powinieneś zauważyć, że używa on tokenów CSRF. Mówiąc dokładniej, korzysta z parametru rt, który jest unikatowy dla każdego użytkownika. Kiedy wystartował program bug bounty dla portalu Badoo, nie mogłem znaleźć żadnej podatności. Jednakże hakerowi Mahmoud Jamalowi to się udało.

Jamal rozpoznał zarówno parametr rt, jak i jego znaczenie. Zauważył również, że parametr jest zwracany w niemalże wszystkich odpowiedziach JSON. Niestety nie było to pomocne, gdyż CORS ochraniał Badoo przed hakerami próbującymi odczytać te odpowiedzi, gdyż są kodowane jako application/json. Jamal jednak nie poprzestał na tym.

W końcu udało mu się znaleźć plik JavaScript https://eu1.badoo.com/worker scope/chrome-service-worker.js, który zawierał parametr o nazwie url_stats i następującej wartości:

var url_stats = 'https://eu1.badoo.com/chrome-push-stats?ws= 1&rt=<wartość_parametru_rt>';

Wartość url_stats przechowywała adres URL, który miał unikatową wartość rt w postaci parametru . Co więcej, żeby uzyskać wartość rt danego użytkownika, atakujący jedynie potrzebował, by ten odwiedził złośliwą stronę, która uzyskiwała dostęp do pliku JavaScript. CORS nie blokuje tego, ponieważ przeglądarki mogą czytać zdalne pliki JavaScript z zewnętrznych źródeł. Atakujący mógł następnie użyć wartości rt w celu połączenia z dowolnym kontem w mediach społecznościowych z kontem użytkownika Badoo. W rezultacie atakujący mógł wywołać żądanie POST w celu zmodyfikowania konta ofiary. Oto strona HTML, której użył Jamal w celu wykorzystania podatności:

<html>

<head>

<title>Badoo account take over</title>

<script src=https://eu1.badoo.com/worker-scope/chrome-service     -worker.js?ws=1></script>

</head>

<body>

<script>

function getCSRFcode(str) {

return str.split('=')[2];

}

window.onload = function(){

var csrf_code = getCSRFcode(url_stats);

csrf_url = 'https://eu1.badoo.com/google/verify.phtml?code=         4/nprfspM3yfn2SFUBear08KQaXo609JkArgoju1gZ6Pc&authuser=3&         session_state=7cb85df679219ce71044666c7be3e037ff54b560..         a810&prompt=none&rt='+ csrf_code;

window.location = csrf_url;

};

</script>

</body>

</html>

Kiedy ofiara załadowała tę witrynę, strona ładowała JavaScript pochodzący z Badoo, odwołując się do niego przez atrybut src w tagu <script> . Po załadowaniu skryptu, strona internetowa wywoływała funkcję JavaScript, window.onload, która zwana jest też funkcją anonimową . Przeglądarki wywołują moduł obsługi zdarzeń onload podczas ładowania strony; ponieważ Jamal zdefiniował swoją funkcję w module window.onload, zostanie ona uruchomiona zawsze po załadowaniu strony.

Następnie Jamal utworzył zmienną csrf_code i przypisał do niej wartość zwracaną w funkcji, którą zdefiniował w , o nazwie getCSRFcode. Funkcja getCSRFcode pobiera i dzieli tekst na tablicę łańcuchów przy każdym znaku „=”. Następnie zwraca wartość trzeciego elementu tablicy. Kiedy funkcja przetwarza zmienną url_stats z podatnego pliku JavaScript w , otrzymuje następującą tablicę:

https://eu1.badoo.com/chrome-push-stats?ws, 1&rt, <wartość_parametru_rt>

Następnie funkcja zwraca trzeci element tablicy, którym jest wartość rt i przypisuje ją do csrf_code.

Kiedy miał już token CSRF, Jamal stworzył zmienną csrf_url, która przechowuje adres URL do strony internetowej Badoo, /google/verify.phtml. Ta strona łączy jego własne konto Google z kontem Badoo ofiary . Wymaga ona kilku parametrów, które są zakodowane w adresie URL. Nie będę ich szczegółowo analizował, ponieważ są one charakterystyczne dla Badoo. Zwróć jednak uwagę na parametr rt, który nie ma wpisanej wartości. Zamiast tego na koniec linku dołączany jest csrf_code, który stanowi poprawną wartość dla rt. Następnie Jamal wykonuje żądanie HTTP, wywołując funkcję window.location z przypisaną wartością csrf_url, które przekierowuje przeglądarkę odwiedzającego na adres wskazany w . Rezultatem jest żądanie GET do Badoo, który weryfikuje parametr rt i przetwarza żądanie w celu połączenia konta Badoo ofiary do konta Google Jamala, kończąc tym samym przejęcie konta.

Wnioski

Nie ma dymu bez ognia. Jamal zauważył, że parametr rt był zwracany w różnych miejscach, a dokładniej w odpowiedziach JSON. Z tego też powodu prawidłowo zgadł, że wartość tego parametru może pojawić się w miejscu, do którego ma dostęp, w tym przypadku był to plik JavaScript. Jeśli odnosisz wrażenie, że strona może być podatna, to nie przestawaj szukać. W tym przypadku uznałem, że to dziwne, że parametr CSRF może mieć tylko 5 cyfr i być dołączony w adresach URL. Zazwyczaj tokeny są znacznie dłuższe, co czyni je trudniejszymi do odgadnięcia, oraz są dołączane w żądaniach HTTP, a nie w adresach URL. Używaj serwerów proxy i sprawdzaj wszystkie źródła, które są wywoływane, kiedy odwiedzasz daną stronę bądź aplikację. Burp Suite pozwala Ci przejrzeć całą historię proxy w celu poszukiwania konkretnych terminów lub wartości, które mogłyby ujawnić wartość rt zawartą w plikach JavaScript. Możesz w ten sposób znaleźć wyciek informacji z wrażliwymi danymi, takimi jak token CSRF.

Na tropie błędów. Przewodnik hakerski

Подняться наверх