Korzystając z chwili wolnego czasu chciałbym przedstawić nieco inne spojrzenie na badanie firmware’u. Tym razem nie będę szukał podatności 😉
W tym poście skupię się na analizie zmian dokonanych w kodzie oprogramowania serwera htttpd w serii routerów D-Link DWR celem zablokowania możliwości administracji urządzeniem poprzez tylną furtkę.
Jeżeli pamietasz czego dotyczyła opisywana przeze mnie sytuacja możesz śmiało pominąć ten akapit. W przypadku chęci zgłębienia problemu zapraszam przeczytania tego posta.
W oprogramowaniu rodziny routerów serii DWR, oprogramowanie dostarczane przez firmę Amit Network, zawiera dodatkowe ukryte konto. Konto wdzięcznie nazywa się “guest” i posiada taką samą flagę uprawnień (innymi słowy, takie same uprawnienia), jak najwyżej uprzywilejowane konto w systemie czyli “admin”.
Przydział flagi uprawnień (zmienna user_login_id) kontu “admin”… (kliknij aby powiększyć)
…oraz flaga konta “guest”
Abstrachując całkowicie od uprawnień tego konta, posiada ono jeszcze jeden “smaczek” – nie posiada hasła. Jedynym sposobem na jego zmianę jest ręczna modyfikacja zawartości pamięci urządzenia. Ten fakt, w połączeniu z podatnością na ataki CSRF umożliwiał napastnikom na pełną modyfikację ustawień urządzenia po zwabieniu użytkownika na specjalnie spreparowaną stronę.
Najnowsza wersja oprogramowania, będąca przedmiotem tego posta, ma zablokowaną możliwość korzystania z backdoora, oraz zaimplementowaną obsługę tokenów zapobiegającą atakom CSRF.
Żadne zmiany w procesie walidacji nazwy użytkownika i hasła nie nastąpiły. Po pomyślnej walidacji i przydzieleniu flag uprawnień pojawił się kawałek kodu odpowiedzialny za zerowanie flag uprawnień, jeżeli nazwą konta jest “guest” lub “user” (konto user zostało pominięte w poprzednich postach z racji poprawnie przydzielonych uprawnień oraz obecności tylko na dwóch modelach urządzeń z całej serii).
Zerowanie flagi uprawnień dla kont “guest” i “user”.
Kolejnym krokiem jest walidacja flag uprawnień ostatniego użytkownika panelu administracyjnego oraz konta, na które zostało zgłoszone żądanie zalogowania. Jeżeli to konto posiada uprawnienia administracyjne (tzn. flaga last_logged_user_login_id > 4, flagi kont “zwykłych” zawierają się w przedziale 2-3), funkcja przechodzi do walidacji user_login_id tym samym kryterium.
Sprawdzenie flag ostatnio zalogowanego użytkownika i konta, na które użytkownik próbuje się zalogować.
Jeżeli poświadczenia dotyczą konta zwyczajnego użytkownika, funkcja przechodzi do końcowego etapu i sprawdzany jest user_login_id, na podstawie którego następuje zalogowanie do panelu administracyjnego.
W przeciwnym wypadku porównywane są adresy IP poprzedniego i nowego użytkownika. Powodzenie operacji porównania powoduje przejście do sprawdzenia user_login_id i właściwej operacji logowania.
Porównanie adresów IP.
Kiedy adres IP użytkownika żądającego dostęp do panelu administracyjnego jest różny od IP ostatnio zalogowanego użytkownika, wykonywany jest poniższy fragment kodu:
Funkcja rtime() jest tu “podpuchą”, gdyż nie chodzi o linuksową funkcję rtime(), lecz o autorską, której zadaniem jest zupełnie co innego – zwrócenie czasu działania urządzenia.
Spójrzmy zatem jak ona wygląda:
Funkcja rtime().
Funkcja jest bardzo prosta. Wywołuje funkcję sysinfo(), celem uzyskania uptime’u w strukturze pod wskaźnikiem sysinfo_struct_pointer i zwraca pierwsze pole tej struktury (uptime).
Kolejnym krokiem jest pobranie z pamięci czasu pracy urządzenia (w sekundach) w momencie logowania administratora, oraz określenie długości jego sesji, poprzez odjęcie od uptime’u pobranej wcześniej wartości. Jeżeli wartość ta przekroczy timeout_value następuje wylogowanie administratora, z komunikatem w logach:
Wylogowanie użytkownika po przekroczeniu timeout’u.
W sytuacji kiedy timeout_value nie zostanie przekroczone, flaga uprawnień user_login_id zostanie zmieniona na 1 oraz pojawi się odpowiedni wpis o próbie logowania:
Zmiana user_login_id oraz komunikat w logach.
Następnie sprawdzana jest wartość flagi user_login_id:
Walidacja user_login_id.
Jeżeli jest mniejsza od 2 (niezalogowany użytkownik) następuje zablokowanie dostępu do panelu administratora i oczywiście wpis do logów.
Kod odpowiedzialny za właściwe logowanie do panelu administratora. (kliknij aby powiększyć)
W przeciwnym wypadku, oczywiście autoryzacja przebiega pomyślnie i można korzystać z panelu administratora z najwyższymi uprawnieniami.