Na tropie błędów. Przewodnik hakerski. Peter Yaworski

Читать онлайн книгу.

Na tropie błędów. Przewodnik hakerski - Peter Yaworski


Скачать книгу
tylko bank akceptowałby ostatni parametr from, który otrzymał. Zamiast wysyłać 5000 $ z konta 12345 na 67890, kod serwera użyłby drugiego parametru i wysłał pieniądze z konta ABCDEF na 67890.

      Kiedy serwer dostaje kilkukrotne parametry z tą samą nazwą, może odpowiedzieć na wiele sposobów. Na przykład PHP i Apache używają ostatniego wystąpienia, Apache Tomcat używa pierwszego, ASP i IIS używają wszystkich i tak dalej. Dwóch badaczy, Luca Carettoni i Stefano di Paola, udostępnili dokładną prezentację wielu różnic między technologiami serwerów podczas konferencji AppSec EU 09; informacja ta jest teraz dostępna na stronie OWASP na https://www.owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf (zob. slajd 9). W wyniku tego nie ma jednego gwarantowanego procesu do obsługi wielokrotnych parametrów z tą samą nazwą, więc znalezienie podatności HPP wymaga nieco kombinowania, by przekonać się o tym, jak działa strona, którą sprawdzasz.

      Przykład z bankiem używa parametrów, które są oczywiste. Czasami jednak podatności HPP objawiają się jako rezultat ukrytego zachowania po stronie serwera, wynikającego z kodu, który nie jest bezpośrednio widoczny. Powiedzmy na przykład, że Twój bank zadecydował ulepszyć sposób, w jaki przetwarza przelewy, i zmienia kod w backendzie tak, aby nie używał parametru from z URL-a. Tym razem bank użyje dwóch parametrów, jednego do konta, na które ma zostać wykonany przelew, a drugiego do kwoty do przelania. Przykładowy link mógłby wyglądać tak:

      https://www.bank.com/transfer?to=67890&amount=5000

      Zazwyczaj kod na serwerze byłby dla nas zagadką, lecz ze względu na potrzeby tego przykładu wiemy, że kod Ruby serwera (nadzwyczaj brzydki i bezużyteczny) wygląda następująco:

      user.account = 12345

      def prepare_transfer(

params)

      

params << user.account

      

transfer_money(params) #user.account (12345) becomes params[2]

      end

      def transfer_money(params)

      

to = params[0]

      

amount = params[1]

      

from = params[2]

      transfer(to,amount,from)

      end

      Ten kod tworzy dwie funkcje, prepare_transfer i transfer_money. Funkcja prepare_transfer używa tablicy o nazwie params

, która zawiera parametry to i amount pochodzące z URL-a. Tablicę stanowiłoby [67890,5000], gdzie jej wartości są wciśnięte między nawiasy, a każda wartość jest oddzielona przecinkiem. Pierwsza linia funkcji
dodaje informacje o koncie użytkownika, które zostały zdefiniowane wcześniej w kodzie, na końcu tablicy. Dostajemy zatem tablicę params [67890,5000,12345], która następnie jest przekazana do transfer_money
. Zauważ to, że w odróżnieniu od parametrów tablice nie mają nazw powiązanych z ich wartościami, więc kod podlega tablicy zawierającej zawsze każdą wartość w następującej kolejności: konto odbiorcy jako pierwsze, kwota przelewu druga i konto, z którego wychodzi przelew, jako następne. W transfer_money kolejność wartości staje się oczywista z racji, że funkcja przypisuje każdą wartość tablicy do zmiennej. Ze względu na to, że tablice są numerowane od 0, params[0] przyjmuje pierwszą wartość w tablicy, którą w tym przypadku jest 67890 i przypisuje ją do zmiennej to
. Pozostałe wartości są również przypisywane zmiennym w wierszach
. Wtedy nazwy zmiennych są przekazane do funkcji transfer, niepokazanej w tym fragmencie, która przyjmuje wartości i wykonuje przelew.

      W najlepszej sytuacji parametry URL byłyby zawsze formatowane w sposób, jakiego kod oczekuje. Jednakże atakujący mógłby zmienić wynik tego procesu przez podanie w from wartości dla params, tak jak z następującym URL-em:

      https://www.bank.com/transfer?to=67890&amount=5000&from=ABCDEF

      W tej sytuacji parametr from jest również włączony do tablicy params przekazanej funkcji prepare_transfer; co za tym idzie, wartościami tablicy mogłyby być [67890,5000,ABCDEF], a podanie konta użytkownika w 

dawałoby rezultat w postaci [67890,5000,ABCDEF,12345]. W wyniku tego w funkcji transfer_money wywołanej w prepare_tranfer wartość from stałaby się trzecim parametrem, zamieniając oczekiwaną wartość 12345 na wartość atakującego ABCDEF
.

      HPP po stronie klienta

      Podatności HPP po stronie klienta pozwalają atakującym na wstrzyknięcie dodatkowych parametrów do adresu URL, w celu wywołania efektów po stronie użytkownika (strona klienta jest częstym sposobem odnoszenia się do akcji, które dzieją się na twoim komputerze, często przez przeglądarkę, a nie po stronie serwera).

      Luca Carettoni i Stefano di Paola w swojej prezentacji zamieścili przykład tego zachowania, używając wymyślonego adresu URL http://host/page.php?par=123%26action=edit i następującego kodu na serwerze:

      

<? $val=htmlspecialchars($_GET['par'],ENT_QUOTES); ?>

      

<a href="/page.php?action=view&par='.<?=$val?>.'">View Me!</a>

      Ten kod generuje nowy adres URL, bazując na wartości par parametru wpisanego przez użytkownika. W tym przykładzie atakujący przekazuje wartość 123%26action=edit jako wartość dla par w celu wygenerowania dodatkowego, nieoczekiwanego parametru. Wartością dla & zakodowaną przez URL jest %26, co oznacza, że kiedy URL jest przetwarzany, %26 jest interpretowane jako &. Ta wartość dodaje dodatkowy parametr do wygenerowanego href-a, bez sprecyzowania parametru w URL-u. Używając parametru 123&action=edit zamiast %26, & byłoby zinterpretowane jako oddzielenie dwóch parametrów, lecz ze względu na to, że strona używa tylko jednego parametru par w swoim kodzie, parametr action zostałby usunięty. Wartość %26 omija ten problem, zapewniając, że akcja nie jest rozpoznawana jako osobny parametr, a więc 123%26action=edit staje się wartością par.

      Następnie par (z zakodowanym & jako %26) jest przekazany do funkcji htmlspecialchars

. Funkcja htmlspecialchars konwertuje znaki specjalne, takie jak %26, do ich zakodowanych w HTML-u wartości, zamieniając %26 na &amp; (jednostka w HTML-u, która reprezentuje &), gdzie ten znak może mieć specjalne znaczenie. Zmieniona wartość jest następnie przechowywana w $val. W następnej kolejności generowany jest nowy link przez dodanie $val do wartości href w 
. Zatem wygenerowany link to <a href="/page.php?action=view&par=123&action=edit">. W konsekwencji atakujący zdołał dodać nieoczekiwany action=edit do URL-a href, który mógłby doprowadzić do podatności w zależności od tego, jak aplikacja traktuje przemycony parametr action.

      Następne 3 przykłady wyjaśniają szczegółowo oba błędy HPP, zarówno po stronie serwera, jak i klienta, znalezione na HackerOne i Twitterze. Wszystkie z tych przykładów wymagają manipulowania parametrami URL. Miej na uwadze fakt, że żaden z przykładów


Скачать книгу