Oprogramowanie

https://chacker.pl/

Wszystkie omawiane dotąd urządzenia byłyby bezużyteczne bez czegoś, co definiuje ich funkcjonalność. W systemach opartych na mikrokontrolerach/mikroprocesorach oprogramowanie definiuje możliwości i tchnie życie w system. Bootloader jest używany do inicjalizacji procesora i uruchomienia oprogramowania systemowego. Oprogramowanie systemowe dla tych systemów zazwyczaj mieści się w jednym z tych trzech scenariuszy:

  • Brak systemu operacyjnego W przypadku prostych systemów
  • System operacyjny czasu rzeczywistego W przypadku systemów ze sztywnymi wymaganiami czasowymi przetwarzania (na przykład VxWorks i Nucleus)

• Ogólny system operacyjny W przypadku systemów, które zazwyczaj nie mają ograniczeń czasowych i mają wiele wymagań funkcjonalnych (na przykład Linux i Embedded Windows)

SWD

https://chacker.pl/

Serial Wire Debug (SWD) to protokół specyficzny dla ARM do debugowania i programowania. W przeciwieństwie do bardziej powszechnego pięciopinowego JTAG, SWD używa dwóch pinów. SWD zapewnia zegar (SWDCLK) i dwukierunkową linię danych (SWDIO), aby zapewnić funkcjonalność debugowania JTAG. Jak widać w Tabeli 20-4, SWD i JTAG mogą współistnieć, co jest ważne.

Możliwości dla programistów i testerów są takie same, jak te wymienione dla JTAG. Podobnie jak w przypadku JTAG, możliwości, które pomagają producentom, umożliwiają również atakującym odkrywanie luk.

JTAG

https://chacker.pl/

Joint Test Action Group (JTAG) została utworzona w latach 80. jako metoda ułatwiająca debugowanie i testowanie układów scalonych. W 1990 r. metoda została znormalizowana jako IEEE 1149.1, ale powszechnie nazywa się ją po prostu JTAG. Chociaż początkowo została stworzona, aby pomóc w testowaniu na poziomie płyty, jej możliwości umożliwiają debugowanie na poziomie sprzętu. Chociaż jest to zbytnie uproszczenie, JTAG definiuje mechanizm wykorzystywania kilku dostępnych zewnętrznie sygnałów w celu uzyskania dostępu do wnętrza układu scalonego za pośrednictwem znormalizowanej maszyny stanowej. Mechanizm jest znormalizowany, ale rzeczywista funkcjonalność za nim stojąca jest specyficzna dla układu scalonego. Oznacza to, że musisz znać debugowany układ scalony, aby skutecznie używać JTAG. Na przykład sekwencja bitów do procesora ARM i procesora MIPS będzie interpretowana inaczej przez wewnętrzną logikę procesora. Narzędzia takie jak OpenOCD wymagają plików konfiguracyjnych specyficznych dla urządzenia, aby działać prawidłowo. Mimo że producenci mogą definiować więcej pinów, opis czterech/pięciu pinów JTAG znajduje się w Tabeli.

Zbiór pinów jest znany również jako port dostępu testowego (TAP). Chociaż można by pomyśleć, że pięć pinów ma standardowy układ, producenci płyt i układów scalonych definiują własne układy. Niektóre typowe układy pinów są zdefiniowane w Tabeli  i obejmują konfiguracje 10-, 14- i 20-pinowe. Układy pinów w tabeli są tylko próbką i muszą zostać zweryfikowane przed użyciem z debugerem.

Dla programistów i testerów powszechnie używane są następujące możliwości:

  • Zatrzymywanie procesora podczas debugowania
  • Odczyt i zapis wewnętrznego magazynu programów (gdy kod jest przechowywany wewnątrz mikrokontrolera)
  • Odczyt i zapis flash (modyfikacja lub ekstrakcja oprogramowania układowego)
  • Odczyt i zapis pamięci
  • Modyfikacja przepływu programu w celu pominięcia funkcjonalności w celu uzyskania ograniczonego dostępu

Jak widać, funkcjonalność dostępna dla interfejsu JTAG jest dość potężna. Producenci sprzętu znajdują się w tarapatach. Aby rozwijać, testować i debugować system wbudowany przez cały cykl jego życia, port JTAG jest niezbędny; jednak jego obecność na płycie daje badaczom i atakującym możliwość odkrywania sekretów, zmiany zachowania i znajdowania luk w zabezpieczeniach. Producenci zazwyczaj próbują utrudnić korzystanie z interfejsu JTAG po produkcji, przecinając linie, nie wypełniając pinów, nie oznaczając wyprowadzeń lub wykorzystując możliwości układu scalonego w celu jego wyłączenia. Chociaż jest to dość skuteczne, zdeterminowany atakujący ma wiele środków w swoim arsenale, aby ominąć zabezpieczenia, w tym naprawianie uszkodzonych ścieżek, lutowanie pinów na płytce, a nawet ewentualnie wysłanie układu scalonego do firmy specjalizującej się w wydobywaniu danych. Niektórzy mogą odrzucić JTAG jako słabość, ponieważ do jego użycia wymagany jest fizyczny, potencjalnie destrukcyjny dostęp. Problem z odrzuceniem ataku polega na tym, że atakujący może dowiedzieć się wiele o systemie za pomocą JTAG. Jeśli w systemie znajduje się globalny sekret, taki jak hasło, celowe tylne wejście do pomocy technicznej, klucz lub certyfikat, może on zostać wyodrębniony i następnie użyty do ataku na zdalny system.

Interfejsy debugowania

https://chacker.pl/

Podczas gdy debugowanie aplikacji na komputerze z systemem Windows lub Linux jest stosunkowo łatwe, po prostu poprzez dołączenie do procesu za pomocą debugera programowego, systemy wbudowane mają wiele przeszkód, które sprawiają, że taki proces jest nieco trudniejszy. Na przykład, jak debugować system wbudowany, gdy nie ma systemu operacyjnego lub system operacyjny nie jest uruchomiony? Nowoczesne systemy wbudowane mają również wiele skomplikowanych układów scalonych na potencjalnie gęsto zaludnionych płytkach z niewielkim lub żadnym dostępem do pinów na układach scalonych. Na szczęście dla programistów i testerów, przemysł produkcji sprzętu opracował metody dostępu do wnętrza układów scalonych w celu testowania, debugowania i zapisywania oprogramowania układowego w pamięci nieulotnej oraz do wielu innych zastosowań.

I2C

https://chacker.pl/

Inter-Integrated-Circuit, wymawiane I-kwadrat-C i zapisywane jako I2C, to protokół komunikacji szeregowej z wieloma masterami, wieloma slave’ami i pakietami. Jest wolniejszy niż SPI, ale używa tylko dwóch pinów zamiast trzech, plus wybór układu dla każdego slave’a. Podobnie jak SPI, I2C jest używany na krótkich odległościach między układami scalonymi na płycie, ale może być używany w okablowaniu. W przeciwieństwie do SPI, I2C jest oficjalną specyfikacją. Chociaż obsługiwanych jest wiele masterów, nie mogą się one ze sobą komunikować i nie mogą jednocześnie korzystać z magistrali. Aby komunikować się z określonym urządzeniem, master używa pakietu adresowego, po którym następuje jeden lub więcej pakietów danych. Dwa piny są następujące:

  • Zegar szeregowy SCL
  • Dane szeregowe SDA

Z rysunku widać, że pin SDA jest dwukierunkowy i współdzielony przez wszystkie urządzenia. Ponadto pin SCL jest sterowany przez urządzenie nadrzędne, które uzyskało magistralę danych.

Podobnie jak SPI, I2C jest powszechnie używany do komunikacji z EEPROM lub NVRAM (nieulotna pamięć o dostępie swobodnym). Używając czegoś takiego jak Bus Pirate, możesz zrzucić zawartość do analizy offline lub zapisać nowe wartości.

SPI

https://chacker.pl/

Serial Peripheral Interface (SPI) to pełnodupleksowy synchroniczny interfejs szeregowy, który jest popularny w systemach wbudowanych. W przeciwieństwie do UART, SPI został zaprojektowany, aby umożliwić komunikację między dwoma lub większą liczbą urządzeń. SPI to protokół krótkiego zasięgu, który jest używany do komunikacji między układami scalonymi w systemie wbudowanym. Protokół wykorzystuje architekturę master/slave i obsługuje wiele urządzeń slave.4 W najprostszej formie SPI wymaga czterech pinów do komunikacji, co stawia go na równi z przykładem UART, ale z szybszą komunikacją (kosztem odległości). Ważne jest, aby pamiętać, że SPI nie jest standaryzowany,5 a arkusze danych będą musiały zostać sprawdzone, aby określić dokładne zachowanie każdego urządzenia. Cztery piny są następujące:

  • SCK Serial Clock
  • MOSI Master Out Slave In
  • MISO Master In Slave Out
  • SS lub CS Slave/Chip Select (wyjście z urządzenia master do adresu slave; aktywny niski)

W przypadku systemów z kilkoma urządzeniami slave, urządzenie master zazwyczaj adresuje każde urządzenie slave za pomocą dedykowanego wyboru układu. Ze względu na dodatkowe wybieranie układów wymaga to więcej pinów/ścieżek i zwiększa koszt systemu. Na przykład system z trzema urządzeniami podrzędnymi w tej konfiguracji wymaga sześciu pinów na mikrokontrolerze

Inną powszechną konfiguracją dla urządzeń z wieloma urządzeniami podrzędnymi jest układ szeregowy. Konfiguracja układu szeregowego, pokazana na rysunku, jest zwykle używana, gdy urządzenie nadrzędne nie musi odbierać danych do zastosowań takich jak diody LED lub gdy istnieje wiele urządzeń podrzędnych. Ponieważ wyjście układu scalonego 1 jest podłączone do wejścia układu scalonego 2 itd., występuje opóźnienie proporcjonalne do liczby układów scalonych między urządzeniem nadrzędnym a docelowym odbiorcą.

Typowym zastosowaniem protokołu SPI jest dostęp do pamięci EEPROM (elektrycznie kasowalnej programowalnej pamięci tylko do odczytu) i urządzeń flash. Używając Bus Pirate i flashrom (lub czegoś podobnego), powinieneś być w stanie wyodrębnić zawartość pamięci EEPROM lub urządzenia flash. Zawartość można następnie przeanalizować, aby zlokalizować system plików i polować na sekrety.

UART

https://chacker.pl/

Protokół Universal Asynchronous Receiver-Transmitter umożliwia dwóm urządzeniom komunikację szeregową przez kanał komunikacyjny. UART jest powszechnie używany do łączenia się z konsolą, aby umożliwić człowiekowi interakcję z urządzeniem. Chociaż większość urządzeń nie będzie miała zewnętrznie dostępnego interfejsu do komunikacji szeregowej, wiele będzie miało wewnętrzny interfejs, który był używany podczas opracowywania i testowania urządzenia. Podczas przeprowadzania testów urządzeń znalazłem zarówno uwierzytelnione, jak i nieuwierzytelnione konsole na wewnętrznie dostępnych interfejsach szeregowych. UART wymaga trzech pinów do komunikacji i zwykle występuje w grupie czterech pinów .

Na płytce możesz zobaczyć etykiety, ale zazwyczaj te pady lub nagłówki nie są oznaczone i trzeba je odkryć. Chociaż Rysunek  pokazuje ładny przykład, w którym nagłówki wyróżniają się jako kandydaci do komunikacji szeregowej, układ pinów może nie zawsze być tak prosty i może być pomieszany w większej liczbie pinów. Głównym powodem lokalizowania i łączenia się z wewnętrznymi portami szeregowymi jest próba zlokalizowania informacji, które nie miały być dostępne dla użytkownika systemu. Na przykład interfejs sieciowy zazwyczaj nie zapewnia bezpośredniego dostępu do systemu plików, ale konsola szeregowa w systemie opartym na systemie Linux zapewni użytkownikowi dostęp do systemu plików. Gdy port szeregowy zostanie uwierzytelniony, będziesz musiał brutalnie wymusić poświadczenia lub spróbować ominąć uwierzytelnianie, zmieniając proces rozruchu (potencjalnie za pomocą portu debugowania JTAG). Aby odkryć pady szeregowe, można użyć narzędzia takiego jak JTAGulator, opracowanego przez Joe Granda, aby uzyskać sygnały metodą brute-force i uzyskać układ padów oraz szybkość transmisji. Poniżej znajduje się przykład uruchomienia testu identyfikacji UART na Ubiquiti ER-X pokazanym na rysunku 20-1, gdzie oznaczone piny zostały zidentyfikowane za pomocą JTAGulatora. Oto kroki:

  1. Zlokalizuj nagłówki lub pady, które Twoim zdaniem mogą być UART, poprzez sprawdzenie płytki. (Widzenie dwóch do czterech padów/pinów zgrupowanych razem na płytce to dobry znak, ale jak wspomniano wcześniej, mogą być one przeplatane z innymi funkcjonalnymi padami/pinami.)
  2. Odkryj napięcie docelowe, badając płytkę multimetrem lub identyfikując układ scalony i sprawdzając arkusz danych.
  3. Odkryj uziemienie, do którego łatwo się podłączyć, mierząc rezystancję (omy) między znanym uziemieniem (takim jak uziemienie obudowy) a pinami, do których łatwo się podłączyć (efektywnie 0 omów między znanym uziemieniem a danym pinem).
  4. Podłącz płytkę do JTAGulatora, jeśli masz wystarczająco dużo szczęścia, aby znaleźć nagłówki, lub przylutuj nagłówek do płytki, a następnie podłącz.
  5. Sprawdź wersję oprogramowania układowego JTAGulatora (1). Wersję można sprawdzić w oparciu o kod w repozytorium pod adresem https://github.com/grandideastudio/jtagulator/releases. Jeśli wersja nie jest najnowsza, postępuj zgodnie z instrukcjami na stronie www.youtube.com/watch? v=xlXwy-weG1M.
  6. Włącz tryb UART (2) i ustaw napięcie docelowe (3).
  7. Uruchom test identyfikacji UART (4).
  8. W przypadku powodzenia poszukaj rozsądnych odpowiedzi, takich jak powrót karetki, przesunięcie wiersza lub czytelny tekst (5) (synchronizacja l-timers(q)).

9. Zweryfikuj zidentyfikowane ustawienia, uruchamiając w trybie pass-thru (6) z kandydatem na szybkość transmisji (7) 57600 w naszym przypadku).

Na płytce możesz zobaczyć etykiety, ale zazwyczaj te pady lub nagłówki nie są oznaczone i trzeba je odkryć. Chociaż Rysunek  pokazuje ładny przykład, w którym nagłówki wyróżniają się jako kandydaci do komunikacji szeregowej, układ pinów może nie zawsze być tak prosty i może być pomieszany w większej liczbie pinów. Głównym powodem lokalizowania i łączenia się z wewnętrznymi portami szeregowymi jest próba zlokalizowania informacji, które nie miały być dostępne dla użytkownika systemu. Na przykład interfejs sieciowy zazwyczaj nie zapewnia bezpośredniego dostępu do systemu plików, ale konsola szeregowa w systemie opartym na systemie Linux zapewni użytkownikowi dostęp do systemu plików. Gdy port szeregowy zostanie uwierzytelniony, będziesz musiał brutalnie wymusić poświadczenia lub spróbować ominąć uwierzytelnianie, zmieniając proces rozruchu (potencjalnie za pomocą portu debugowania JTAG). Aby odkryć pady szeregowe, można użyć narzędzia takiego jak JTAGulator, opracowanego przez Joe Granda, aby uzyskać sygnały metodą brute-force i uzyskać układ padów oraz szybkość transmisji. Poniżej znajduje się przykład uruchomienia testu identyfikacji UART na Ubiquiti ER-X pokazanym na rysunku 20-1, gdzie oznaczone piny zostały zidentyfikowane za pomocą JTAGulatora. Oto kroki:

  1. Zlokalizuj nagłówki lub pady, które Twoim zdaniem mogą być UART, poprzez sprawdzenie płytki. (Widzenie dwóch do czterech padów/pinów zgrupowanych razem na płytce to dobry znak, ale jak wspomniano wcześniej, mogą być one przeplatane z innymi funkcjonalnymi padami/pinami.)
  2. Odkryj napięcie docelowe, badając płytkę multimetrem lub identyfikując układ scalony i sprawdzając arkusz danych.
  3. Odkryj uziemienie, do którego łatwo się podłączyć, mierząc rezystancję (omy) między znanym uziemieniem (takim jak uziemienie obudowy) a pinami, do których łatwo się podłączyć (efektywnie 0 omów między znanym uziemieniem a danym pinem).
  4. Podłącz płytkę do JTAGulatora, jeśli masz wystarczająco dużo szczęścia, aby znaleźć nagłówki, lub przylutuj nagłówek do płytki, a następnie podłącz.
  5. Sprawdź wersję oprogramowania układowego JTAGulatora (1). Wersję można sprawdzić w oparciu o kod w repozytorium pod adresem https://github.com/grandideastudio/jtagulator/releases. Jeśli wersja nie jest najnowsza, postępuj zgodnie z instrukcjami na stronie www.youtube.com/watch? v=xlXwy-weG1M.
  6. Włącz tryb UART (2) i ustaw napięcie docelowe (3).
  7. Uruchom test identyfikacji UART (4).
  8. W przypadku powodzenia poszukaj rozsądnych odpowiedzi, takich jak powrót karetki, przesunięcie wiersza lub czytelny tekst (5) (synchronizacja l-timers(q)).

9. Zweryfikuj zidentyfikowane ustawienia, uruchamiając w trybie pass-thru (6) z kandydatem na szybkość transmisji (7) 57600 w naszym przypadku).

  • Działa na systemie Linux w wersji 3.10.14-UBNT:

  • Partycje MTD pomagają zrozumieć układ pamięci masowej:

Po ustaleniu układu możesz użyć narzędzia takiego jak Bus Pirate, aby połączyć się z padami i komunikować się z systemem wbudowanym. Najważniejszą rzeczą do zapamiętania jest podłączenie TX na urządzeniu do RX Twojego Bus Pirate i podłączenie RX na urządzeniu do TX Twojego Bus Pirate. Podobnie jak w przypadku interfejsu JTAG, niektórzy mogą bagatelizować powagę włączenia portów szeregowych na urządzeniu. Jednak dzięki dostępowi do konsoli atakujący może wyodrębnić konfigurację i pliki binarne, zainstalować narzędzia i poszukać globalnych sekretów, które ułatwiają zdalne ataki na wszystkie urządzenia tego typu.

Interfejsy szeregowe

https://chacker.pl/

Interfejs szeregowy komunikuje się z równorzędnym elementem jeden bit na raz, szeregowo, przez kanał komunikacyjny. Ponieważ tylko jeden bit jest przesyłany na raz, w układzie scalonym potrzeba mniej pinów. Natomiast komunikacja interfejsu równoległego przesyła wiele bitów na raz i wymaga większej liczby pinów (jeden pin na bit). W systemach wbudowanych stosuje się kilka protokołów szeregowych, ale omówimy tylko protokoły Universal Asynchronous Receiver-Transmitter (UART), Serial Peripheral Interface (SPI) i Inter-Integrated-Circuit (I2C).

Typowe architektury procesorów

https://chacker.pl/

Chociaż istnieje wiele architektur mikrokontrolerów, takich jak Intel 8051, Freescale (Motorola) 68HC11 i Microchip PIC, dwie architektury pojawiają się znacznie częściej w urządzeniach podłączonych do Internetu: ARM i MIPS. Znajomość architektury procesora jest ważna podczas korzystania z narzędzi, takich jak deasemblery, narzędzia do kompilacji i debugery. Identyfikację architektury procesora można zazwyczaj przeprowadzić poprzez wizualną inspekcję płyty i zlokalizowanie procesora. ARM to licencjonowana architektura, z której korzysta wielu producentów mikroprocesorów, mikrokontrolerów i układów SoC, takich jak Texas Instruments, Apple, Samsung i inni. Rdzenie ARM są licencjonowane w wielu profilach w zależności od zamierzonych zastosowań. Rdzenie ARM występują w architekturach 32- i 64-bitowych i mogą być skonfigurowane jako big- lub little-endian. MIPS, ostatnio należący do Wave Computing, który niedawno wyszedł z bankructwa, nie jest już rozwijany na rzecz RISC-V; jednak umowy licencyjne podpisane przed restrukturyzacją wydają się być ważne. MIPS został licencjonowany przez kilku producentów, takich jak Broadcom, Cavium i inni. Podobnie jak ARM, MIPS ma warianty 32- i 64-bitowe i może być uruchamiany w trybie big- lub little-endian. Jest powszechnie spotykany w urządzeniach sieciowych, takich jak bezprzewodowe punkty dostępowe i małe routery domowe.

System on Chip

https://chacker.pl/

System on Chip (SoC) to jeden lub więcej rdzeni mikroprocesora lub mikrokontrolerów z szeroką gamą zintegrowanych funkcji sprzętowych w jednym układzie scalonym (IC). Na przykład SoC telefonu może zawierać jednostkę przetwarzania grafiki (GPU), procesor dźwięku, jednostkę zarządzania pamięcią (MMU), kontroler komórkowy i sieciowy. Główną zaletą SoC jest niższy koszt dzięki mniejszej liczbie chipów i mniejszym aplikacjom, które są zazwyczaj używane w bardziej niestandardowy sposób. Podczas gdy mikrokontroler przechowuje program wewnętrznie i zapewnia ograniczoną pamięć, SoC zazwyczaj wykorzystuje zewnętrzną pamięć masową i pamięć.