NFsec Logo

Podgląd linków – some kind of monster #2

08/12/2020 w Bezpieczeństwo Brak komentarzy.  (artykuł nr 762, ilość słów: 1558)

W

pierwszej części omówiliśmy sobie kilka problemów związanych z funkcjonalnością generowania podglądu linków w (web)aplikacjach. Dzisiaj chciałbym rozszerzyć problemy z metodą, gdzie serwer pośredni generuje podgląd na przykładzie serwisów Twitter oraz Facebook. Tworząc tego rodzaju rozwiązanie musimy mieć świadomość, że taka funkcja może zostać wykorzystana w nie do końca w sposób jaki byśmy sobie tego życzyli. Schemat działania takiego rozwiązania jest prosty – jeśli zalogujemy się do webaplikacji Twitter’a lub Facebook’a i zamieścimy w oknie nowego wpisu link – to pierwsze, co zrobi algorytm to prześlę ten link do kolejnego systemu, który powie serwerom (botom) danego serwisu, aby odwiedziły podatną stronę, pobrały jej zawartość i zwróciły niezbędne informacje do wygenerowania podglądu przy zamieszczaniu wpisu na w/w mediach społecznościowych. Jakie zagrożenia to może wywołać?

Możliwość stworzenia złej reputacji w sieci

Funkcjonalność podglądu linków na platformie Twitter / Facebook ze względu na brak konkretnych ograniczeń ich generowania jeszcze przed utworzeniem wpisu / twitta może doprowadzić do sytuacji, w której użytkownik specjalnie skieruje serwery tych serwisów na systemy bezpieczeństwa, które wydają ocenę na temat reputacji adresów IP. Atakujący może pobrać / utworzyć listę adresów różnych systemów / serwerów, które zgłaszają ataki przy użyciu protokołu HTTP do serwisów rejestrujących reputację adresów IP (np. AbuseIPDB). Mając listę takich serwerów wystarczy przygotować dla nich wrogie adresy URL (np. /wp-content/plugins/wp-file-manager/lib/files/x.php lub /%00/etc/passwd) symulujące atak. Użytkownik kierując teraz boty na spreparowane adresy URL – ze względu na złośliwe frazy w nich zawarte lub kody 404, 403 (i szybkość ich tworzenia), które będą generować na tych systemach / serwerach – spowoduje, że adresy IP tych botów (Twitter’a oraz Facebook’a) zostaną zgłoszone jako atakujące. Korzystając z wielu kont jednocześnie i “atakując” wiele systemów na raz – ranking złej reputacji może bardzo szybko osiągnąć maksymalną wartość.

Jak zreprodukować takie zachowanie?

1) Pierwszy sposób opiera się na wklejaniu wielu adresów URL za jednym razem. Logujemy się do na konto serwisu Twitter lub Facebook za pomocą ulubionej przeglądarki.
2) Tworzymy nowy wpis (ale go nie zapisujemy / wysyłamy).
3) Wklejamy w okno dialogowe nowego wpisu listę spreparowanych adresów URL (Twitter / Facebook), które odnoszą się do pojedynczego systemu bezpieczeństwa:

https://nfsec.pl/%
https://nfsec.pl/%00
https://nfsec.pl/%00/
https://nfsec.pl/%00/e
https://nfsec.pl/%00/et
https://nfsec.pl/%00/etc
https://nfsec.pl/%00/etc/
https://nfsec.pl/%00/etc/p
https://nfsec.pl/%00/etc/pa
https://nfsec.pl/%00/etc/pas
https://nfsec.pl/%00/etc/pass
https://nfsec.pl/%00/etc/passw
https://nfsec.pl/%00/etc/passwd

4) Sprawdzamy w przeglądarce, czy webaplikacja wysłała instrukcje do swoich botów np. z poziomu Narzędzi dla developerów ( Twitter / Facebook ).
5) Zaznaczamy cały wpis (Ctrl+A / Cmd+A) – odczekujemy najmniejsze okno czasowe, jakie uda nam się ustalić – na przykład 30 sekund – i powtarzamy operację od punktu 3. z innym zestawem adresów URL.

Tak wygląda ruch HTTP od strony serwera web:

[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:47 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/e HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/etc/pass HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/etc/pa HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/et HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/etc/ HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/etc/pas HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/etc/p HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00 HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/etc/passwd HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:21:48 +0100] "GET /%00/etc/passw HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"

Po odczekaniu 30 sekund:

[22/Nov/2020:17:23:21 +0100] "GET /%00 HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/e HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/etc/pas HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/etc/p HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/etc/pa HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/etc/pass HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/etc/passw HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/etc HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/et HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:17:23:21 +0100] "GET /%00/etc/passwd HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"

Twitter wygenerował po 10 żądań na sekundę. Facebook jest nieco bardziej agresywny w tej kwestii, ponieważ potrafi osiągnąć 35 żądań na sekundę:

[22:27:48] "GET /%00/etc/pas HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pass HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pass HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/p HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/passwd HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/passwd HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/p HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/passw HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1" 
[22:27:48] "GET /%00/e HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/e HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/passw HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00 HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pas HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pas HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00 HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pass HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pass HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/p HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/p HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pa HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pa HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/etc/pa HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"
[22:27:48] "GET /%00/et HTTP/1.1" 404 360 "-" "facebookexternalhit/1.1"

6) Opcjonalnie: atakujący może sprawdzić, czy bot danego serwisu został już zgłoszony przez atakowane serwery do usługi reputacji adresów IP lub stwierdzić to na podstawie braku generowania podglądu linków dla danego adresu URL.

Innym podejściem do kroku 3 jest powolne wpisywanie pojedynczego adresu URL – w odstępach dwóch / trzech sekund. Wówczas ruch do serwera HTTP wygląda tak:

[22/Nov/2020:18:08:36 +0100] "GET /robots.txt HTTP/1.1" 200 6278 "-" "Twitterbot/1.0"
[22/Nov/2020:18:08:36 +0100] "GET /%0 HTTP/1.1" 400 1179 "-" "Twitterbot/1.0"
[22/Nov/2020:18:08:39 +0100] "GET /%00 HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:08:45 +0100] "GET /%00/e HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:08:47 +0100] "GET /%00/et HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:08:49 +0100] "GET /%00/etc HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:08:55 +0100] "GET /%00/etc/p HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:08:58 +0100] "GET /%00/etc/pa HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:09:01 +0100] "GET /%00/etc/paa HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:09:03 +0100] "GET /%00/etc/paas HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:09:06 +0100] "GET /%00/etc/paasw HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"
[22/Nov/2020:18:09:08 +0100] "GET /%00/etc/paaswd HTTP/1.1" 404 6168 "-" "Twitterbot/1.0"

Kasujemy tylko ścieżkę do zasobu i również w odstępach dwu / trzy sekundowych wpisujemy kolejny adres:

[22/Nov/2020:18:09:11 +0100] "GET /e HTTP/1.1" 404 16911 "-" "Twitterbot/1.0"
[22/Nov/2020:18:09:13 +0100] "GET /et HTTP/1.1" 404 16896 "-" "Twitterbot/1.0"
[22/Nov/2020:18:09:15 +0100] "GET /etc HTTP/1.1" 404 16887 "-" "Twitterbot/1.0"
[22/Nov/2020:18:09:18 +0100] "GET /etc/h HTTP/1.1" 404 16897 "-" "Twitterbot/1.0"

* Twitterbot nie próbkuje „/” na końcu adresu URL – więc atakujący może pominąć okno czasowe dla tych adresów URL.

Facebook również w tej kwestii jest bardziej agresywniejszy, ponieważ potrafi wygenerować przez 21 sekund 151 żadań, co daje w przybliżeniu 7 req/s. Gdyby nie jeden fakt w tym scenariuszu – osoba atakująca ten sposób generowanie podglądu linków mogłaby zatruć wiele usług reputacji adresów IP powodując, że wszystkie serwery korzystające z takich baz danych zaczęły by blokować boty należące do serwisów Twitter oraz Facebook traktując je jako wrogie adresy IP. Ponadto dzienniki z tych serwerów by przemawiały na niekorzyść tych botów. Mogłoby to skuktować brakiem funkcjonalności podglądu linków dla wybranych adresów w tych społecznościówkach. Inne funkcje webaplikacji wykorzystujące te same adresy IP, co boty również zostałyby objęte blokadą. Po odzyskaniu prawidłowej reputacji, ale bez wprowadzenia odpowiednich mechanizmów ograniczających tego typu zachowania (np. generowanie podglądu dopiero po wysłaniu wpisu przez użytkownika) atakujący może bardzo szybko ponownie wpłynąć na złą reputację adresów IP botów – bez tworzenia żadnego wpisu.

Wszystko wygląda ładnie w teorii. Niestety w praktyce okazuje się, że serwisy utrzymujące ranking adresów IP – posiadają też funkcjonalność białych list, na które wpisują boty tak dużych serwisów – pozwalając im na tego typu praktyki. Dlatego wykorzystując ten rodzaj ataku – możemy doprowadzić jedynie do zablokowania botów na pojedynczych systemach – a ich zgłoszenia do centralnego systemu i tak zostaną zingorowane.

Możliwość skanowania stron za pomocą botów

Jakiś czas temu wyszło na jaw, że funkcjonalność podglądu linków oraz boty serwisu Facebook były wykorzystywane jako serwery proxy dla innych botów pozyskujących dane z różnych stron (ang. web scraping). Testy wykazały, że korzystając z jednego konta na Facebooku można było z łatwością wysłać ponad 10.000 żądań na minutę do dowolnej strony internetowej. Nic dziwnego – skoro użytkownik poprzez funkcjonalność prostego okienka, w które może wpisać dowolny adres URL i otrzymać odpowiedź – dostaje do dyspozycji flotę botów, których inne serwisy (również te związane z bezpieczeństwem) boją się blokować. Nawet po wprowadzeniu limitów otrzymujemy prosty skaner protokołu HTTP z funkcją proxy w gratisie (to adresy IP botów pojawią się w logach skanowanego serwera, a nie naszego IP, które łączy się za pomocą przeglądarki z serwisem). Na podstawie technik opisanych wyżej oraz kodów HTTP generowanych w podglądzie jesteśmy w stanie określić, czy dobrze zgadliśmy dany adres, czy też należy szukać dalej, głębiej…aż coś wyjdzie z ukrycia.

Więcej informacji: Zmuszenie botów do skanowania serwerów, a serwery do blokowania

Kategorie K a t e g o r i e : Bezpieczeństwo

Tagi T a g i : , , , , , , , ,

Komentowanie tego wpisu jest zablokowane.