Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Reverse Engineering w praktyce - część 3

ghost666 16 Feb 2017 23:03 3450 0
Computer Controls
  • Reverse Engineering w praktyce - część 3
    W drugiej części artykułu sporo uwagi poświęciliśmy danym zgromadzonym w pamięci analizowanego routera. W części trzeciej nadal zajmować będziemy się danymi, ale zejdziemy niżej - analiza danych niskopoziomowych, będących blisko sprzętu, pozwoli nam dowiedzieć się więcej o urządzeniu i jego działaniu.

    Mając dostęp do sprzętu - wszystkich sygnałów elektrycznych w systemie - mamy w zasadzie dostęp do wszystkich informacji, jakie są w nim zawarte. Przy odrobinie starania i wykorzystaniu odpowiedniego wyposażenie możemy bez problemu wyciągnąć te dane. Wszystko oczywiście zależy, jakim dysponujemy sprzętem: prosty analizator logiczny pozwoli pozwoli nam podsłuchać transmisje cyfrowe, a jeśli możemy zainwestować kilka tysięcy dolarów, to możemy nawet odczytywać szyfrowane klucze prywatne analizując pobór prądu układów scalonych.

    W trzeciej części artykułu przyjrzymy się niskopoziomowym (ale nie tak, jak wspominanie analizowanie poboru prądu) metodom na analizowanie systemu w naszym urządzeniu. Głównie pochylimy się nad interfejsami i spróbujemy podsłuchać transmisje. Tego rodzaju metody są szeroko rozpowszechnione w elektronice, tak podczas normalnego debuggowania jak i podczas analizy nieznanych nam interfejsów.

    Uwaga! Te czynności są na granicy legalności - o ile możemy we własnym zakresie odczytywać i analizować te dane, to publikowanie ich tutaj nie musi być legalne. Autor skonsultował się przed publikacją z działem bezpieczeństwa firmy Huawei.

    Przepływ danych na płytce drukowanej

    Dane same w sobie są bezużyteczne, jeśli nie znamy statycznej zawartości pamięci - koniecznie musimy ją odczytać i sprawdzić, gdzie system zapisuje poszczególne informacje. Prosta analiza płytki drukowanej routera pozwoli nam zanalizować, którędy płyną interesujące nas informacje i gdzie musimy się wpiąć:

    Reverse Engineering w praktyce - część 3


    Nie będziemy poszukiwać żadnych sprzętowych backdoorów, ani innych interfejsów, które zakopane są w sprzęcie zbyt głęboko. Zanalizujemy po prostu transmisję SPI, jaka przebiega pomiędzy Ralinkiem (głównym układem routera) a zewnętrzną pamięcią Flash.

    Zasadniczo każdy układ scalony dostępny komercyjnie posiada swoją kartę katalogową i dokumentację techniczną, więc możemy wyczytać z nich rozkład pinów, napięcie zasilania etc. Cała dokumentacja dostępna jest zazwyczaj publicznie i wystarczy skorzystać z wyszukiwarki. W naszym przypadku interesować nas będą następujące dokumenty:

    Opis układu Ralink RT3352F - nie jest to karta katalogowa, ale zawiera przydatne informacje.
    Karta katalogowa Spansion FL064PIF - 64 Mbit Flash z interfejsem SPI.

    Skoro znamy już rozkład pinów i detale elektryczne protokołu możemy spróbować zajrzeć w transmisję i wydobyć z niej interesujące nas informacje.

    Zrozumieć Flash

    Wiemy już co będzie nas interesować - ruch na interfejsie SPI pomiędzy układem Ralinka a pamięcia Flash. Zacznijmy zatem - po pierwsze musimy podłączyć nasz analizator logiczny. W karcie katalogowej pamięci znajdziemy opis wyprowadzeń układu, więc nie ma potrzeby jego analizowania i inżynierii wstecznej:

    Reverse Engineering w praktyce - część 3


    Standardowo komunikacja po SPI wykorzystuje 4 piny:

    MISO (Master In Slave Out) Komunikacja od pamięci do CPU.
    MOSI (Master Out Slave In) Komunikacja od CPU do pamięci.
    SCK - Zegar interfejsu.
    /CS# (Chip Select) Sygnał aktywacji pamięci (aktywny stan niski) - dzięki temu na jednym interfejsie MISO/MOSI/SCK podłączone może być więcej układów z wieloma /CS.

    Skoro znamy pinout układy możemy podłączyć pod te piny analizator i zobaczyć pierwszą, losową transmisję:

    Reverse Engineering w praktyce - część 3


    Aby ustawić nasz analizator musimy wybrać następujące ustawienia:

    * Najpierw MSB (kierunek bitów w słowie).
    * Liczba bitów w transmisji: 8 (to będzie oczywiste, jak zobaczymy zrzut).
    * CPOL - domyślny stan linii zegara podczas transmisji.
    * CPHA - zbocze zegara które powinno wywoływać akwizycję danych.

    Wszystkie te ustawienia, oprócz CPHA, są dosyć oczywiste, znając interfejs. Z karty katalogowej wyczytać możemy, że układ pamięci działa tylko w dwóch trybach:

    * CPOL = 1, CPHA = 1;
    * CPOL = 0, CPHA = 0.

    Reverse Engineering w praktyce - część 3


    Spójrzmy zatem na odczytane dane:

    Reverse Engineering w praktyce - część 3


    Aby zrozumieć co się tutaj dzieje musimy najpierw zerknąć na zestaw instrukcji FL064PIF, zapisany w karcie katalogowej:

    Reverse Engineering w praktyce - część 3


    I już możemy zobaczyć jakie dane zgrywa nasz analizator:

    Reverse Engineering w praktyce - część 3


    Jak widzimy w karcie katalogowej Flash ten ma kilka trybów odczytu i zapisu dedykowanych do zwiększenia prędkości transmisji: podwójny i poczwórny, które multipleksują transmisję na większą ilość linii - w takiej sytuacji nasz analizator logiczny może sobie nie poradzić, ale z prostej analizy tych transmisji widzimy, że układ nie korzysta z takich sztuczek. Oczywiście dobrze jest przeczytać kartę katalogową wcześniej i wiedzieć czego się spodziewać gdy np. na analizatorze wpiętym w 'normalne' SPI widzimy coś dziwnego.

    Dlaczego prędkość próbkowania jest tak ważna (trochę teorii)

    Analizator logiczny - koncepcyjnie - to bardzo proste urządzenie: odczytuje stan linii cyfrowych co X mikrosekund przez okres Y sekund. Po skończonej akwizycji analizuje zebrane dane i przesyła do komputera wyniki tej analizy. Dla analizatora protokołów ważne jest to, żebyśmy zbierali dane szybciej niż układ je zapisuje, inaczej dane zbite zostaną w nieczytelną masę bitów i zdeformowanych transmisji.

    To jak szybko próbkować transmisję może nasz analizator wynika zasadniczo z tego ile kosztował. Od tego też zależy ile linii może on obserwować naraz. W przypadku analizowania bardziej skomplikowanych interfejsów może nam zabraknąć wejść w analizatorze lub możemy potrzebować po prostu droższego i lepszego sprzętu. W opisywanym artykule transmisja SPI była analizowana niedrogim analizatorem Salea na jego maksymalnej prędkości próbkowania dla tej ilości linii - 24 MS/s.

    Reverse Engineering w praktyce - część 3


    Jak widać na zdjęciu nawet pomimo tego, że widać osiem przejść zegara z stanu niskiego do wysokiego, to przebiegi danych są nieczytelne. Czemu? Zegar interfejsu taktuje dane na liniach MISO i MOSI; deformacje jakie obserwujemy teraz na analizatorze pochodzić mogą z odczytywania danych w złym momencie zegara. Zawsze jest jakiś margines czasu w przebiegu danych, a póki co nie potrzebujemy odczytać poprawnych danych, jednakże dobrze jest pamiętać o wszystkich możliwych miejsc, z których pochodzić mogą problemy, gdy później będziemy chcieli odczytać dane.

    Przesiądźmy się na lepszy analizator i odczytajmy tą transmisję z wyższą prędkością - 100 MS/s.

    Reverse Engineering w praktyce - część 3


    Jak widzimy na załączonym obrazku teraz przebieg zegarowy jest idealnie prostokątny, gdy częstotliwość próbkowania jest odpowiednio wysoka. Analizując tego rodzaju transmisje pamiętajmy zawsze o ograniczeniach naszego sprzętu, uwzględniajmy ile danych jesteśmy utracić i czy nie jest to czas przesiąść się na lepszy analizator albo zrezygnować z tego elementu inżynierii wstecznej.

    Obserwacja przepływu danych

    Znamy już system dosyć dobrze, dzięki analizie jaką przeprowadziliśmy w części drugiej artykułu, więc możemy nastawić się na analizę konkretnych transmisji po SPI, które zawierać mogą interesujące nas dane. Obserwacja oscyloskopem przebiegu na liniach MISO i MOSI pomoże nam sprawdzić kiedy te transmisje są wyzwalane.

    Reverse Engineering w praktyce - część 3


    Na poniższym filmie zobaczyć możemy jak przebiegają transmisje: na interfejsie szeregowym i na SPI, gdy pracujemy na routerze:



    Metoda ta jest doskonała do identyfikacji procesów i akcji, które wyzwalają odczyt/zapis do pamięci flash. Pomoże to nam ocenić, kiedy najlepiej (i na jak długo) włączyć analizator logiczny.

    Analiza transmisji SPI - komenda save z ATP

    W części 2 wspominaliśmy, że linia komend ATP posiada komendę save do zapisu danych w pamięci flash, niestety nie ma do niej żadnej pomocy w APT, więc nie wiemy jak ona działa. Jedyne co pokazuje sama komenda to pasek postępu, więc jedyne co możemy zrobić to zbadać samodzielnie jak to działa. Ułóżmy plan:

    1. Poczekajmy do końca sekwencji bootowania do momentu, którym router nic nie robi, więc nie napotkamy na losowe, niespodziewane transmisje w SPI.
    2. Uruchommy ATP CLI jak w części 1.
    3. Podłączmy do MISO/MOSI oscyloskop i zgrajmy sygnał, aby z grubsza wiedzieć ile czasu i kiedy potrzebujemy na zgranie transmisji.
    4. Ustawmy trigger analizatora tak, aby zaczął zbierać dane gdy tylko /CS zostanie aktywowany.
    5. Zapiszmy dane.
    6. Zanalizujmy dane.

    Kroki 3 oraz 4 można połączyć w jeden, tak więc można obserwować jednocześnie przebieg na oscyloskopie i dane na analizatorze logicznym. Dzięki temu możemy być pewni, że nie stracimy nic z transmisji. Aby wygodnie podłączyć oba urządzenia do układów scalonych na PCB routera wykorzystać możemy tego rodzaju bardzo wygodne klipsy:

    Reverse Engineering w praktyce - część 3


    Kiedy zgramy już transmisję, możemy ją zanalizować i zobaczyć co w niej jest:

    Reverse Engineering w praktyce - część 3


    Zastanówmy się jakiego rodzaju dane możemy wydobyć z tego zrzutu transmisji i jakie z nich mogą być dla nas przydatne. Pracujemy z układem pamięci, więc możemy wyczytać jakie dane są zapisywane i odczytywane oraz spod jakiego adresu. Dane te możemy prezentować na dwa wygodne sposoby:

    1. Mapę ruchu na interfejsie, która pokaże nam - w kolejności chronologicznej - z jakich obszarów pamięci dane są odczytywane, kasowane i zapisywane.
    2. Dane binarne, reprezentujące bloki pamięci, które zostały zapisane lub odczytane. Najlepiej po oczyszczeniu transmisji z wszelkich 'śmieci' związanych z samą transmisją, protokołem etc.

    Analizator SPI Saleae eksportuje dane do pliku CSV. Idealnie byłoby gdybyśmy mogli tak skonfigurować analizator, aby robił to wszystko za nas, ale to bardzo dużo pracy - zbyt wiele jak na ten projekt. Zaletą prostych niskopoziomowych interfejsów jest to, że są bardzo intuicyjne. Autor artykułu stworzył prosty skrypt w Pythonie, który analizuje dane z CSV za nas i ekstrahuje to co nas interesuje. Skrypty te pobrać można z githuba:

    * Binmaker
    * Traffic mapper

    Praca z wykorzystaniem tych skryptów jest bardzo prosta.

    Po eksporcie danych do CSV i wczytaniu ich do skryptu:

    1. Iteruje on po poszczególnych elementach zrzutu.
    2. Identyfikuje różne komendy
    3. Rozpoznaje komendy
    4. Przetwarza argumenty tych komend (adresy etc).
    5. Identyfikuje akcje odczytu i zapisu.
    6. Konwertuje zapisywane/odczytywane bajty na znaki ASCII.
    7. Zapisuje dane binarne do plików: osobno dla MISO (odczyt) i MOSI (zapis).

    Odczytaj dane wygenerowane przez skrypty komendą:

    Code: bash
    Log in, to see the code
    )

    Wyniki działania skryptów na zgranych danych wyglądają następująco:

    * Mapa ruchu
    * MOSI
    * MISO
    * Lista plików, dane dzielone po adresie

    Mapa ruchu jest szczególnie interesująca w połączeniu z znaną z poprzedniej części mapą pamięci Flash:

    Reverse Engineering w praktyce - część 3


    Z zebranej mapy ruchu widzimy, że znaczna większość komend zapisu jest bardzo prosta:

    1. Odczyt 64 kB danych z zabezpieczonego obszary.
    2. Nadpisanie odczytanych danych.

    W pliku binarnym, pochodzącym z linii MISO widzimy, że są to głównie po prostu jedynki:

    Reverse Engineering w praktyce - część 3


    Większość odczytanych z MOSI danych to zwykły XML zapisany tekstowo i wygląda on jak plik /var/curcfg.xml, który odkryliśmy w części drugiej artykułu. Plik ten zawiera aktualną konfigurację systemu, m.in. obecne dane do logowania do WiFi.

    Standardem jest trzymanie tego rodzaju danych w zarezerwowanych obszarach pamięci Flash. Zazwyczaj są to krytyczne dla działania urządzenia dane, które konieczne są po restarcie urządzenia, ale mogą być konfigurowane przez użytkownika, firmware lub w fabryce. Ma to sens, że komenda zapisu konfiguracji będzie właśnie w tym obszarze zapisywać. Tłumaczy to też czemu dane da się tak łatwo odczytać - nie są one skompresowane itp tak jak jest w przypadku systemu plików na routerze. Tłumaczy to też czemu dane wyglądają jak plik XML, który odnaleźliśmy w folderze /var/ na urządzeniu - to folder danych konfiguracyjnych, potrzebny do konfiguracji i działania urządzenia.

    Garniec złota na końcu firmware (znowu trochę teorii

    Podczas całego omawianego procesu dobrze jest mieć jakiś nadrzędny cel, który pomoże nam ukierunkować swoje działania. W naszym przypadku jest on jeden: wydobyć algorytm, który generuje domyślne hasło do sieci WiFi routera. Jeśli uda nam się zdobyć algorytm i jeżeli generuje on rzeczone hasło na podstawie jakichkolwiek dostępnych publicznie danych, to zasadniczo każdy router tego typu na świecie może stać przed nami otworem.

    Jest to poważny problem - w wielu przypadkach jest tak, że hasło generowane jest na podstawie SSID routera bądź MACa Acces Pointa, co czyni je podatnymi na ataki. Oczywiście nie każdy router jest podatny na tego rodzaju atak, ten wcale nie musi być. Chodzi tutaj głównie po prostu o uchwycenie pewnego modus operandi, typowego dla inżynierii wstecznej systemów wbudowanych - zależy nam na uzyskaniu jakichś danych zapisanych w firmware układu, które mogą być unikalne dla niego - od hasła do WiFi do danych uwierzytelniania systemów IoT w sieci.

    Problem naklejek

    W dzisiejszych czasach podłączyć do routera chcemy się poprzez WiFi - podłączanie się po kablu, aby uniknąć koniecznosci generowania domyślnego hasła nie wchodzi w grę. Można by wykorzystać mały wyświetlacz na urządzeniu, aby zaprezentować tam domyślne hasło, ale to bardzo drogie rozwiązanie... Dlatego też generuje się domyślne hasła, drukuje na naklejkach i nakleja na obudowie.

    Reverse Engineering w praktyce - część 3


    Hasło do WiFi jest tym unikalnym fragmentem danych, którego szukamy. Jednocześnie wiemy, że firmware doskonale wie jak hasło to jest generowane i przyjmuje domyślne hasło bez problemu. Developerzy rozwiązują ten problem zazwyczaj na dwa sposoby:

    1. Ten sam algorytm implementowany jest w urządzeniu i w drukarce naklejek. Oba są zasilane tymi samymi danymi wejściowymi.
    2. Komputer drukujący naklejki generuje hasła i jednocześnie wgrywa je do urządzenia.

    Abstrahując od niekompetencji developerów pierwszy sposób jest generalnie rzadko używany, na przykład gdy producent nie jest w stanie flashować każdego urządzenia z osobna unikalnymi danymi, lub zwiększa to powyżej budżetu koszt wykonania.

    Drugie podejście jest znacznie lepsze: nie wgrywamy wtedy do systemu danych, które są na tyle istotne, aby mogły narazić na szwank bezpieczeństwo całej serii urządzeń.

    The second approach is much better by design: We’re not trusting the hardware with data sensitive enough to compromise every other device in the field. That being said, the company may still decide to use an algorithm with predictable outputs instead of completely random data; that would make the system as secure as the weakest link between the algorithm -mathematically speaking-, the confidentiality of their source code and the security of the computers/network running it.

    Analiza wgrywania ustawień fabrycznych

    Gdy już znamy nasze założenia, zbierzmy trochę danych z nimi związanych. Pierwszą rzeczą, jaką chcemy sprawdzić jest to co wywołuje przepływ interesujących nas danych na PCB. W naszym przypadku będzie to jedna akcja - przytrzymanie przycisku powrotu do ustawień fabrycznych przez 10 sekund. Powinno to zastąpić aktualne ustawienia routera (m.in. dane do logowania) domyślnymi. W takiej sytuacji domyślne dane uwierzytelniania z pewnością będą musiały być wygenerowane więc odczytany zostanie algorytm zapisany w pamięci Flash, a mu przechwycimy do podsłuchując transmisję. Brzmi prosto?

    Jednocześnie obserwować będziemy interfejs UART z pomocą oscyloskopu. Pozwoli nam to sprawdzić jakie wykonane zostaną operacji - analogicznie jak podczas analizy działania komendy save powłoki ATP.

    Wyjście UART:

    Reverse Engineering w praktyce - część 3


    Przegląd ruchu:

    Reverse Engineering w praktyce - część 3


    Wyjście z naszych Pythonowych skryptów:

    * Mapa Ruchu
    * Zrzut MISO
    * Zrzut MOSI

    Mapa ruchu mówi nam, że urządzenie odczytuje a potem nadpisuje dwa duże kawałki pamięci z obszaru chronionego, a potem odczytuje mniejszy kawałek z obszaru systemu plików (być może jest to kolejna operacja do wykonania):

    Code:
    ___________________
    
    |Transmission  Map|
    |  MOSI  |  MISO  |
    |        |0x7e0000| Size: 12    // Część obszaru chronionego
    |        |0x7e0000| Size: 1782
    |        |0x7e073d| Size: 63683
    | ERASE 0x7e073d  | Size: 64kB
    |0x7e073d|        | Size: 195
    |0x7e0800|        | Size: 256
    |0x7e0900|        | Size: 256
    ---------//--------
           [...]
    ---------//--------
    |0x7e0600|        | Size: 256
    |0x7e0700|        | Size: 61
    |        |0x7d0008| Size: 65529 // Część obszaru chronionego
    | ERASE 0x7d0008  | Size: 64kB
    |0x7d0008|        | Size: 248
    |0x7d0100|        | Size: 256
    ---------//--------
           [...]
    ---------//--------
    |0x7dff00|        | Size: 256
    |0x7d0000|        | Size: 8
    |        |0x1c3800| Size: 512   // Część obszaru chronionego
    |        |0x1c3a00| Size: 512
    ---------//--------
           [...]
    ---------//--------
    |        |0x1c5a00| Size: 512
    |        |0x1c5c00| Size: 512
    -------------------


    Teraz gdy połączymy tą wiedze z plikami binarnymi możemy zrozumieć trochę więcej na temat resetu do ustawień fabrycznych układu:

    1. Odczytaj ATP_LOG z pamięci Flash - zawiera on informacje o dostępie zdalnym do routera i ustawieniach fabrycznych; kończy się blokiem jedynek (0xFF).
    2. Nadpisz cały segment pamięci jedynkami (0xFF).
    3. Zapisz nowy ATP_LOG waz aktualną konfiguracją w pliku curcfg.xml.
    4. Odczytaj fragment skompresowanych danych z systemu plików.

    Jako że skompresowane dane odczytywane, które są odczytywane z regionu systemu plików, są odczytywane PO zapisaniu ustawień (wraz z hasłem) nie znajdziemy tam raczej algorytmu jego generowania. Oznacza to, że może on być załadowany już wcześniej do pamięci, albo w ogóle nie istnieć, ale o tym nie możemy przesądzać.

    W danych zebranych z MOSI widzimy nowe hasło WiFi zapisywane jako string w XMLu:

    Reverse Engineering w praktyce - część 3


    Zatem skąd bierze się hasło? Nie widzimy go w danych zebranych z MISO, więc albo jest odczytywane z wykorzystaniem jakiegoś innego trybu odczytu z pamięci Flash, albo algorytm jest już załadowany w pamięci RAM. Ta druga opcja wydaje się być bardziej prawdopodobna, więc nie będziemy bawić się w analizowanie zrzutów transmisji pod kątem innych trybów.

    A co dzieje się gdy zmieniamy ustawienia na inne? na przykład podczas zapisu nowego hasła? Tak jak się spodziewamy - układ odczytuje obszar pamięci i następnie nadpisuje go nowymi ustawieniami.

    Reverse Engineering w praktyce - część 3


    Jak widać hasło jest zapisane zwykłym tekstem w pamięci Flash. To w sumie może oznaczać, że urządzenie nie posiada żadnego algorytmu generacji domyślnego hasła, ale na tym etapie nie możemy tego potwierdzić na 100%. Być może developerzy zdecydowali się ładować algorytm do RAMu jednorazowo, np. podczas ładowania systemu - pozwala to zminimalizować ilość odczytów i zapisów tego algorytmu do pamięci; pozwala to lepiej ukryć dane dotyczące tego algorytmu. Gdyby był on ładowany za każdym razem to byłby o wiele łatwiejszy do podsłuchania.

    Kolejne kroki

    Teraz mając już cały kod możemy binarnie odtworzyć transmisję i jej mapę w krótką chwilę. Kolejnym krokiem będzie komunikacja bezpośrednio z ukłądem Flash, aby zgrać całą zawartość pamięci. To w kolejnej części.

    Źródło: http://jcjc-dev.com/2016/05/23/reversing-huawei-3-sniffing/

    Cool? Ranking DIY
    Can you write similar article? Send message to me and you will get SD card 64GB.
    About Author
    ghost666
    Translator, editor
    Offline 
    Fizyk z wykształcenia. Po zrobieniu doktoratu i dwóch latach pracy na uczelni, przeszedł do sektora prywatnego, gdzie zajmuje się projektowaniem urządzeń elektronicznych i programowaniem. Od 2003 roku na forum Elektroda.pl, od 2008 roku członek zespołu redakcyjnego.
    ghost666 wrote 11099 posts with rating 9410, helped 157 times. Live in city Warszawa. Been with us since 2003 year.
  • Computer Controls