
Kilka dni temu postanowiłem przeprowadzić inżynierię wsteczną oprogramowania układowego mojego routera, używając binwalk.
Kupiłem sobie . To nie jest najlepszy router, ale w zupełności wystarcza do moich potrzeb.
Za każdym razem, gdy kupuję nowy router, instaluję . Dlaczego? Zazwyczaj producenci nie dbają o wsparcie swoich routerów, a z czasem oprogramowanie staje się przestarzałe, pojawiają się luki w zabezpieczeniach i tak dalej, rozumiesz. Dlatego wolę dobrze wspieraną przez społeczność, otwartoźródłową wersję oprogramowania OpenWRT.
Pobierając OpenWRT, ściągnąłem również dla mojego nowego Archer C7 z oficjalnej strony i postanowiłem go przeanalizować. Czysto dla zabawy i aby opowiedzieć o binwalk.
Czym jest binwalk?
to narzędzie z otwartym kodem źródłowym do analizy, inżynierii wstecznej i wydobywania obrazów oprogramowania układowego.
Stworzone w 2010 roku przez Craiga Heffnera, binwalk potrafi skanować obrazy oprogramowania układowego i znajdować pliki, identyfikować i wydobywać obrazy systemów plików, kod wykonywalny, skompresowane archiwa, bootloadery i jądra, formaty plików takie jak JPEG i PDF oraz wiele innych.
Możesz używać binwalk do inżynierii wstecznej oprogramowania układowego, aby zrozumieć, jak ono działa. Szukać w plikach binarnych luk w zabezpieczeniach, wydobywać pliki oraz szukać backdoorów lub cyfrowych certyfikatów. Można również znaleźć opcodes dla wielu różnych procesorów.
Możesz rozpakować obrazy systemów plików, aby szukać określonych plików haseł (passwd, shadow itd.) i spróbować złamać hashe haseł. Możesz przeprowadzić analizę binarną między dwoma lub więcej plikami. Możesz wykonać analizę entropii danych, aby znaleźć skompresowane dane lub zakodowane klucze szyfrowania. To wszystko bez dostępu do kodu źródłowego.
W skrócie, wszystko, co potrzebne, jest 🙂
Jak działa binwalk?
Podstawową cechą binwalk jest jego skanowanie sygnatur.
Binwalk może skanować obraz oprogramowania układowego w poszukiwaniu różnych wbudowanych typów plików i systemów plików. plik?
znasz narzędzie wiersza poleceńZespół plikfile /bin/bash /bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, stripped patrzy na nagłówek pliku i szuka sygnatury (magicznej liczby), aby określić typ pliku. Na przykład, jeśli plik zaczyna się od sekwencji bajtów, ona wie, że to jest plik PNG. Na jest lista powszechnych podpisów plików.
Binwalk działa podobnie. Ale zamiast szukać podpisów tylko na początku pliku, binwalk przeszuka cały plik. Dodatkowo, binwalk może wyodrębnić pliki znalezione w obrazie.
Narzędzia plik i binwalk używa biblioteki libmagic do identyfikacji podpisów plików. Ale binwalk dodatkowo obsługuje listę niestandardowych magicznych podpisów do wyszukiwania skompresowanych / spakowanych plików, nagłówków firmware, jąder Linux, bootloaderów, systemów plików i tak dalej.
Chcesz się pobawić?
Instalacja binwalk
Binwalk jest wspierany na kilku platformach, w tym Linux, OSX, FreeBSD i Windows.
Aby zainstalować najnowszą wersję binwalk, możesz i postępować zgodnie z lub , dostępnym na stronie projektu.
Binwalk ma wiele różnych opcji:
$ binwalk
Binwalk v2.2.0
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
Użycie: binwalk [OPTIONS] [FILE1] [FILE2] [FILE3] ...
Opcje skanowania sygnatur:
-B, --signature Skanuj docelowy plik(i) w poszukiwaniu powszechnych sygnatur plików
-R, --raw= Skanuj docelowy plik(i) w poszukiwaniu określonej sekwencji bajtów
-A, --opcodes Skanuj docelowy plik(i) w poszukiwaniu powszechnych sygnatur kodów operacyjnych
-m, --magic= Określij niestandardowy plik magiczny do użycia
-b, --dumb Wyłącz smart sygnatury słów kluczowych
-I, --invalid Pokaż wyniki oznaczone jako nieważne
-x, --exclude= Wyklucz wyniki, które pasują do
-y, --include= Pokaż tylko wyniki, które pasują do
Opcje ekstrakcji:
-e, --extract Automatycznie ekstraktuj znane typy plików
-D, --dd= Ekstraktuj sygnatury , nadaj plikom rozszerzenie , i wykonaj
-M, --matryoshka Rekursywnie skanuj wyodrębnione pliki
-d, --depth= Ogranicz głębokość rekursji matryoshki (domyślnie: 8 poziomów)
-C, --directory= Ekstraktuj pliki/foldery do niestandardowego katalogu (domyślnie: bieżący katalog roboczy)
-j, --size= Ogranicz rozmiar każdego wyodrębnionego pliku
-n, --count= Ogranicz liczbę wyodrębnionych plików
-r, --rm Usuń skopiowane pliki po ekstrakcji
-z, --carve Wydobądź dane z plików, ale nie wykonuj narzędzi ekstrakcji
-V, --subdirs Ekstraktuj do podkatalogów nazwanych na podstawie offsetu
Opcje entropii:
-E, --entropy Oblicz entropię pliku
-F, --fast Użyj szybszej, ale mniej szczegółowej analizy entropii
-J, --save Zapisz wykres jako PNG
-Q, --nlegend Pomijaj legendę z wykresu entropii
-N, --nplot Nie generuj wykresu entropii
-H, --high= Ustaw próg wyzwalacza entropii do wzrostu (domyślnie: 0.95)
-L, --low= Ustaw próg wyzwalacza entropii do spadku (domyślnie: 0.85)
Opcje różnicowania binarnego:
-W, --hexdump Wykonaj hexdump / różnice pliku lub plików
-G, --green Pokaż tylko linie zawierające bajty, które są takie same we wszystkich plikach
-i, --red Pokaż tylko linie zawierające bajty, które różnią się we wszystkich plikach
-U, --blue Pokaż tylko linie zawierające bajty, które różnią się w niektórych plikach
-u, --similar Pokaż tylko linie, które są takie same między wszystkimi plikami
-w, --terse Różnicuj wszystkie pliki, ale wyświetlaj tylko hexdump pierwszego pliku
Opcje kompresji raw:
-X, --deflate Skanuj w poszukiwaniu surowych strumieni kompresji deflate
-Z, --lzma Skanuj w poszukiwaniu surowych strumieni kompresji LZMA
-P, --partial Wykonaj powierzchowny, ale szybszy skan
-S, --stop Zatrzymaj się po pierwszym wyniku
Opcje ogólne:
-l, --length= Liczba bajtów do skanowania
-o, --offset= Rozpocznij skanowanie od tego offsetu pliku
-O, --base= Dodaj adres podstawowy do wszystkich wydrukowanych offsetów
-K, --block= Ustaw rozmiar bloku pliku
-g, --swap= Odwróć co n bajtów przed skanowaniem
-f, --log= Zapisuj wyniki do pliku
-c, --csv Zapisuj wyniki do pliku w formacie CSV
-t, --term Formatuj wyjście aby pasowało do okna terminala
-q, --quiet Tłumacz wyjście na stdout
-v, --verbose Włącz szczegółowe wyjście
-h, --help Pokaż pomoc
-a, --finclude= Skanuj tylko pliki, których nazwy pasują do tego wyrażenia regularnego
-p, --fexclude= Nie skanuj plików, których nazwy pasują do tego wyrażenia regularnego
-s, --status= Włącz serwer statusu na określonym porcieSkanowanie obrazów
Zacznijmy od wyszukiwania sygnatur plików wewnątrz obrazu (obraz z witryny ).
Uruchomienie binwalk z parametrem —signature:
$ binwalk --signature --term archer-c7.bin
DECIMAL HEXADECIMAL OPIS
------------------------------------------------------------------------------------------
21876 0x5574 Ciąg wersji U-Boot, "U-Boot 1.1.4-g4480d5f9-dirty (Maj
20 2019 - 18:45:16)"
21940 0x55B4 Tablica wielomianów CRC32, big endian
23232 0x5AC0 Nagłówek uImage, rozmiar nagłówka: 64 bajty, CRC nagłówka:
0x386C2BD5, utworzono: 2019-05-20 10:45:17, rozmiar obrazu:
41162 bajty, Adres danych: 0x80010000, Punkt wejścia:
0x80010000, CRC danych: 0xC9CD1E38, OS: Linux, CPU: MIPS,
typ obrazu: Firmware Image, typ kompresji: lzma, nazwa obrazu:
"obraz u-boot"
23296 0x5B00 Dane skompresowane LZMA, parametry: 0x5D, rozmiar słownika:
8388608 bajtów, rozmiar po dekompresji: 97476 bajtów
64968 0xFDC8 Dokument XML, wersja: "1.0"
78448 0x13270 Nagłówek uImage, rozmiar nagłówka: 64 bajty, CRC nagłówka:
0x78A267FF, utworzono: 2019-07-26 07:46:14, rozmiar obrazu:
1088500 bajtów, Adres danych: 0x80060000, Punkt wejścia:
0x80060000, CRC danych: 0xBB9D4F94, OS: Linux, CPU: MIPS,
typ obrazu: Multi-File Image, typ kompresji: lzma,
nazwa obrazu: "MIPS OpenWrt Linux-3.3.8"
78520 0x132B8 Dane skompresowane LZMA, parametry: 0x6D, rozmiar słownika:
8388608 bajtów, rozmiar po dekompresji: 3164228 bajtów
1167013 0x11CEA5 System plików Squashfs, little endian, wersja 4.0,
kompresja:xz, rozmiar: 14388306 bajtów, 2541 inode,
rozmiar bloku: 65536 bajtów, utworzono: 2019-07-26 07:51:38
15555328 0xED5B00 Dane skompresowane gzip, z Unix, ostatnia modyfikacja: 2019-07-26
07:51:41Teraz mamy dużo informacji o tym obrazie.
Obraz wykorzystuje jako bootloader (nagłówek obrazu pod adresem 0x5AC0 i skompresowany obraz bootloadera pod adresem 0x5B00). Na podstawie nagłówka uImage pod adresem 0x13270, wiemy, że architektura procesora to MIPS, a jądro Linux to wersja 3.3.8. A na podstawie obrazu, znalezionego pod adresem 0x11CEA5, możemy zobaczyć, że rootfs jest systemem plików squashfs.
Teraz rozpakujmy bootloader (U-Boot) za pomocą polecenia dd:
$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 rekordów w
41162+0 rekordów out
41162 bajtów (41 kB, 40 KiB) skopiowanych, 0,0939608 s, 438 kB/sPonieważ obraz jest skompresowany za pomocą LZMA, musimy go rozpakować:
$ unlzma u-boot.bin.lzmaTeraz mamy obraz U-Boot:
$ ls -l u-boot.bin
-rw-rw-r-- 1 sprado sprado 97476 Lut 5 08:48 u-boot.binJak wygląda poszukiwanie wartości domyślnej dla bootargs?
$ strings u-boot.bin | grep bootargs
bootargs
bootargs=console=ttyS0,115200 board=AP152 rootfstype=squashfs init=/etc/preinit mtdparts=spi0.0:128k(factory-uboot),192k(u-boot),64k(ART),1536k(uImage),14464k@0x1e0000(rootfs) mem=128MZmienne środowiskowe U-Boot bootargs jest używane do przekazywania parametrów do jądra Linux. Z powyższego lepiej rozumiemy pamięć flash urządzenia.
Co powiesz na wyodrębnienie obrazu jądra Linux?
$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 rekordów w
1088572+0 rekordów out
1088572 bajtów (1,1 MB, 1,0 MiB) skopiowano, 1,68628 s, 646 kB/sMożemy sprawdzić, czy obraz został pomyślnie wyodrębniony za pomocą polecenia plik:
$ file uImage
uImage: u-boot legacy uImage, MIPS OpenWrt Linux-3.3.8, Linux/MIPS, Multi-File Image (lzma), 1088500 bajtów, Pią 26 Lip 07:46:14 2019, Adres załadunku: 0x80060000, Punkt wejścia: 0x80060000, CRC nagłówka: 0x78A267FF, CRC danych: 0xBB9D4F94Format pliku uImage to głównie obraz jądra Linux z dodatkowymi nagłówkami. Usuńmy ten nagłówek, aby uzyskać finalny obraz jądra Linux:
$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 rekordów w
1088500+0 rekordów out
1088500 bajtów (1,1 MB, 1,0 MiB) skopiowano, 1,65603 s, 657 kB/sObraz jest skompresowany, więc rozpakujmy go:
$ unlzma Image.lzmaTeraz mamy obraz jądra Linux:
$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Lut 5 10:51 ImageCo możemy zrobić z obrazem jądra? Możemy na przykład przeszukać ciągi w obrazie i znaleźć wersję jądra Linux oraz poznać środowisko używane do kompilacji jądra:
$ strings Image | grep "Linux version"
Linux version 3.3.8 (leo@leo-MS-7529) (gcc version 4.6.3 20120201 (prerelease) (Linaro GCC 4.6-2012.02) ) #1 Pon Maj 20 18:53:02 CST 2019Mimo że oprogramowanie układowe zostało wydane w zeszłym roku (2019), gdy piszę ten artykuł, używa starej wersji jądra Linux (3.3.8), wydanej w 2012 roku, skompilowanej z bardzo starym GCC (4.6) również z 2012 roku!
(przyp. red. czy nadal ufacie swoim routerom w biurze i w domu?)
Z opcją --opcodes możemy również użyć binwalk do wykrywania instrukcji maszynowych i określenia architektury procesora obrazu:
$ binwalk --opcodes Image
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
2400 0x960 Instrukcje MIPS, epilog funkcji
2572 0xA0C Instrukcje MIPS, epilog funkcji
2828 0xB0C Instrukcje MIPS, epilog funkcjiCo z systemem plików root? Zamiast wyodrębniać obraz ręcznie, skorzystajmy z opcji binwalk --extract:
$ binwalk --extract --quiet archer-c7.binPełny system plików root zostanie wyodrębniony do podkatalogu:
$ cd _archer-c7.bin.extracted/squashfs-root/
$ ls
bin dev etc lib mnt overlay proc rom root sbin sys tmp usr var www
$ cat etc/banner
MM NM MMMMMMM M M
$MMMMM MMMMM MMMMMMMMMMM MMM MMM
MMMMMMMM MM MMMMM. MMMMM:MMMMMM: MMMM MMMMM
MMMM= MMMMMM MMM MMMM MMMMM MMMM MMMMMM MMMM MMMMM'
MMMM= MMMMM MMMM MM MMMMM MMMM MMMM MMMMNMMMMM
MMMM= MMMM MMMMM MMMMM MMMM MMMM MMMMMMMM
MMMM= MMMM MMMMMM MMMMM MMMM MMMM MMMMMMMMM
MMMM= MMMM MMMMM, NMMMMMMMM MMMM MMMM MMMMMMMMMMM
MMMM= MMMM MMMMMM MMMMMMMM MMMM MMMM MMMM MMMMMM
MMMM= MMMM MM MMMM MMMM MMMM MMMM MMMM MMMM
MMMM$ ,MMMMM MMMMM MMMM MMM MMMM MMMMM MMMM MMMM
MMMMMMM: MMMMMMM M MMMMMMMMMMMM MMMMMMM MMMMMMM
MMMMMM MMMMN M MMMMMMMMM MMMM MMMM
MMMM M MMMMMMM M M
M
---------------------------------------------------------------
For those about to rock... (%C, %R)
---------------------------------------------------------------Teraz możemy zrobić wiele rzeczy.
Możemy wyszukiwać pliki konfiguracyjne, hashe haseł, klucze kryptograficzne i certyfikaty cyfrowe. Możemy zanalizować pliki binarne w celu i luk bezpieczeństwa.
Dzięki i możemy nawet uruchomić (emulować) plik wykonywalny z obrazu:
$ ls
bin dev etc lib mnt overlay proc rom root sbin sys tmp usr var www
$ cp /usr/bin/qemu-mips-static .
$ sudo chroot . ./qemu-mips-static bin/busybox
BusyBox v1.19.4 (2019-05-20 18:13:49 CST) wielofunkcyjny plik binarny.
Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko
i inni. Licencjonowane na GPLv2.
Zobacz dystrybucję źródłową, aby uzyskać pełną informację.
Użycie: busybox [funkcja] [argumenty]...
lub: busybox --list[-full]
lub: funkcja [argumenty]...
BusyBox to plik binarny wielofunkcyjny, który łączy wiele popularnych Unixowych
narzędzi w pojedynczym pliku wykonywalnym. Większość ludzi tworzy
link do busybox dla każdej funkcji, którą chcą używać, a BusyBox
działa tak, jak zostało wywołane.
Obecnie zdefiniowane funkcje:
[, [[, addgroup, adduser, arping, ash, awk, basename, cat, chgrp, chmod, chown, chroot, clear, cmp, cp, crond, crontab, cut, date, dd, delgroup, deluser, dirname, dmesg, echo, egrep, env, expr, false,
fgrep, find, free, fsync, grep, gunzip, gzip, halt, head, hexdump, hostid, id, ifconfig, init, insmod, kill, killall, klogd, ln, lock, logger, ls, lsmod, mac_addr, md5sum, mkdir, mkfifo, mknod, mktemp,
mount, mv, nice, passwd, pgrep, pidof, ping, ping6, pivot_root, poweroff, printf, ps, pwd, readlink, reboot, reset, rm, rmdir, rmmod, route, sed, seq, sh, sleep, sort, start-stop-daemon, strings,
switch_root, sync, sysctl, tail, tar, tee, telnet, test, tftp, time, top, touch, tr, traceroute, true, udhcpc, umount, uname, uniq, uptime, vconfig, vi, watchdog, wc, wget, which, xargs, yes, zcatŚwietnie! Ale zwróć uwagę, że wersja BusyBox to 1.19.4. To bardzo stara wersja BusyBox, wydana w kwietniu 2012 roku.
Tak więc TP-Link wydaje obraz oprogramowania w 2019 roku, korzystając z oprogramowania (GCC toolchain, kernel, BusyBox itd.) z 2012 roku!
Teraz rozumiesz, dlaczego zawsze instaluję OpenWRT na swoich routerach?
To jeszcze nie wszystko
Binwalk może również przeprowadzać analizę entropii, wyświetlać surowe dane entropijne oraz generować wykresy entropii. Zwykle wysoka entropia występuje, gdy bajty w obrazie są losowe. Może to oznaczać, że obraz zawiera zaszyfrowany, skompresowany lub obfuscowany plik. Twardo wdrożony klucz szyfrowania? Czemu nie.

Możemy również użyć parametru --raw do wyszukiwania niestandardowej sekwencji surowych bajtów w obrazie lub parametru --hexdump aby wykonać dump szesnastkowy, porównujący dwa lub więcej plików wejściowych.
mogą być dodane do binwalk albo za pomocą pliku niestandardowych sygnatur, wskazanego w wierszu poleceń za pomocą parametru --magic, albo przez dodanie ich do katalogu $HOME/.config/binwalk/magic.
Więcej informacji na temat binwalk znajdziesz w .
Rozszerzeniu binwalk
Jest binwalk, wdrożonym jako moduł Pythona, który może być używany przez każdy skrypt Pythona do programowego wykonywania skanowania binwalk, a narzędzie wiersza poleceń binwalk można prawie całkowicie powielić za pomocą zaledwie dwóch linijek kodu Pythona!
import binwalk
binwalk.scan()Dzięki API Pythona możesz również tworzyć do dostosowywania i rozszerzania binwalk.
Istnieje również oraz wersja chmurowa .
Więc dlaczego nie pobrać obrazu oprogramowania układowego z Internetu i nie wypróbować binwalk? Obiecuję, że będziesz się świetnie bawić 🙂
Źródło: habr.com
