Exploit jest łatwy. Trudno wiedzieć, czego szukać
PentestingZespół SwarmAttacker w JolocorpOpublikowano 8 min czytania

Oto rzecz, przed którą nikt nas nie ostrzegł przy zautomatyzowanym testowaniu penetracyjnym na obecnym topowym modelu: napisanie exploita okazało się łatwą częścią. Skieruj SwarmAttacker na podatną aplikację webową i poproś o działające polecenie lub spreparowane żądanie, a robi to. Czysto. Kłopoty zaczynają się o krok wcześniej, w części, która nigdy nie trafia do tutorialu: w ustaleniu, na co w ogóle patrzysz.
Przeszliśmy ponownie przez każdy cel, którego agent nie ruszył, spodziewając się, że przyłapiemy model na plątaniu składni lub sięganiu po niewłaściwą technikę. Nie znaleźliśmy tego. Ani razu cel nie wymknął się dlatego, że agent nie umiał napisać kodu. Gdy zawodził, zawodził z cichszego powodu: właściwa idea nigdy się nie uformowała albo nigdy nie została dogoniona wystarczająco daleko.
Właściwa klasa, zła technika: gdzie zatrzymuje się automatyczny pentesting
W całym zestawie SwarmAttacker był niemal zawsze we właściwym obszarze. Poprawnie nazywał klasę podatności. Często stawiał działający przyczółek. Wiedział, że formularz logowania jest prawdopodobnie podatny na wstrzyknięcie, wiedział, gdzie płynie wejście użytkownika, znał kształt problemu. Czego nie zawsze potrafił, to trafić w dokładną technikę, której żądał cel.
Wiedza, że cel ma wstrzyknięcie SQL, to nie to samo, co wiedza, że jest to wstrzyknięcie ślepe, oparte na wartościach logicznych.
Ta luka brzmi na małą. Nie jest. Odległość między „jest tu wstrzyknięcie” a „oto precyzyjna, ślepa technika po jednym bicie naraz, która faktycznie wydobywa dane” to miejsce, gdzie mieszkał spory kawał naszych porażek. Exploit był w zasięgu przez cały czas. Ścianą była diagnoza.
Gdzie ściana jest najwyższa: ślepe wstrzyknięcie SQL
Jeśli chcesz zobaczyć to w jednej liczbie, spójrz na ślepe wstrzyknięcie SQL. W całym zestawie była to najgorsza klasa, z jaką mierzył się agent, rozwiązana zaledwie w 1 na 3. Całą resztę tej rodziny, głośne, gadatliwe podatności, agent niemal zmiótł.
Powodem jest właśnie problem diagnozy, zaostrzony do granic. Odbity błąd cross-site scripting krzyczy do ciebie: wysyłasz sondę, ładunek odbija się prosto z powrotem na stronę, a sygnał jest nie do pomylenia. Wstrzyknięcie poleceń jest takie samo, uruchom sondę, a własne wyjście celu mówi ci, że zadziałało. Ślepe SQLi nie ma takiej uprzejmości. Nie ma nic do odczytania. Strona wygląda identycznie, niezależnie od tego, czy twoja próba była trafna, czy nie. Odpowiedź trzeba odbudować po jednej prawda-lub-fałsz inferencji naraz, a ta długa, krucha pętla, pytaj, czekaj, interpretuj różnicę tak subtelną, że mogłaby być szumem, dostosuj, pytaj znowu, to dokładnie miejsce, gdzie agent najczęściej gubił wątek.
Głośne sygnały są zmiatane; ślepy nie
Klasy podatności z oczywistą reakcją są niemal doskonałe. Ślepe wstrzyknięcie SQL, gdzie nie ma nic widocznego do odczytania, to jedyny słaby odstający wynik.
Dlaczego wyszukiwarka internetowa nie uratowała trudnych porażek?
Oczywistym rozwiązaniem jest danie agentowi wyszukiwarki internetowej i zrobiliśmy to. Przy tych trudnych porażkach rzadko cokolwiek ratowała. To nas zaskoczyło, dopóki nie przyjrzeliśmy się dlaczego. Wąskim gardłem nigdy nie było to, że model nie znał odpowiedzi, odpowiedź na „jak wykorzystać ślepe wstrzyknięcie oparte na wartościach logicznych” jest spisana w setce miejsc. Wąskim gardłem była niezdolność agenta do sformułowania wystarczająco precyzyjnego pytania z własnego mętnego wyjścia narzędzia.
Wyszukiwanie nagradza ostre zapytanie. „Endpoint resetu hasła zwraca 200 zarówno dla ważnych, jak i nieważnych tokenów, a długość odpowiedzi różni się o dwa bajty” to pytanie, na które można odpowiedzieć. „Coś tu jest nie tak” już nie. Gdy agent potrafił już wyartykułować problem, zwykle nie musiał szukać. Gdy nie potrafił, żadna ilość szukania nie pomagała, bo nie miał nic ostrego, czego mógłby szukać.
Odpowiedź roju: najpierw cierpliwie, potem równolegle
Jeśli diagnoza jest trudną częścią, to najgorsze, co możesz zrobić, to rzucić tłum workerów na cel, zanim ktokolwiek go zrozumie. Pięćdziesiąt równoległych sond przeciwko podatności, której nikt poprawnie nie odczytał, po prostu produkuje pięćdziesiąt pewnie błędnych raportów. Dlatego SwarmAttacker zbudowany jest tak, by iść wolno, zanim zaroi.
Przez pierwsze ~10 minut biegu celowo utrzymuje każdą falę małą, tylko 4 workerów, aby móc obserwować powrót każdej sondy, odczytać ją i często przeplanowywać. To faza czytania, część, w której ustala, na co właściwie patrzy. Dopiero gdy ma realne tropy, rozwija się szerzej, 6 workerów na falę, by wykorzystać przewagę, wszystko w twardym limicie 40 minut.
Ten rytm zostawia odcisk w czasie. Czasy rozwiązań są dwumodalne. Jest duży wczesny garb w okolicach kilkunastu minut, jednostrzałowe zdobycze, gdzie sygnał był głośny, a agent odczytał go od razu. Potem drugi, późniejszy wzrost po 20 minutach: cele, które potrzebowały drugiego aktu starannej, cierpliwej inferencji, zanim cokolwiek oddały. Mediana wypada na 15 minut, a większość rozwiązań domyka się przed 20, ale trudny ogon, ślepe, ciche, wymagające diagnozy cele, przychodzi wolno.
Czasy rozwiązań są dwumodalne
Wczesny garb w okolicach kilkunastu minut dla jednostrzałowych zdobyczy, potem drugi wzrost po 20 minutach dla celów, które potrzebują drugiego aktu starannej inferencji.
Co to zmienia
Przez lata modelem myślowym automatycznego napastnika była maszyna do kodu: niebezpieczeństwo polegało na tym, że stanie się dobry w pisaniu exploitów. Na nowoczesnym modelu ten statek po cichu odpłynął i nie była to interesująca część. Interesującą, wciąż nierozwiązaną częścią jest percepcja, odczytywanie wyjścia narzędzia, gdy nie wiesz, jak sygnał ma wyglądać, i zawężanie mglistego wrażenia „coś tu jest” do jednej dokładnej techniki.
To jest zakład, jaki robi cała architektura. Jeśli chcesz szczegółów, czemu zbudowaliśmy ją jako fale najpierw-cierpliwie-potem-równolegle, a nie jako jeden wielki rój, to jest w jak to działa. A jeśli chcesz pełnego rozbicia klasa po klasie, w tym klas, które zmiótł, i tych, które się broniły, wszystko jest w wynikach. Wersja krótka: model potrafi już napisać exploita. Nauczenie go wiedzieć, czego szuka to teraz granica.


