Reverse Engineering eines Heimrouters mit Hilfe von binwalk. Vertrauen Sie der Software Ihres Routers?

Reverse Engineering eines Heimrouters mit Hilfe von binwalk. Vertrauen Sie der Software Ihres Routers?

Vor ein paar Tagen beschloss ich, das Reverse Engineering der Firmware meines Routers mit binwalk durchzuführen.

Ich habe mir einen TP-Link Archer C7 Home-Router. Nicht der beste Router, aber für meine Bedürfnisse reicht er vollkommen aus.

Jedes Mal, wenn ich einen neuen Router kaufe, installiere ich OpenWRT. Warum? In der Regel kümmern sich die Hersteller nicht wirklich um die Unterstützung ihrer Router, und im Laufe der Zeit wird die Software veraltet, es entstehen Sicherheitsanfälligkeiten und so weiter, ihr versteht schon. Deshalb bevorzuge ich die gut unterstützte Open-Source-Firmware OpenWRT.

Nachdem ich OpenWRT heruntergeladen hatte, habe ich auch das letzte Firmware-Image für meinen neuen Archer C7 von der offiziellen Website heruntergeladen und beschlossen, es zu analysieren. Rein aus Spaß und um über binwalk zu berichten.

Was ist binwalk?

Binwalk ist ein Open-Source-Tool zur Analyse, Reverse Engineering und Extraktion von Firmware-Images.

Es wurde 2010 von Craig Heffner entwickelt und kann Firmware-Images scannen, Dateien finden, Dateisystem-Images identifizieren und extrahieren, ausführbaren Code, komprimierte Archive, Bootloader und Kerne, Dateiformate wie JPEG und PDF und vieles mehr.

Mit binwalk könnt ihr das Reverse Engineering der Firmware durchführen, um zu verstehen, wie sie funktioniert. Sucht nach Sicherheitsanfälligkeiten in Binärdateien, extrahiert Dateien und sucht nach Backdoors oder digitalen Zertifikaten. Man kann auch OpCodes für viele verschiedene CPUs finden.

Ihr könnt Dateisystem-Images entpacken, um nach bestimmten Passwortdateien (passwd, shadow usw.) zu suchen und versuchen, Passwort-Hashes zu knacken. Ihr könnt eine binäre Analyse zwischen zwei oder mehr Dateien durchführen. Ihr könnt eine Entropieanalyse der Daten durchführen, um komprimierte Daten oder codierte Verschlüsselungsschlüssel zu finden. All dies ohne Zugriff auf den Quellcode.

Kurz gesagt, alles, was ihr braucht, ist vorhanden 🙂

Wie funktioniert binwalk?

Das Hauptmerkmal von binwalk ist das signaturbasierte Scannen. Binwalk kann Firmware-Images scannen, um verschiedene eingebettete Dateitypen und Dateisysteme zu finden.

Kennt ihr das Kommandozeilen-Tool SETUP.EXE: MS-DOS-Executable, NE für MS Windows 3.x?

file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamisch verlinkt, Interpreter /lib64/l, für GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, strippeter

Team SETUP.EXE: MS-DOS-Executable, NE für MS Windows 3.xschaut sich den Dateihauptteil an und sucht nach einer Signatur (magische Zahl), um den Dateityp zu bestimmen. Zum Beispiel, wenn eine Datei mit der Bytefolge 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, sie weiß, dass es sich um eine PNG-Datei handelt. Auf Wikis gibt es eine Liste gängiger Dateisignaturen.

Binwalk funktioniert ähnlich. Aber anstatt nur am Anfang der Datei nach Signaturen zu suchen, scannt Binwalk die gesamte Datei. Darüber hinaus kann Binwalk auch Dateien extrahieren, die im Abbild gefunden werden.

Werkzeuge SETUP.EXE: MS-DOS-Executable, NE für MS Windows 3.x und binwalk verwenden die Bibliothek libmagic zur Identifizierung von Dateisignaturen. Aber binwalk unterstützt zusätzlich eine Liste benutzerdefinierter magischer Signaturen zur Suche nach komprimierten/archivierten Dateien, Firmware-Headern, Linux-Kerneln, Bootloadern, Dateisystemen usw.

Lass uns Spaß haben?

Installation von binwalk

Binwalk wird auf mehreren Plattformen unterstützt, einschließlich Linux, OSX, FreeBSD und Windows.

Um die neueste Version von binwalk zu installieren, können Sie den Quellcode herunterladen und Installationsanweisungen oder eine kurze Anleitung, die auf der Projektwebsite verfügbar ist.

Binwalk hat viele verschiedene Optionen:

$ binwalk

Binwalk v2.2.0
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk

Verwendung: binwalk [OPTIONEN] [DATEI1] [DATEI2] [DATEI3] ...

Signatur-Scan-Optionen:
    -B, --signature              Zieldatei(en) nach gängigen Dateisignaturen scannen
    -R, --raw=              Zieldatei(en) nach der angegebenen Bytefolge scannen
    -A, --opcodes                Zieldatei(en) nach gängigen ausführbaren Opcode-Signaturen scannen
    -m, --magic=           Eine benutzerdefinierte Magie-Datei angeben
    -b, --dumb                   Intelligente Signatur-Stichworte deaktivieren
    -I, --invalid                Ergebnisse anzeigen, die als ungültig markiert sind
    -x, --exclude=          Ergebnisse ausschließen, die mit  übereinstimmen
    -y, --include=          Nur Ergebnisse anzeigen, die mit  übereinstimmen

Extraktionsoptionen:
    -e, --extract                Bekannte Dateitypen automatisch extrahieren
    -D, --dd=      -Signaturen extrahieren, den Dateien die Erweiterung  geben und  ausführen
    -M, --matryoshka             Extrahierte Dateien rekursiv scannen
    -d, --depth=            Rekursionstiefe der Matroschka beschränken (Standard: 8 Ebenen tief)
    -C, --directory=        Dateien/Ordner in ein benutzerdefiniertes Verzeichnis extrahieren (Standard: aktuelles Arbeitsverzeichnis)
    -j, --size=             Die Größe jeder extrahierten Datei begrenzen
    -n, --count=            Anzahl der extrahierten Dateien begrenzen
    -r, --rm                     Genutzte Dateien nach der Extraktion löschen
    -z, --carve                  Daten aus Dateien extrahieren, aber Extraktionswerkzeuge nicht ausführen
    -V, --subdirs                In Unterverzeichnisse mit den entsprechenden Offsets extrahieren

Entropie-Optionen:
    -E, --entropy                Dateientropie berechnen
    -F, --fast                   Schnellere, aber weniger detaillierte Entropieanalyse verwenden
    -J, --save                   Diagramm als PNG speichern
    -Q, --nlegend                Die Legende aus dem Entropie-Diagramm weglassen
    -N, --nplot                  Kein Entropie-Diagramm erzeugen
    -H, --high=           Den Schwellenwert für den Anstieg der Entropie festlegen (Standard: 0.95)
    -L, --low=            Den Schwellenwert für den Abfall der Entropie festlegen (Standard: 0.85)

Binäre Diffing-Optionen:
    -W, --hexdump                Eine Hexdump/Diff von einer oder mehreren Dateien durchführen
    -G, --green                  Nur Zeilen anzeigen, die Bytes enthalten, die in allen Dateien gleich sind
    -i, --red                    Nur Zeilen anzeigen, die Bytes enthalten, die in allen Dateien unterschiedlich sind
    -U, --blue                   Nur Zeilen anzeigen, die Bytes enthalten, die in einigen Dateien unterschiedlich sind
    -u, --similar                Nur Zeilen anzeigen, die zwischen allen Dateien gleich sind
    -w, --terse                  Diff aller Dateien, aber nur einen Hexdump der ersten Datei anzeigen

Rohe Kompressionsoptionen:
    -X, --deflate                Nach rohen Deflate-Kompressionsströmen scannen
    -Z, --lzma                   Nach rohen LZMA-Kompressionsströmen scannen
    -P, --partial                Eine oberflächliche, aber schnellere Analyse durchführen
    -S, --stop                   Nach dem ersten Ergebnis anhalten

Allgemeine Optionen:
    -l, --length=           Anzahl der zu scannenden Bytes
    -o, --offset=           Scan an diesem Datei-Offset starten
    -O, --base=             Allen ausgegebenen Offsets eine Basisadresse hinzufügen
    -K, --block=            Dateiblöcke festlegen
    -g, --swap=             Jedes n-Byte vor dem Scannen umkehren
    -f, --log=             Ergebnisse in einer Datei protokollieren
    -c, --csv                    Ergebnisse in einer Datei im CSV-Format protokollieren
    -t, --term                   Ausgabe an das Terminalfenster anpassen
    -q, --quiet                  Ausgabe an stdout unterdrücken
    -v, --verbose                Ausführliche Ausgabe aktivieren
    -h, --help                   Hilfeausgabe anzeigen
    -a, --finclude=         Nur Dateien scannen, deren Namen mit diesem Regulären Ausdruck übereinstimmen
    -p, --fexclude=         Dateien, deren Namen mit diesem Regulären Ausdruck übereinstimmen, nicht scannen
    -s, --status=           Den Statusserver an dem angegebenen Port aktivieren

Bild-Scans

Fangen wir an, nach Dateisignaturen innerhalb des Bildes zu suchen (Bild von der Website TP-Link).

Ausführung von binwalk mit Parameter —signature:

$ binwalk --signature --term archer-c7.bin

DEZIMAL     HEXADEZIMAL     BESCHREIBUNG
------------------------------------------------------------------------------------------
21876       0x5574          U-Boot Versionszeichenkette, "U-Boot 1.1.4-g4480d5f9-dirty (Mai
                              20 2019 - 18:45:16)"
21940       0x55B4          CRC32 Polynom-Tabelle, big endian
23232       0x5AC0          uImage-Header, Header-Größe: 64 Bytes, Header-CRC:
                              0x386C2BD5, erstellt: 2019-05-20 10:45:17, Bildgröße:
                              41162 Bytes, Datenadresse: 0x80010000, Einstiegspunkt:
                              0x80010000, Daten-CRC: 0xC9CD1E38, OS: Linux, CPU: MIPS,
                              Bildtyp: Firmware-Image, Kompressionstyp: lzma, Bild
                              Name: "u-boot image"
23296       0x5B00          LZMA komprimierte Daten, Eigenschaften: 0x5D, Wörterbuchgröße:
                              8388608 Bytes, unkomprimierte Größe: 97476 Bytes
64968       0xFDC8          XML-Dokument, Version: "1.0"
78448       0x13270         uImage-Header, Header-Größe: 64 Bytes, Header-CRC:
                              0x78A267FF, erstellt: 2019-07-26 07:46:14, Bildgröße:
                              1088500 Bytes, Datenadresse: 0x80060000, Einstiegspunkt:
                              0x80060000, Daten-CRC: 0xBB9D4F94, OS: Linux, CPU: MIPS,
                              Bildtyp: Multi-File Image, Kompressionstyp: lzma,
                              Bildname: "MIPS OpenWrt Linux-3.3.8"
78520       0x132B8         LZMA komprimierte Daten, Eigenschaften: 0x6D, Wörterbuchgröße:
                              8388608 Bytes, unkomprimierte Größe: 3164228 Bytes
1167013     0x11CEA5        Squashfs-Dateisystem, little endian, Version 4.0,
                              Kompression:xz, Größe: 14388306 Bytes, 2541 Inodes,
                              Blockgröße: 65536 Bytes, erstellt: 2019-07-26 07:51:38
15555328    0xED5B00        gzip komprimierte Daten, von Unix, zuletzt geändert: 2019-07-26
                              07:51:41

Jetzt haben wir viele Informationen über dieses Bild.

Das Bild verwendet U-Boot als Bootloader (Header des Bildes an Adresse 0x5AC0 und das komprimierte Bild des Bootloaders an Adresse 0x5B00). Basierend auf dem uImage-Header an Adresse 0x13270 wissen wir, dass die Prozessorarchitektur MIPS ist und der Linux-Kernel die Version 3.3.8 ist. Und basierend auf dem Bild, das an Adresse 0x11CEA5, können wir sehen, dass rootfs ein Dateisystem ist squashfs.

Lass uns nun den Bootloader (U-Boot) mit dem Befehl entpacken dd:

$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 Datensätze eingelesen
41162+0 Datensätze ausgegeben
41162 Bytes (41 kB, 40 KiB) kopiert, 0,0939608 s, 438 kB/s

Da das Bild mit LZMA komprimiert ist, müssen wir es entpacken:

$ unlzma u-boot.bin.lzma

Jetzt haben wir das U-Boot-Bild:

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

Wie wäre es mit der Suche nach dem Standardwert für 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

U-Boot Umgebungsvariable bootargs wird zur Übertragung von Parametern an den Linux-Kernel verwendet. Und aus dem Obigen verstehen wir besser den Flash-Speicher des Geräts.

Wie wäre es mit dem Extrahieren des Kern-Images von Linux?

$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 Datensätze eingelesen
1088572+0 Datensätze geschrieben
1088572 Bytes (1,1 MB, 1,0 MiB) kopiert, 1,68628 s, 646 kB/s

Wir können überprüfen, dass das Image erfolgreich extrahiert wurde, mit dem Befehl SETUP.EXE: MS-DOS-Executable, NE für MS Windows 3.x:

$ file uImage
uImage: u-boot legacy uImage, MIPS OpenWrt Linux-3.3.8, Linux/MIPS, Multi-File Image (lzma), 1088500 Bytes, Fri Jul 26 07:46:14 2019, Ladeadresse: 0x80060000, Einstiegspunkt: 0x80060000, Header CRC: 0x78A267FF, Data CRC: 0xBB9D4F94

Das uImage-Dateiformat ist hauptsächlich ein Kernel-Image von Linux mit einem zusätzlichen Header. Lassen Sie uns diesen Header entfernen, um das endgültige Kernel-Image von Linux zu erhalten:

$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 Datensätze eingelesen
1088500+0 Datensätze geschrieben
1088500 Bytes (1,1 MB, 1,0 MiB) kopiert, 1,65603 s, 657 kB/s

Das Bild ist komprimiert, also lassen Sie uns es entpacken:

$ unlzma Image.lzma

Jetzt haben wir das Kernel-Image von Linux:

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

Was können wir mit dem Kernel-Image tun? Wir könnten beispielsweise nach Strings im Image suchen und die Version des Linux-Kernels finden und erfahren, welche Umgebung für den Kernel-Bau verwendet wurde:

$ 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 Mon May 20 18:53:02 CST 2019

Obwohl die Firmware im letzten Jahr (2019) veröffentlicht wurde, als ich diesen Artikel schreibe, verwendet sie eine alte Version des Linux-Kernels (3.3.8), die 2012 veröffentlicht wurde, und wurde mit einer sehr alten Version von GCC (4.6) ebenfalls aus dem Jahr 2012 kompiliert!
(Anmerkung des Übersetzers: Vertrauen Sie immer noch Ihren Routern im Büro und zu Hause?)

Mit der Option --opcodes können wir auch binwalk verwenden, um Maschinenanweisungen zu finden und die Prozessorarchitektur des Images zu bestimmen:

$ binwalk --opcodes Image
DEZIMAL       HEXADECIMAL     BESCHREIBUNG
--------------------------------------------------------------------------------
2400          0x960           MIPS-Anweisungen, Funktionsepilog
2572          0xA0C           MIPS-Anweisungen, Funktionsepilog
2828          0xB0C           MIPS-Anweisungen, Funktionsepilog

Wie steht es um das Root-Dateisystem? Anstatt das Image manuell zu extrahieren, lassen Sie uns die Option binwalk --extract:

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

Das vollständige Root-Dateisystem wird in ein Unterverzeichnis extrahiert:

$ 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
 ---------------------------------------------------------------
   Für die, die bereit sind zu rocken... (%C, %R)
 ---------------------------------------------------------------

Jetzt können wir viele verschiedene Dinge tun.

Wir können nach Konfigurationsdateien, Passwort-Hashes, kryptografischen Schlüsseln und digitalen Zertifikaten suchen. Wir können Binärdateien analysieren, um Fehler zu finden und Schwachstellen.

Mit Hilfe von qemu und chroot Wir können sogar eine ausführbare Datei aus dem Image starten (emulieren):

$ 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) Multi-Call-Binär.
Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko
und andere. Lizenziert unter GPLv2.
Siehe Quellenverteilung für vollständige Hinweise.

Verwendung: busybox [funktion] [argumente]...
   oder: busybox --list[-full]
   oder: funktion [argumente]...

    BusyBox ist eine Multi-Call-Binärdatei, die viele gängige Unix-
    Dienstprogramme in einer einzigen ausführbaren Datei kombiniert.  Die meisten Benutzer erstellen einen
    Link zu busybox für jede Funktion, die sie verwenden möchten, und BusyBox
    verhält sich wie das, was auch immer aufgerufen wurde.

Derzeit definierte Funktionen:
    [, [[, 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

Super! Aber beachte, dass die Version von BusyBox - 1.19.4. Das ist eine sehr alte Version von BusyBox, die im April 2012 veröffentlicht wurde.

Somit veröffentlicht TP-Link 2019 ein Firmware-Image unter Verwendung von Software (GCC-Toolchain, Kernel, BusyBox usw.) aus dem Jahr 2012!

Jetzt verstehst du, warum ich immer OpenWRT auf meinen Routern installiere?

Das ist noch nicht alles

Binwalk kann auch eine Entropie-Analyse durchführen, rohe Entropiedaten drucken und Entropiegrafiken generieren. Große Entropie wird normalerweise beobachtet, wenn die Bytes im Image zufällig sind. Das könnte bedeuten, dass das Image eine verschlüsselte, komprimierte oder obfuskierte Datei enthält. Hartcodierter Verschlüsselungsschlüssel? Warum nicht.

Reverse Engineering eines Heimrouters mit Hilfe von binwalk. Vertrauen Sie der Software Ihres Routers?

Wir können auch den Parameter --raw verwenden, um nach einer benutzerdefinierten Sequenz roher Bytes im Image zu suchen, oder den Parameter --hexdump verwenden, um einen hexadezimalen Dump durchzuführen, der zwei oder mehr Eingabedateien vergleicht.

Benutzerdefinierte Signaturen können entweder über eine benutzerdefinierte Signaturdatei hinzugefügt werden, die in der Befehlszeile mit dem Parameter --magic, oder indem sie in das Verzeichnis $HOME/.config/binwalk/magic.

eingefügt werden. Weitere Informationen zu binwalk finden Sie in der offiziellen Dokumentation.

Binwalk-Erweiterung.

Es gibt API-Schnittstelle von binwalk, die als Python-Modul implementiert ist und von jedem Python-Skript verwendet werden kann, um die binwalk-Scans programmgesteuert durchzuführen. Das binwalk-Befehlszeilenwerkzeug kann fast vollständig mit nur zwei Zeilen Python-Code dupliziert werden!

import binwalk
binwalk.scan()

Mit der Python-API können Sie auch Python-Plugins erstellen, um binwalk anzupassen und zu erweitern.

Es gibt auch ein IDA-Plugin und eine Cloud-Version von Binwalk Pro..

Warum laden Sie also nicht ein Firmware-Image aus dem Internet herunter und probieren binwalk aus? Ich verspreche, Sie werden viel Spaß haben 🙂

Quelle: habr.com

60GB SSD 8Gb DDR4