Bloby i szyfry. Przyjemna konsolowa przygoda

ciemnastrona.com.pl 1 rok temu
Zdjęcie: Obrazek pokazujący krzyczącą twarz uwięzioną w galarecie z plakatu filmu The Blob. Całość widać zza półprzezroczystej ściany zer i jedynek


Swego czasu ukazał się interesujący post na stronie devever.net, zatytułowany The i.MX8 cannot be deblobbed.

Odwołuje się on do smutnego faktu, iż podstawowe części naszych telefonów opierają się na zamkniętych, nieprzeniknionych programach.
Nawet telefony stawiające na prywatność i otwarty kod muszą, chcąc nie chcąc, polegać na takich podzespołach. Bo nie ma alternatyw.

Autor potwierdził w swoim wpisie, iż kontrola sięga głębiej. choćby gdyby ktoś stworzył wierny zamiennik dla zamkniętego programu, to nie wszystko by działało. Bo programy mogą być ściśle przypisane do części poprzez szyfrowanie (a dokładniej: przez bazujący na nim cyfrowy podpis).

Nasza zależność od takich modułów jest kolejnym objawem centralizacji władzy. Zmory współczesnych czasów.

Mój wpis nie będzie jednak omówieniem tej patologii, ale czymś bardziej popularyzatorskim. Zweryfikuję odkrycie autora, komentując przystępnym językiem jego działania.

Dzięki temu osoby, które nie znają świata programików konsolowych, będą mogły nieco się z nim oswoić. Zobaczyć, iż za tajemniczymi zaklęciami kryją się czasem zadziwiająco proste rzeczy :wink:

Kontekst

Współczesne telefony zawierają wiele różnych elementów. Modem. Układ obsługujący karty SIM. Moduł Bluetooth. Żyroskop. I wiele innych.

Tymi fizycznymi częściami steruje pewien szczególny rodzaj programów, nazywanych firmware’em. Są zwykle stworzone przez producentów i ściśle zintegrowane z funkcjami fizycznych części.

Są również nieprzeniknione – to często bloki złożone z zer i jedynek. Dokładny opis ich funkcji nie jest publicznie dostępny. Żargonowo nazywa się je binary large objects, duże obiekty binarne. Nieformalny skrót to bloby.

Ich nieprzejrzystość jest problemem – nie wiadomo, czy nie działają na szkodę użytkowników, na przykład wysyłając ukradkiem informacje (dotyczy to zwłaszcza blobów w modemie).
A choćby jeżeli nie, to mogą mieć jakieś luki w zabezpieczeniach, które kiedyś pozwoliłyby hakerom dobrać się do naszych urządzeń.

To między innymi z tych powodów osoby związane z ruchem open source wzięły sobie za cel zastąpienie blobów otwartym kodem, który każdy mógłby zweryfikować. Ich inicjatywy nazywa się nieformalnie deblobbingiem, „walką z blobami”.

Źródła: plakat horroru The Blob z 1988 roku, zera i jedynki z Pixabay. Aranżacja moja.

Ale niektórzy producenci nie lubią otwartej konkurencji, która mogłaby ich wygryźć. Próbują wymusić, żeby fizyczny sprzęt akceptował jedynie ich własny firmware. Mogą wykorzystywać do tego celu certyfikaty – cyfrowe podpisy niemożliwe do podrobienia.

Zbadaniem takiej kwestii zajął się Hugo Landau, autor strony Devever.
Wyczytał w dokumentach fragment, który dało się rozumieć dwojako. I spróbował wykazać, iż bloby związane z procesorami i.MX 8 oraz i.MX 8M są właśnie w ten sposób zaplombowane.

Motywowało go między innymi to, iż takich procesorów używają rzekomo prywatnościowe telefony firmy Librem (choć niektórzy tego nie potwierdzają).

Konieczność bazowania na niezaufanym kodzie byłaby dla nich szczególnie mocnym ciosem. Ale na rynku niestety nie jest na tyle łatwo o procesory dla urządzeń mobilnych, żeby mogli wybrzydzać.

Ciekawostka

Dokładniej rzecz biorąc, autor skupił się na kodzie odpowiedzialnym za obsługę popularnego złącza od multimediów, HDMI.
Na forum HackerNews znajdziemy spekulacje o tym, iż uszczelnianie tego konkretnego kodu może wynikać z chęci przypodobania się producentom filmów. To grupa często naciskająca na to, żeby chronić ich treści przed użytkownikami.

Misja autora opierała się na następujących krokach:

  • zdobyć firmware od producenta, firmy NXP;
  • znaleźć w jego bebechach certyfikat;
  • sprawdzić, czy jest przypisany do tego konkretnego producenta.

Powtarzamy kroki

Autor opisuje krok po kroku, co zrobił, wkleja treść użytych komend. Dzięki temu można łatwo zweryfikować jego wyniki, za co ma u mnie wielkiego plusa.

Pisze jednak z (uzasadnionym) założeniem, iż odbiorcy rozumieją konsolę. A we mnie, na widok ścian tekstu, odżywają wspomnienia dawnych czasów.

Próbując się wgryźć w tematy komputerowe, zerkałem na popularne fora.
Ktoś tam wklejał komendy, które miały rzekomo rozwiązać cudzy problem. Bez dodatkowego komentarza, tak jakby rozwiązanie było oczywiste.

A ja choćby nie wiedziałem, gdzie to wpisać. Nie wiedziałem, iż istnieje coś takiego jak konsola, pozwalająca „rozmawiać” bezpośrednio z komputerem. I innymi programami, które znałem tylko jako ikony do klikania.

Gdy już odkryłem konsolę, to często coś mi nie działało. Bo potrzeba jakiegoś programu. A ja nie wiem, skąd go zdobyć, nie znajduję żadnego instalatora.
Czasem po chwili szukania odkrywałem, iż cała podana komenda działa tylko na systemie Linux. A na swoim ówczesnym Windowsie musiałbym użyć jakiegoś zamiennika.

I tak dalej. Odbijałem się od tematu jak od ściany. Rzeczy proste wydawały się magią, kiedy tyle osób „cytowało konsolę” bez dodatkowego kontekstu.

Odkrycie autora Devever broni się samo. Ale uważam, iż zasługuje na jeszcze przystępniejsze omówienie, żeby więcej osób je doceniło. A zatem je tutaj zapewnię.

Wypatrujemy komend

Sam wpis z Devever jest mieszanką poleceń konsolowych, komentarzy autora oraz wyświetlonych wyników. To wszystko może się nieco zlewać, więc najpierw ustalmy sobie, jak rozumieć tekst.

  • Komendy z konsoli to linijki mające na początku znak dolara ($);
  • Linijki rozpoczynające się od krzyżyka (#) to komentarze autora;
  • Reszta tekstu to treść, jaka mu się wyświetliła.

Dolar nie jest jakimś wymysłem autora, tylko szeroko przyjętą konwencją. Wiele terminali go wyświetla na początku linijki, żeby dać nam znać, iż czekają na wpisanie polecenia.

Porada

Mam drobną prośbę do twórców stron. jeżeli chcecie na nich cytować komendy z dolarkiem, to bardzo proszę, niech będzie nie do zaznaczenia.
Dzięki temu wystarczy dwukrotnie kliknąć myszką linijkę tekstu, żeby zaznaczyć całość, gotową do skopiowania, bez dolara. Nie trzeba go usuwać z zaznaczenia, jest szybciej. Mała rzecz, a cieszy :wink:
Jeśli nasz szablon strony nie daje dostępu do arkuszy styli, to w najprostszym przypadku można po prosto robić w takich sytuacjach tabelki. Dolara w pierwszej kolumnie, a resztę komendy w drugiej.

Swoją drogą komendy konsolowe z artykułu odnoszą się do systemu Linux. To na nim mamy (często z domysłu) zainstalowane programiki, których używa autor. Sam również używałem systemu Linux Mint, tworząc ten wpis.
Ale niech użytkownicy Windowsa się nie zrażają. Na nim też da się powtórzyć większość kroków, tylko parę ostatnich wymaga więcej pracy.

Skoro już wiemy, które fragmenty tekstu to komendy, to po kolei je sobie omówmy.

Pobranie pliku

Zaczynajmy! Pierwsza komenda wpisana przez autora była taka:

wget http://www.freescale.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.0.bin

Na urządzeniach mobilnych komendy nie wyświetlają się w całości. Można odsłonić resztę, kładąc palec na czarnym polu i ruszając nim w lewo.

Ogólna zasada – w konsoli spacje rozdzielają różne elementy. Nazwa programu to element pierwszy, najbardziej po lewej. Reszta to wrzucane do niego opcje, takie jak nazwy plików do odczytania.

Nieco się to zmienia, jeżeli mamy w linijce specjalne operatory. Jeszcze o nich będzie w tym wpisie.

Użytym programem jest tu zatem wget. Odpowiada za pobieranie różnych plików z internetu.
Zaś drugi człon, po spacji, to link do konkretnej rzeczy na stronie freescale.com, gdzie są przykłady interesującego nas firmware’u.

W tym prostym przypadku użycie wgeta jest adekwatnie tym samym, co odwiedzenie strony przez przeglądarkę.
Zresztą sami możemy to sprawdzić! Gdybyśmy spróbowali wkleić ten adres w przeglądarkę, to by nas zapytało, czy chcemy pobrać plik:

Ciekawostka

Czasem wget nie otrzymuje tego, co próbuje pobrać, ponieważ jest „zbyt szczery”. Wprost załącza do swoich zapytań informację o tym, iż jest skryptem. A niektóre strony nie dopuszczają do siebie automatów.
Kiedy natomiast prośba o daną rzecz wygląda na coś pochodzącego od popularnej przeglądarki, to zostanie spełniona. Za odróżnianie automatów od ludzi odpowiada często informacja zwana user agentem.

Rozpakowywanie pliku

Kiedy już mamy plik na dysku, to znaczy iż można z nim pracować.

Ale czym on w ogóle jest? .bin to rozszerzenie pliku oznaczające binary, czyli jakiśtam blok zer i jedynek. Mało nam to mówi, a plik może być czymkolwiek.

Autor pisze w komentarzu, iż to w rzeczywistości skompresowany plik plus trochę tekstu, którym jest licencja użytkownika (EULA).

Nie mówi, w jaki sposób poznał ten fakt, ale bardzo możliwe, iż użył na pobranym pliku programu Binwalk. Nieco później to właśnie po niego sięgnął.

Skoro plik jest skompresowany, to można spróbować go rozpakować. Autor zrobił to tak:

7z x firmware-imx-8.0.bin

7z to tutaj programik 7-Zip do pracy ze skompresowanymi plikami, takimi jak ZIP czy RAR. Ale póki zna metodę kompresji, działa też na innych.

Ostatni, trzeci człon polecenia to nasz plik. A co oznacza x?
To prawdopodobnie jakaś opcja programu. A to oznacza, iż wyjaśnienie powinno być zawarte w jego instrukcji. Wpisałem w konsolę 7z --help (bardzo wiele programów ma taką opcję) i zobaczyłem tam:

x : eXtract files with full paths

Czyli cała komenda to po prostu rozpakowanie pliku!
Właściwie nie potrzeba do tego choćby 7-Zipa, bo wiele domyślnych przeglądarek plików, jak Eksplorator na Windowsie, ma wbudowaną opcję rozpakowywania archiwów.

Jednak nasz program do eksplorowania plików musi wiedzieć, iż ma traktować plik bin jak archiwum. Zatem wybieramy opcję zmiany nazwy pliku i zmieniamy końcówkę na .zip.

Źródło ikonek i opcji: system Linux Mint. Strzałka ze strony Flaticon. Przeróbki moje.

Potem mój Linux Mint się nie buntował, kiedy kliknąłem plik prawym przyciskiem myszy i wybrałem opcję Rozpakuj tutaj. Wydobył z pliku jego zawartość, również o nazwie firmware-imx-8.0.

Ponowne rozpakowanie

Po rozpakowaniu otrzymaliśmy… kolejny skompresowany plik. Trochę jak rosyjska matrioszka.
Nic dziwnego, iż kolejna komenda autora też odpowiadała za rozpakowanie. Ale tym razem programikiem tar:

tar xvf firmware-imx-8.0

xvf to zwięzła forma na podanie tarowi kilku instrukcji naraz:

  • x oznacza, iż ma rozpakować plik;
  • f PLIK mówi, jaki plik ma załadować;
  • v (verbose) oznacza, iż ma wyświetlić szczegółową listę wypakowanych plików.

Tutaj ponownie dało się użyć zwykłego eksploratora. Kliknąć plik firmware-imx-8.0 prawym przyciskiem myszy i wybrać opcję rozpakowania. Na systemie Linux Mint nie musiałem choćby zmieniać rozszerzenia na zip.

W ten sposób otrzymaliśmy najzwyklejszy folder, po którym można chodzić przez Eksploratora Plików.

Szukanie plików

Po zwykłym folderze można nie tylko chodzić; można też szukać w nim plików! I to właśnie zrobił autor swoim kolejnym poleceniem.

Po tym, co wyczytał w dokumencie firmowym, interesowały go rzeczy związane ze słowem hdmi (nazwa złącza). Poszukał go:

find firmware-imx-8.0 -type f | grep hdmi

To nieco inna komenda, bo złożona adekwatnie z dwóch niezależnych programów. Zdradza nam to obecność pionowej krechy, „rury” (ang. pipe operator) – |.
Oznacza ona po prostu tyle, iż wynik działania programiku po lewej stronie wrzucamy do tego po prawej.

Program find znajduje w podanym folderze wszystkie pliki (co sugeruje nam dopisek -type f, gdzie f to skrót od file).
Poprzez rurę ich lista trafia do grepa.
A on z kolei wyłapuje te z nich, które gdzieś w nazwie (tu: gdziekolwiek w ścieżce) mają tekst hdmi.

To samo osiągnęlibyśmy w zwykłym Eksploratorze Plików, naciskając Ctrl+F i wpisując słowo hdmi.

Byłoby to choćby nieco precyzyjniejsze. Nie pokazuje nam bowiem tych plików, które jedynie znajdują się w podfolderze hdmi, ale same nie mają tego tekstu w nazwie.

Przejście do znalezionych plików

Autor używa następnie programiku cd:

cd firmware-imx-8.0/firmware/hdmi/cadence

Jego nazwa to skrót od change directory. „Przejdź do innego folderu”. I dokładnie to robi ten program, kiedy poda mu się ścieżkę tegoż folderu.

A dlaczego autor nie musi podawać pełnej ścieżki? Tego, co na Windowsie zaczynałoby się na przykład od C://?

Bo swoją konsolę uruchomił w tym samym folderze co plik .bin. To on jest dla niego aktywnym folderem, punktem odniesienia. Wystarczy używać ścieżek względnych wobec niego.

A samą ścieżkę sobie po prostu skopiował z wyników wyszukiwania poprzednią komendą.
Na podobnej zasadzie moglibyśmy w graficznym Eksploratorze kliknąć dwukrotnie nazwę folderu hdmi, żeby do niego przejść.

Eksploracja pliku

Autora interesował jeden konkretny plik spośród wyników – signed_hdmi_imx8.bin. Kolejny blok zer i jedynek.

A skąd wiedział, iż akurat o ten plik chodzi? Jego wzrok mogło zwrócić słowo signed w nazwie, sugerujące iż jest tam coś podpisanego (podpisem cyfrowym).
Skoro szukał certyfikatów, to mógł być wyczulony na takie szczególne słowa.

Do eksploracji użył programu Binwalk. Który przemierza takie bloki zero-jedynkowe, porównuje ich ciągi do swojej listy wzorców i na tej podstawie znajduje fragmenty tekstu oraz różne zagnieżdżone pliki.

binwalk signed_hdmi_imx8m.bin

Wydaje mi się, iż w tym miejscu autor zrobił literówkę (albo coś zmienili pod pierwotnym linkiem). W moim folderze był tylko plik z literką m na końcu; zakładam, iż to o niego chodziło, bo reszta informacji się zgadza.

Binwalk odnalazł w naszym pliku tajemniczy „certyfikat w formacie DER”:

Tutaj niestety mam złą wiadomość dla użytkowników Windowsa chcących sprawdzić wyniki. Binwalk jest dość mocno przystosowany do Linuksa; do tego stopnia, iż oficjalna strona ma instrukcje instalacji działające tylko na nim.

Chętni daliby radę go zainstalować również na Windzie, ale wymagałoby to trochę zachodu. Podobnie będzie z pozostałymi dwoma krokami.
Jeśli znajdę jakiś sposób na łatwe odtworzenie tego i kolejnych kroków na Windowsie, to zaktualizuję wpis. Ale póki co pozostaje chyba uwierzyć na słowo w pokazywane tu rzeczy :wink:

Wyciągnięcie certyfikatu

Skoro autor wiedział, iż plik składa się z dwóch głównych członów, a interesował go ten drugi, to mógł wydać polecenie: „weź wszystko od miejsca, w którym zaczyna się certyfikat, aż do końca”. W ten sposób mógłby wywlec certyfikat z pliku.

Skopiował sobie zatem numer bajtu początkowego (103636 z kolumny DECIMAL z poprzednich wyników). Dodał do niego 1.

Dlaczego? Przyznam, iż jeszcze muszę doczytać; może pierwszy bajt był jakimś początkiem pliku, niezwiązanym z samym certyfikatem? W każdym razie bez tego by potem wyskoczył błąd.
Potem użył komendy:

tail -c +103637 signed_hdmi_imx8m.bin > x.bin

Programem z lewej strony jest tutaj tail. Odpowiada za czytanie plików od końca.
Mamy również kolejny specjalny operator. Strzałkę (>), czyli zapisanie wyników polecenia po jej lewej do pliku po prawej (o dowolnej podanej przez nas nazwie; jeżeli takiego nie ma, to zostanie stworzony).

Cała komenda oznacza: „weź z pliku dane od bajtu numer 103637 do końca”. Zaś strzałka dodaje od siebie: „…i zapisz to do pliku x.bin”.

Odczytanie certyfikatu

Mając certyfkat w osobnym pliku, można do niego zajrzeć. Powinna być tam informacja o tym, przez kogo został wydany. Autor użył komendy:

openssl x509 -inform der -in x.bin -text

OpenSSL to bardzo popularny, spory pakiet do pracy ze wszelkimi szyframi. Dostępny również na Windowsa.

Spójrzmy bliżej na parametry użyte w poleceniu:

  • x509 oznacza, iż z całego pakietu OpenSSL-a wybieramy konkretny program, odpowiedzialny za certyfikaty.
  • -inform der to wbrew pozorom nie informacje, ale skrót od input format.

    Ta komenda wymaga wskazania formatu z zamkniętej listy: DER, NET albo PEM. Wiemy iż u nas jest DER, bo tak powiedział wcześniej Binwalk.

  • -in PLIK wskazuje nam, jaki plik chcemy wczytać. Autor wybrał ten wcześniej wyciągnięty certyfikat.
  • -text nakazuje wyświetlić informacje w formie tekstowej.

Pod tą komendą mamy na stronie całą ścianę tekstu. Zawierającą różne informacje, w tym te mocno techniczne, dotyczące szyfrów.

Ale nas interesuje jedno konkretne pole. Issuer, czyli podmiot wystawiający certyfikat.

Werdykt

Wystawcą certyfikatu jest strona nxp.com, należąca do firmy NXP. Tej samej, która stworzyła sam procesorek i.MX 8.

Czyli obawy prawdopodobnie się potwierdziły.
Nawet gdyby ktoś przeanalizował cały ten firmware, wielki blok zer i jedynek, po czym przepisał go na coś czytelnego i przyjaźniejszego użytkownikom… To cała robota byłaby na nic.

Fizyczny sprzęt mógłby nie akceptować zmienionego firmware’u. Bo patrzyłby na cyfrowy podpis niczym doskonały grafolog. I widziałby, iż nie pasuje do wzoru producenta, który ma u siebie zakodowany.

Stąd ponury wniosek – kompletne usunięcie nieprzeniknionych elementów i „oczyszczenie” firmware’u od NXP byłoby bardzo trudne lub wręcz niemożliwe. Nie nawrócimy go na jasną stronę, możemy co najwyżej nie korzystać z funkcji HDMI.

these chips can never be fully deblobbed

A jeżeli producent kiedyś padnie, a jego certyfikat straci ważność, to wszystkie szyfrowane funkcje wygasną na zawsze.

Podsumowanie

Konsola nie jest taka zła! Choć enigmatyczne komendy mogą odstraszać, często stoją za nimi całkiem prozaiczne rzeczy. Takie, które każdy użytkownik komputera może wykonać na własną rękę. Ona po prostu przyspiesza pracę.

Powtarzając kroki autora strony Devever, mogliśmy użyć następujących programów oraz specjalnych operatorów:

wget, 7z, tar, find, grep, cd, binwalk, tail, openssl, |, >

Całkiem nieźle jak na krótką eksplorację!

Mieliśmy również wgląd w fascynujący świat inżynierii wstecznej.
To tam różne mądre głowy wyciągają z zer i jedynek szczegóły działania programów. Nieraz po to, żeby stworzyć alternatywy dla zamkniętych korposystemów – bardziej szanujące ludzi oraz ich prywatność i niezależność.

Widzimy jednak, jak bardzo utrudnia im życie szyfrowanie (rzecz, paradoksalnie, często chroniąca prywatność).
Wykorzystują je chętnie producenci, którzy chcą sobie zapewnić, iż to oni i tylko oni będą mieli kontrolę nad fundamentami współczesnej elektroniki.

Kto wygra ten wyścig zbrojeń? Czy będzie trzeba odejść od prób otwarcia cudzego kodu i zejść niżej, na poziom open hardware?
Nie wiem. Ale zawsze trzymam stronę dzielnych ruchów oporu :smile:

Idź do oryginalnego materiału