BACK

Smashing Aero2 BDI captcha for Fun and Profit, czyli wejście w Internet w kapciach i bez.

W dniu 1.04.2014r. Operator Aero2 uprzykrzył życie użytkownikom BDI, którzy zgodnie z udzieloną przez UKE koncesją uzyskali możliwość korzystania z łącza internetowego z gwarantowaną przepustowością między 128 a 256 kb/s, a później między 256 a 512 kb/s. Obecne wysiłki mające na celu zniechęcenie użytkowników do korzystania z BDI, są rozpaczliwą próbą odciągnięcia zainteresowania od jednego z najważniejszych osiągnięć w dziedzinie upowszechnienia dostępu do Internetu w polskim społeczeństwie. (Historycznie jest to jedna z pierwszych inicjatyw administracji publicznej na świecie, mająca zapewnić powszechny i bezpłatny dostępu do Internetu „prawie szerokopasmowego”, na skalę ogólnokrajową).
Operator Aero2 uzyskał koncesję na użytkowanie części pasma radiowego w zakresie 2570 – 2620 MHz, po niezwykle preferencyjnych cenach, w zamian za konieczność udostępnienia przynajmniej 20% przepustowości swoich łącz na cele BDI. W związku z tym starał się od początku tworzyć bariery w dostępie do BDI. Od utrudniania uzyskania karty SIM, przez konieczność używania modemów o wyśrubowanych parametrach specyfikacji, kompatybilnych z BDI, aż do obecnego wprowadzenia mechanizmu captcha, o trudności którego wypowiedziało się już UKE.

Prześledźmy, co tak naprawdę dzieje się w momencie „zakapciowania” dostępu do usługi BDI.

Do testów potrzebna będzie *nixowa maszyna z dostępem do shella (ja posłużyłem się bash’em), oraz działającymi X Windows’ami i paroma programami, które na takiej maszynie zapewne są domyślnie zainstalowane (wget, Firefox), plus jednym bardzo przydatnym skryptem perlowym – formfind.pl. Aby w pełni zrozumieć następne kroki proponuję najpierw zapoznać się z tym artykułem.

Operator Aero2 zakłada, że przeciętny użytkownik będzie posługiwał się przeglądarką internetową posiadającą GUI. Pójdźmy więc tym tropem i zobaczmy jak i co będzie się działo, gdy spróbujemy używać Firefoxa po „zakapciowaniu” dostępu do BDI. Bądźmy jednak bardziej zaawansowanymi użytkownikami i włączmy podgląd i analizę ruchu generowanego przez tą przeglądarkę (wciśnijmy jednocześnie magiczną kombinację [CTRL]+[SHIFT]+[K] lub w zakładce „Narzędzia”, pod pozycją „Dla twórców witryn” zaznaczmy opcję „Konsola WWW”).

W tym miejscu mniej zaawansowanym czytelnikom należy się wyjaśnienie. W zasadzie wszystko co robicie w Internecie za pośrednictwem protokołu HTTP, sprowadza się do pobierania (GET) i wysyłania (POST) pewnych danych. (Taka koncepcja przyświecała temu protokołowi od momentu jego powstania.) Więcej informacji na ten temat znajdziecie w Wikipedii lub bezpośrednio u źródła.

Co więc widzimy po uruchomieniu Firefoxa i wpisaniu URL wybranej strony internetowej?
Oto, zamiast dostać się do wybranego przez nas adresu URL, zostajemy przekierowani pod adres http://bdi.free.aero2.net.pl:8080/ (nasza przeglądarka pobrała zawartość tej strony). Adres IP, który otrzymał nasz modem jest z puli 10.22x.x.x
Widzimy też, że przy tej okazji pojawił się błąd przetwarzania zawartości tej strony: Oczekiwano końca wartości, ale odnaleziono „sans-serif”. Błąd podczas przetwarzania wartości dla „font-family”.
Zajrzyjmy więc, do cache’u przeglądarki, lub dla wygody dalszych analiz zapiszmy sobie w innym miejscu naszą stronę proszącą o kliknięcie.
wget --save-cookies=/tmp/ciastka.txt --keep-session-cookies -S -O /tmp/bdi.html http://bdi.free.aero2.net.pl:8080/
Analizując kod tej strony (/tmp/bdi.html) od razu znajdujemy problematyczną deklarację z linii 27.:
font-family: 'Arial' sans-serif;
No cóż, ktoś nie przejrzał kodu strony i nie zauważył dopisanego niepotrzebnie sans-serif. Ale nas interesują linijki od 53. do 56., a dokładnie formularz (FORM), który posiada tylko jedno pole viewForm oraz przycisk z polem typu SUBMIT, o nazwie Kliknij tutaj powodujący odesłanie wartości true w polu viewForm, pod dotychczasowy adres http://bdi.free.aero2.net.pl:8080/.
Czytelnicy o mniejszej znajomości składni HTML, lub bardziej leniwi, mogą zamiast czytania treści pliku /tmp/bdi.html po prostu wywołać komendę:
./formfind.pl < /tmp/bdi.html
i otrzymają te informacje automatycznie.
Kliknijmy więc tam gdzie zachęca nas Aero2.
Przed naszymi oczami w „Konsoli WWW” pojawia się cała litania pobranych plików. Przyjrzyjmy się im zgrubnie, i wyposażeni w wiedzę o odsyłanych danych formularza, sprawdźmy co będzie jeśli wywołamy następującą komendę w shell’u:
wget --post-data viewForm=true --save-cookies=/tmp/ciastka.txt --keep-session-cookies -S -r http://bdi.free.aero2.net.pl:8080/
W wyniku tego, w katalogu w którym pracowaliśmy, mamy teraz parę różnych plików i katalogów korespondujących z zawartością historii działań Firefoxa. Wydaje się, że najbardziej interesujący plik, to plik JPG o rozdzielczości 300x57 piksli (sprawdźcie sami poleceniem jpeginfo), z nazwą zaczynającą się od image, z katalogu www.google.com/recaptcha/api/.

No ale jak teraz odesłać prawidłową odpowiedź?
Spójrzmy więc do tego samego katalogu, do pliku zaczynającego się od challenge. Interesujące linijki to 3. i 5. Oto bowiem, linijka 3. zawiera ciąg: 6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1 z nazwy pliku który właśnie przeglądamy (a nazwa ta jest odzwierciedleniem adresu URL z którego pochodzi ten plik), a linijka 5. zawiera ciąg znaków z nazwy/URL obrazka który pobraliśmy.
No dobrze, ale jak odpowiedzieć serwerowi, co odnaleźliśmy na obrazku?
Pamiętajmy, że rozmawiamy z „kapcio-bramką” BDI Aero2, spójrzmy więc do katalogu bdi.free.aero2.net.pl:8080/ do pliku index.html. Znowu w linijce 30. mamy znajome pole formularza viewForm ustawione na wartość true, w linijce 64. pole recaptcha_response_field oczekujące na wpisanie naszego rozwiązania, a w linijce 68. element SUBMIT odpowiedzialny za odesłanie formularza z dwoma pierwszymi wartościami. (Ponownie możemy sprawdzić nasze wyniki analizy formfind.pl’em). A więc sprawa stała się jasna, oto bowiem, aby pobrać obrazek który mamy „odkapciować”, wystarczy że zapytamy serwer Google o nasz „challenge”:
wget -q -O /tmp/google.html http://www.google.com/recaptcha/api/challenge?k=6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1
URL jest zawsze taki sam, bo to URL otrzymanej (wykupionej?) przez Aero2 u Google „usługi na dostarczanie kapci”. Wyciągniemy z otrzymanego pliku zawartość linijki 5., albo bardziej uniwersalnie, pola z identyfikatorem „challenge’a”, a następnie zapytamy serwer Google o obrazek dla tego „challenge’a”:
wget -q -O /tmp/captcha.jpg http://www.google.com/recaptcha/api/image?k=<przydzielony numer id challenge>
Teraz wystarczy obejrzeć obrazek i odpowiedzieć serwerowi na adres http://bdi.free.aero2.net.pl:8080/ w prawidłowy sposób, jakie to znaki znajdowały się „na kapciu”.
A robimy to w następujący sposób:
wget -q --post-data 'viewForm=true&recaptcha_response_field=<nasza odpowiedź>&recaptcha_challenge_field=<przydzielony numer id challenge>' -O /tmp/response.html http://bdi.free.aero2.net.pl:8080/
Na uwagę zasługuje to, że oprócz odkrytych w pliku bdi.free.aero2.net.pl:8080/index.html dwóch pól: viewForm i recaptcha_response_field, musimy jeszcze do naszej odpowiedzi dodać pole recaptcha_challenge_field (to z powodu konieczności zidentyfikowania naszej odpowiedzi przez Google). Strukturę odpowiedzi możemy podejrzeć klikając w jej linijkę w „Konsoli WWW”. Tam od razu mogliśmy wyczytać jak odpowiadać na „kapcia”, ale byłoby to mało pouczające.
W ten sposób otrzymaliśmy komplet informacji potrzebnych do odblokowywania „zakapciowanego” dostępu do BDI, bez konieczności klikania gdziekolwiek, czy używania przeglądarki typu Firefoxa.
Tu jest przykładowy skrypt, którym sam rozwiązałem „problem kapcia” w moim komputerze. W razie pojawienia się „kapcia”, uruchamia on xv z obrazkiem i czeka na wpisanie odpowiedzi w shell’u, dalej jest tak jak kiedyś – przy zwykłym wywołaniu wvdial z opcją wznawiania połączenia w sposób automatyczny.

Oczywiście to nie wyczerpuje puli ciekawostek związanych z „kapciem”.
Spróbujcie zapytać rekurencyjnie (wget opcja -r) nieco zmodyfikowany adres zwracający „challenge”, z ciekawości możecie tego spróbować nie koniecznie przy pomocy łącza dostarczanego przez Aero2.
(Aero2 wycięło opcję dostępu do wersji akustycznej „kapcia” obcinając URL w zapytaniu serwera Google). Jeśli po ciągu 6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1 w zapytaniu Google o „challenge” dopiszecie &is_audio=false lub &is_audio=true, a zamiast challenge wstawicie noscript, otrzymacie to co dostaje Aero2 od Google. Spójrzcie w związku z tym ponownie do katalogu bdi.free.aero2.net.pl:8080/, do pliku index.html, na linijkę 109.

Przed chwilą zaproponowałem żebyście odpytali serwer Google tak jak robi to Aero2, a więc wywołując następującą komendę:
wget -S -r http://www.google.com/recaptcha/api/noscript?k=6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1
W katalogu www.google.com/recaptcha/api/ powinny być teraz 3 nowe pliki:
noscript?k=6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1
noscript?k=6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1&is_audio=false
noscript?k=6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1&is_audio=true

Z widokiem bezpośredniego odpytania Google o to, co zwraca do serwerów Aero2 gdy Operator „podrzuca nam kapcia”. To że strona Aero2 nie umożliwia odsłuchu „angielskiej wersji akustycznej kapcia”, to tylko wybieg Operatora by osoby z upośledzeniem narządu wzroku nie mogły składać skarg na brak dostępu do BDI. Zgodne z tymi informacjami osoby takie mogą się ubiegać o wyłączenie „kapcia” w przypadku swojego SIM’a.

Zainteresowało was „rozmawianie z serwerami używającymi kapci”?
To świetnie, teraz niektórzy z was już widzą, że jeśliby agregować obrazki od Google, identyfikować je np. sumami md5 i wiązać z prawidłowym rozwiązaniem w postaci tekstowej, to w tak utworzonej bazie danych, o id wiersza w postaci sumy md5 i „polu tekstowym” z rozwiązaniem w postaci odpowiedniego string’a, mielibyśmy tęczowe tablice na „mechanizm kapcia”. Ale to już zupełnie inna bajka...

W związku z tym, że „dla ułatwienia życia użytkownikom”, „kapeć” pojawia się nieregularnie kilka razy na dobę, napisanie wcześniej wskazanego skryptu zajęło mi kilka wieczorów, dodatkowo musiałem napisać ten tekst, stąd informacje te zamieszczam dopiero 7.04.2014r. Gdyby „kapeć” wyskakiwał co godzinę, skrypt byłby gotowy szybciej (dobrze, że w domu mamy 2 modemy, trochę to ułatwiło pracę).
Na zakończenie informacja dla ciekawskich.
Odpytajcie adres „challenge’a”:
http://www.google.com/recaptcha/api/challenge?k=6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1
Wyciągnijcie id obrazka, i sprawdźcie co otrzymacie po odpytaniu odpowiedniego URL.
Albo zapytajcie bezpośrednio:
http://www.google.com/recaptcha/api/noscript?k=6LfXGdQSAAAAADi5NxUNOWP5sYiW8rDzk-0DRUz1
A teraz zsumujcie to z poprzednim akapitem...

Miłej zabawy, i udanych eksperymentów.

Kacper Kulczycki Warszawa 6 – 7.04.2014r.


Suplement z dnia 17.05.2014r.

W związku z odejściem Aero2 od mechanizmu reCaptcha by Google, oraz przejściem na „własnoserwerową” metodę z użyciem skryptu PHP cool-php-captcha mój skrypt do automatyzacji łączenia z Aero2 wymagał pewnych zmian.
Znowu zachęcam do przyjrzenia się wymianie informacji między serwerem Aero2, a naszym komputerem. Nadal pierwszą stroną, która załaduje się po wywołaniu:
wget --save-cookies=/tmp/ciastka.txt --keep-session-cookies -S -O /tmp/bdi.html http://bdi.free.aero2.net.pl:8080/
będzie strona z błędem w definicji czcionek, nawołująca do kliknięcia (przesłania formularza z zawartością pola: viewForm ustawionego na wartość true)
Widać, że nadal rozwiązanie jest robione najtańszymi metodami i nie było gruntownej przebudowy, nastąpiło tylko zejście z drogi niezadowolonemu Google i naciskanym przez użytkowników BDI urzędnikom UKE.
Po kliknięciu wskazanego linku, załaduje nam się znacznie mniej „śmieci”. Jednak w przeciwieństwie do poprzedniego rozwiązania zostanie nam podrzucone ciastko z identyfikatorem sesji PHPSESSID
Najważniejszy dla nas obrazek jest dostępny pod adresem:
http://bdi.free.aero2.net.pl:8080/getCaptcha.html
Gdy odpowiemy serwerowi Aero2, wysyłany jest formularz z dwoma polami: viewForm o wartości true oraz captcha o wartości zawierającej naszą odpowiedź, oczywiście musimy się dodoatkowo wylegitymować właściwym ciastkiem PHPSESSID
Ostatecznie musimy więc tylko odpytywać adres http://bdi.free.aero2.net.pl:8080/getCaptcha.html i odsyłać odpowiedź na http://bdi.free.aero2.net.pl:8080/ pamiętając o przechowywaniu ciastek.
W związku z tym, zaktualizowany skrypt można pobrać tu
Obecnie stosowane rozwiązanie jest oczywiście bardziej podatne na zmechanizowane rozwiązywanie testu niż reCaptcha by Google.

Kacper Kulczycki Warszawa 17.05.2014r.

Suplement z dnia 20.05.2014r.

W związku z porzuceniem przez Aero2 mechanizmu ciastek sesyjnych mój skrypt do automatyzacji łączenia z Aero2 wymagał kolejnych zmian.
Obecnie gdy wywołamy polecenie:
wget -S -O /tmp/bdi.html http://bdi.free.aero2.net.pl:8080/
Otrzymamy dotychczasową stronę z błędem w definicji czcionek, nawołująca do kliknięcia (przesłania formularza z zawartością pola: viewForm ustawionego na wartość true)
Znowu, mimo zmian nikt nie zadał sobie trudu poprawienia kodu.
Po przejściu pod wskazany link, załaduje nam się trochę inna strona niż ostatnio. Do formularza w niej zawartego doszło nowe pole PHPSESSID o 26-znakowym identyfikatorze sesji, którego wartość doklejana jest do URL obrazka:
http://bdi.free.aero2.net.pl:8080/getCaptcha.html?PHPSESSID=<identyfikator sesji>
Odpowiedź do serwera Aero2, zawiera formularz z trzema polami viewForm o wartości true, PHPSESSID o wartości zawierającej 26-znakowy identyfikator sesji, oraz captcha o wartości zawierającej odpowiedź.
Obecnie więc trzeba pobrać formularz z identyfikatorem sesji:
wget -S -O /tmp/form.html --post-data viewForm=true http://bdi.free.aero2.net.pl:8080/
Wyciągnąć identyfikator sesji z pliku /tmp/form.html i pobrać obrazek:
wget -S -O /tmp/captcha.jpg http://bdi.free.aero2.net.pl:8080/getCaptcha.html?PHPSESSID=<identyfikator sesji>
A następnie odesłać formularz:
wget -S -O /tmp/response.html --post-data 'viewForm=true&PHPSESSID=<identyfikator sesji>&captcha=<nasza odpowiedź>' http://bdi.free.aero2.net.pl:8080/
Zaktualizowany skrypt można pobrać tu

Kacper Kulczycki Warszawa 20.05.2014r.

Podgląd plików graficznych w terminalu Linuksa.

W związku z tym, że Jakub Danecki i Cezary Jackiewicz po moim mailu umieścili informacje o skrypcie na swoich forach, zauważyłem że niektórzy, mniej obeznani z terminalem Linuksa użytkownicy tego systemu, mają problem z wyświetlaniem obrazków w konsoli.
Jest na to kilka sposobów, najbardziej przyjazny dla czysto tekstowego terminala monochromatycznego to biblioteka aalib, wraz z tekstową przeglądarką grafiki aview. W terminalu kolorowym można użyć biblioteki libcaca i przeglądarki cacaview.
Jednak największe możliwości daje użycie framebuffer'a. Dzięki niemu mamy do dyspozycji możliwości przeglądarek grafiki fbi z pakietu fbida lub przeglądarki fbv.
Ta ostatnia ma bardzo ciekawą opcję uruchomieniową --noclear, -c powodującą że po wyjściu z programu, framebuffer nie wyczyści bufora ramki, a więc daje możliwość podglądu obrazka podczas wpisywania znaków na standardowe wejście.

Kacper Kulczycki Warszawa 30.05.2014r.


BACK