
Qualche giorno fa, ho deciso di eseguire il reverse engineering del firmware del mio router usando binwalk.
Ho comprato per me . Non è il miglior router, ma per le mie esigenze è più che sufficiente.
Ogni volta che acquisto un nuovo router, installo . Perché? Di solito i produttori non si prendono molto cura del supporto per i propri router e nel tempo il software diventa obsoleto, sorgono vulnerabilità e così via, insomma, avete capito. Pertanto, preferisco un firmware open-source ben supportato dalla comunità come OpenWRT.
Scaricando OpenWRT, ho anche per il mio nuovo Archer C7 dal sito ufficiale e ho deciso di analizzarlo. Giusto per divertimento e per parlare di binwalk.
Cos'è binwalk?
è uno strumento open source per analizzare, fare reverse engineering e estrarre immagini di firmware.
Creato nel 2010 da Craig Heffner, binwalk può scansionare le immagini di firmware e trovare file, identificare e estrarre immagini di file system, codice eseguibile, archivi compressi, bootloader e kernel, formati di file come JPEG e PDF, e molto altro.
Puoi usare binwalk per fare reverse engineering del firmware per capire come è strutturato. Cercare vulnerabilità nei file binari, estrarre file e cercare backdoor o certificati digitali. Puoi anche trovare opcodes per una miriade di CPU diverse.
Puoi estrarre immagini di file system per cercare file specifici di password (passwd, shadow, ecc.) e cercare di rompere gli hash delle password. Puoi eseguire un'analisi binaria tra due o più file. Puoi eseguire un'analisi di entropia dei dati per cercare dati compressi o chiavi di crittografia codificate. Tutto questo senza necessità di accesso al codice sorgente.
Insomma, c'è tutto ciò che serve 🙂
Come funziona binwalk?
La caratteristica principale di binwalk è la sua scansione basata su firme. Binwalk può scansionare un'immagine di firmware per cercare vari tipi di file e file system incorporati.
Conosci l'utilità da riga di comando file?
file /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, strippedTeam fileguarda l'intestazione del file e cerca una firma (numero magico) per determinare il tipo di file. Ad esempio, se il file inizia con una sequenza di byte 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, sa sa che si tratta di un file PNG. Su c'è un elenco delle firme di file più comuni.
Binwalk funziona allo stesso modo. Ma invece di cercare le firme solo all'inizio del file, binwalk scannerà l'intero file. Inoltre, binwalk può estrarre file trovati nell'immagine.
Strumenti file e binwalk usa la libreria libmagic per identificare le firme dei file. Ma binwalk supporta anche un elenco di firme magiche personalizzate per cercare file compressi / archiviati, intestazioni di firmware, kernel Linux, bootloader, file system e così via.
Divertiamoci?
Installazione di binwalk
Binwalk è supportato su diverse piattaforme, tra cui Linux, OSX, FreeBSD e Windows.
Per installare l'ultima versione di binwalk, puoi e seguire o , disponibile sul sito del progetto.
Binwalk ha molte opzioni differenti:
$ binwalk
Binwalk v2.2.0
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
Uso: binwalk [OPZIONI] [FILE1] [FILE2] [FILE3] ...
Opzioni di scansione delle firme:
-B, --signature Scansiona il file di destinazione per firme di file comuni
-R, --raw= Scansiona il file di destinazione per la sequenza di byte specificata
-A, --opcodes Scansiona il file di destinazione per firme di opcode eseguibili comuni
-m, --magic= Specifica un file magico personalizzato da utilizzare
-b, --dumb Disabilita le parole chiave delle firme intelligenti
-I, --invalid Mostra risultati contrassegnati come non validi
-x, --exclude= Esclude risultati che corrispondono a
-y, --include= Mostra solo i risultati che corrispondono a
Opzioni di estrazione:
-e, --extract Estrae automaticamente tipi di file noti
-D, --dd= Estrae firme di , assegna ai file un'estensione di ed esegue
-M, --matryoshka Scansiona ricorsivamente i file estratti
-d, --depth= Limita la profondità di ricorsione matryoshka (default: 8 livelli)
-C, --directory= Estrae file/cartelle in una directory personalizzata (default: directory di lavoro corrente)
-j, --size= Limita la dimensione di ciascun file estratto
-n, --count= Limita il numero di file estratti
-r, --rm Elimina i file ritagliati dopo l'estrazione
-z, --carve Estrae dati dai file, ma non esegue le utilità di estrazione
-V, --subdirs Estrae in sottodirectory denominate in base all'offset
Opzioni di entropia:
-E, --entropy Calcola l'entropia del file
-F, --fast Usa un'analisi dell'entropia più rapida, ma meno dettagliata
-J, --save Salva il grafico come PNG
-Q, --nlegend Om Ramme la legenda dal grafico dell'entropia
-N, --nplot Non genera un grafico dell'entropia
-H, --high= Imposta la soglia di attivazione dell'entropia dell'edge ascendente (default: 0.95)
-L, --low= Imposta la soglia di attivazione dell'entropia dell'edge discendente (default: 0.85)
Opzioni di differenza binaria:
-W, --hexdump Esegue un hexdump / differenza di uno o più file
-G, --green Mostra solo le righe contenenti byte che sono gli stessi tra tutti i file
-i, --red Mostra solo le righe contenenti byte che sono differenti tra tutti i file
-U, --blue Mostra solo le righe contenenti byte che sono differenti tra alcuni file
-u, --similar Mostra solo le righe che sono uguali tra tutti i file
-w, --terse Differenza di tutti i file, ma mostra solo un hexdump del primo file
Opzioni di compressione raw:
-X, --deflate Scansiona per flussi di compressione raw deflate
-Z, --lzma Scansiona per flussi di compressione raw LZMA
-P, --partial Esegue una scansione superficiale, ma più veloce
-S, --stop Si ferma dopo il primo risultato
Opzioni generali:
-l, --length= Numero di byte da scansionare
-o, --offset= Inizia la scansione a questo offset del file
-O, --base= Aggiunge un'indirizzo di base a tutti gli offset stampati
-K, --block= Imposta la dimensione del blocco del file
-g, --swap= Riserva ogni n byte prima della scansione
-f, --log= Registra i risultati su un file
-c, --csv Registra i risultati su un file in formato CSV
-t, --term Format output to fit the terminal window
-q, --quiet Sopprime l'output su stdout
-v, --verbose Abilita output dettagliato
-h, --help Mostra output di aiuto
-a, --finclude= Scansiona solo file i cui nomi corrispondono a questa regex
-p, --fexclude= Non scansionare file i cui nomi corrispondono a questa regex
-s, --status= Abilita il server di stato sulla porta specificataScansione delle immagini
Iniziamo con la ricerca delle firme dei file all'interno dell'immagine (immagine dal sito ).
Avviando binwalk con l'opzione —signature:
$ binwalk --signature --term archer-c7.bin
DECIMALI ESADECIMALE DESCRIZIONE
------------------------------------------------------------------------------------------
21876 0x5574 Stringa di versione U-Boot, "U-Boot 1.1.4-g4480d5f9-dirty (May
20 2019 - 18:45:16)"
21940 0x55B4 Tabella polinomiale CRC32, big endian
23232 0x5AC0 intestazione uImage, dimensione intestazione: 64 byte, CRC intestazione:
0x386C2BD5, creata: 2019-05-20 10:45:17, dimensione immagine:
41162 byte, Indirizzo dati: 0x80010000, Punto d'ingresso:
0x80010000, CRC dati: 0xC9CD1E38, OS: Linux, CPU: MIPS,
tipo immagine: Firmware Image, tipo compressione: lzma, nome immagine:
"immagine u-boot"
23296 0x5B00 Dati compressi LZMA, proprietà: 0x5D, dimensione dizionario:
8388608 byte, dimensione non compressa: 97476 byte
64968 0xFDC8 Documento XML, versione: "1.0"
78448 0x13270 intestazione uImage, dimensione intestazione: 64 byte, CRC intestazione:
0x78A267FF, creata: 2019-07-26 07:46:14, dimensione immagine:
1088500 byte, Indirizzo dati: 0x80060000, Punto d'ingresso:
0x80060000, CRC dati: 0xBB9D4F94, OS: Linux, CPU: MIPS,
tipo immagine: Multi-File Image, tipo compressione: lzma,
nome immagine: "MIPS OpenWrt Linux-3.3.8"
78520 0x132B8 Dati compressi LZMA, proprietà: 0x6D, dimensione dizionario:
8388608 byte, dimensione non compressa: 3164228 byte
1167013 0x11CEA5 filesystem Squashfs, little endian, versione 4.0,
compressione:xz, dimensione: 14388306 byte, 2541 inode,
dimensione blocco: 65536 byte, creata: 2019-07-26 07:51:38
15555328 0xED5B00 dati compressi gzip, da Unix, ultima modifica: 2019-07-26
07:51:41Ora abbiamo molte informazioni su questa immagine.
L'immagine utilizza come bootloader (intestazione dell'immagine all'indirizzo 0x5AC0 e immagine compressa del bootloader all'indirizzo 0x5B00). Basandoci sull'intestazione uImage all'indirizzo 0x13270, sappiamo che l'architettura della CPU è MIPS e che il kernel Linux è versione 3.3.8. E sulla base dell'immagine trovata all'indirizzo 0x11CEA5, possiamo vedere che rootfs è un filesystem squashfs.
Ora estraiamo il bootloader (U-Boot) usando il comando dd:
$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 record in
41162+0 record out
41162 byte (41 kB, 40 KiB) copiati, 0,0939608 s, 438 kB/sPoiché l'immagine è compressa con LZMA, dobbiamo decomprimerla:
$ unlzma u-boot.bin.lzmaOra abbiamo l'immagine U-Boot:
$ ls -l u-boot.bin
-rw-rw-r-- 1 sprado sprado 97476 Feb 5 08:48 u-boot.binChe ne dite di cercare il valore predefinito per 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=128MVariabile d'ambiente U-Boot bootargs viene utilizzato per trasmettere parametri al kernel di Linux. E da quanto sopra, comprendiamo meglio la memoria flash del dispositivo.
Che ne dici di estrarre l'immagine del kernel di Linux?
$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 record in
1088572+0 record out
1088572 bytes (1,1 MB, 1,0 MiB) copiati, 1,68628 s, 646 kB/sPossiamo verificare che l'immagine sia stata estratta con successo utilizzando il comando file:
$ 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, Load Address: 0x80060000, Entry Point: 0x80060000, Header CRC: 0x78A267FF, Data CRC: 0xBB9D4F94Il formato del file uImage è fondamentalmente un'immagine del kernel di Linux con un'intestazione aggiuntiva. Rimuoviamo questa intestazione per ottenere l'immagine finale del kernel di Linux:
$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 record in
1088500+0 record out
1088500 bytes (1,1 MB, 1,0 MiB) copiati, 1,65603 s, 657 kB/sL'immagine è compressa, quindi scompattiamola:
$ unlzma Image.lzmaOra abbiamo l'immagine del kernel di Linux:
$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Feb 5 10:51 ImageCosa possiamo fare con l'immagine del kernel? Potremmo, ad esempio, cercare le stringhe nell'immagine e trovare la versione del kernel di Linux e scoprire l'ambiente utilizzato per compilare il kernel:
$ 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 2019Anche se il firmware è stato rilasciato lo scorso anno (2019), mentre scrivo questo articolo, utilizza una vecchia versione del kernel di Linux (3.3.8), rilasciata nel 2012, compilata con una versione di GCC molto vecchia (4.6) anch'essa del 2012!
(nota del traduttore: continui a fidarti dei tuoi router in ufficio e a casa?)
Con l'opzione --opcodes possiamo anche utilizzare binwalk per cercare istruzioni macchina e determinare l'architettura del processore dell'immagine:
$ binwalk --opcodes Image
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
2400 0x960 istruzioni MIPS, epilogo della funzione
2572 0xA0C istruzioni MIPS, epilogo della funzione
2828 0xB0C istruzioni MIPS, epilogo della funzioneChe ne dite del filesystem radice? Invece di estrarre manualmente l'immagine, utilizziamo l'opzione binwalk --extract:
$ binwalk --extract --quiet archer-c7.binL'intero filesystem radice verrà estratto in una sottocartella:
$ 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
---------------------------------------------------------------
Per chi sta per rock... (%C, %R)
---------------------------------------------------------------Ora possiamo fare molte cose diverse.
Possiamo cercare file di configurazione, hash delle password, chiavi crittografiche e certificati digitali. Possiamo analizzare file binari per e vulnerabilità.
Utilizzando e possiamo persino eseguire (emulare) un file eseguibile dall'immagine:
$ 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 (20-05-2019 18:13:49 CST) binario multi-chiamata.
Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko
e altri. Concesso in licenza sotto GPLv2.
Vedi distribuzione sorgente per nota completa.
Uso: busybox [funzione] [argomenti]...
o: busybox --list[-full]
o: funzione [argomenti]...
BusyBox è un binario multi-chiamata che combina molte comuni
utilità di Unix in un unico eseguibile. La maggior parte delle persone creerà un
link a busybox per ogni funzione che desiderano utilizzare e BusyBox
agirà come qualsiasi cosa venga invocata.
Funzioni attualmente definite:
[, [[, 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, zcatOttimo! Ma fai attenzione, la versione di BusyBox è 1.19.4. Questa è una versione molto vecchia di BusyBox, rilasciata nell'aprile 2012.
Quindi, TP-Link rilascia un'immagine del firmware nel 2019 utilizzando software (GCC toolchain, kernel, BusyBox, ecc.) del 2012!
Ora capisci perché installo sempre OpenWRT sui miei router?
E non è tutto
Binwalk può anche eseguire un'analisi dell'entropia, stampare dati entropici grezzi e generare grafici dell'entropia. Di solito, una grande entropia è osservata quando i byte nell'immagine sono casuali. Questo può significare che l'immagine contiene un file crittografato, compresso o offuscato. Una chiave di crittografia scritta a mano? Perché no.

Possiamo anche utilizzare il parametro --raw per cercare una sequenza personalizzata di byte grezzi nell'immagine oppure il parametro --hexdump per eseguire un dump esadecimale che confronta due o più file di input.
possono essere aggiunte a binwalk sia tramite un file di firme personalizzate specificato nella riga di comando con il parametro --magic, oppure aggiungendole nella directory $ HOME / .config / binwalk / magic.
Puoi trovare ulteriori informazioni su binwalk in .
Estensione di binwalk
Esiste import binwalk binwalk.scan()
Utilizzando l'API di Python puoi anche creareplugin in Python Esiste anche
un plugin IDA Binwalk Pro .
🥇Reverse engineering di un router domestico con binwalk. Ti fidi del software del tuo router? | ProHoster
Fonte: habr.com
