Reverse engineering domowego routera za pomocą binwalk. Czy ufasz oprogramowaniu swojego routera?

Reverse engineering domowego routera za pomocą binwalk. Czy ufasz oprogramowaniu swojego routera?

Kilka dni temu postanowiłem przeprowadzić inżynierię wsteczną oprogramowania układowego mojego routera, używając binwalk.

Kupiłem sobie router domowy TP-Link Archer C7. To nie jest najlepszy router, ale w zupełności wystarcza do moich potrzeb.

Za każdym razem, gdy kupuję nowy router, instaluję OpenWRT. 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ż najnowszy obraz oprogramowania dla mojego nowego Archer C7 z oficjalnej strony i postanowiłem go przeanalizować. Czysto dla zabawy i aby opowiedzieć o binwalk.

Czym jest binwalk?

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 Wikipedii 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 pobierz kod źródłowy i postępować zgodnie z instrukcją instalacji lub krótkim przewodnikiem, 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 porcie

Skanowanie obrazów

Zacznijmy od wyszukiwania sygnatur plików wewnątrz obrazu (obraz z witryny TP-Link).

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:41

Teraz mamy dużo informacji o tym obrazie.

Obraz wykorzystuje U-Boot 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/s

Ponieważ obraz jest skompresowany za pomocą LZMA, musimy go rozpakować:

$ unlzma u-boot.bin.lzma

Teraz mamy obraz U-Boot:

$ ls -l u-boot.bin
-rw-rw-r-- 1 sprado sprado 97476 Lut  5 08:48 u-boot.bin

Jak 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=128M

Zmienne ś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/s

Moż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: 0xBB9D4F94

Format 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/s

Obraz jest skompresowany, więc rozpakujmy go:

$ unlzma Image.lzma

Teraz mamy obraz jądra Linux:

$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Lut  5 10:51 Image

Co 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 2019

Mimo ż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 funkcji

Co z systemem plików root? Zamiast wyodrębniać obraz ręcznie, skorzystajmy z opcji binwalk --extract:

$ binwalk --extract --quiet archer-c7.bin

Peł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 szukania błędów i luk bezpieczeństwa.

Dzięki qemu i chroot 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.

Reverse engineering domowego routera za pomocą binwalk. Czy ufasz oprogramowaniu swojego routera?

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.

Niestandardowe sygnatury 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 oficjalnej dokumentacji.

Rozszerzeniu binwalk

Jest Interfejsie API 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ć wtyczki w Pythonie do dostosowywania i rozszerzania binwalk.

Istnieje również wtyczka IDA oraz wersja chmurowa Binwalk Pro.

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

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster