
Qualche giorno fa, ho deciso di eseguire un reverse engineering del firmware del mio router utilizzando binwalk.
Ho acquistato un . 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 preoccupano molto del supporto dei propri router e col passare del tempo il software diventa obsoleto, sorgono vulnerabilità e così via, insomma, avete capito. Per questo motivo preferisco un firmware open-source ben supportato dalla comunità, OpenWRT.
Dopo aver scaricato OpenWRT, ho anche per il mio nuovo Archer C7 dal sito ufficiale e ho deciso di analizzarlo. Solo per divertimento e per parlare di binwalk.
Che cos'è binwalk?
è uno strumento open-source per analizzare, eseguire reverse engineering e estrarre immagini di firmware.
Creato nel 2010 da Craig Heffner, binwalk può scansionare immagini di firmware e trovare file, identificare ed estrarre immagini di file system, codice eseguibile, archivi compressi, bootloader e kernel, formati di file come JPEG e PDF, e molto altro.
Puoi utilizzare binwalk per il reverse engineering del firmware per capire come è strutturato. Cerca vulnerabilità nei file binari, estrai file e cerca backdoor o certificati digitali. Puoi anche trovare opcodes per diversi CPU.
Puoi decomprimere le immagini del file system per cercare determinati file di password (passwd, shadow, ecc.) e tentare di rompere gli hash delle password. Puoi eseguire un'analisi binaria tra due o più file. Puoi effettuare un'analisi dell'entropia dei dati per cercare dati compressi o chiavi di crittografia codificate. Tutto questo senza la necessità di accedere al codice sorgente.
In generale, tutto il necessario è qui 🙂
Come funziona binwalk?
La caratteristica principale di binwalk è la scansione basata su firme. Binwalk può eseguire la scansione dell'immagine del firmware per cercare diversi tipi di file e file system incorporati.
Conosci l'utilità della 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, per GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, strippedTeam fileesamina l'intestazione del file e cerca una firma (numero magico) per determinare il tipo di file. Ad esempio, se un file inizia con una sequenza di byte 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, sa che si tratta di un file PNG. Su c'è un elenco delle firme file più comuni.
Binwalk funziona in modo simile. Ma invece di cercare firme solo all'inizio del file, binwalk esaminerà l'intero file. Inoltre, binwalk può estrarre file trovati nell'immagine.
Strumenti file e binwalk utilizza la libreria libmagic per identificare le firme dei file. Ma binwalk supporta anche un elenco di firme magiche personalizzate per la ricerca di file compressi / archivi, intestazioni di firmware, kernel Linux, bootloader, filesystem e altro.
Divertiamoci?
Installazione di binwalk
Binwalk è supportato su più piattaforme, tra cui Linux, OSX, FreeBSD e Windows.
Per installare l'ultima versione di binwalk, puoi e seguire o , disponibile sul sito web del progetto.
Binwalk ha molte opzioni diverse:
$ 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/i target per firme di file comuni
-R, --raw= Scansiona il file/i target per la sequenza di byte specificata
-A, --opcodes Scansiona il file/i target per le firme di opcode eseguibili comuni
-m, --magic= Specifica un file magic personalizzato da usare
-b, --dumb Disabilita le parole chiave di firma intelligenti
-I, --invalid Mostra i risultati contrassegnati come non validi
-x, --exclude= Escludi i risultati che corrispondono a
-y, --include= Mostra solo i risultati che corrispondono a
Opzioni di estrazione:
-e, --extract Estrai automaticamente i tipi di file conosciuti
-D, --dd= Estrai le firme , assegna ai file un'estensione di e esegui
-M, --matryoshka Scansiona ricorsivamente i file estratti
-d, --depth= Limita la profondità di ricorsione matryoshka (default: 8 livelli)
-C, --directory= Estrai file/cartelle in una directory personalizzata (default: directory di lavoro corrente)
-j, --size= Limita la dimensione di ogni file estratto
-n, --count= Limita il numero di file estratti
-r, --rm Elimina i file scolpiti dopo l'estrazione
-z, --carve Scolpisci dati dai file, ma non eseguire le utilità di estrazione
-V, --subdirs Estrai 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ù veloce, ma meno dettagliata
-J, --save Salva il grafico come PNG
-Q, --nlegend Ometti la legenda dal grafico dell'entropia
-N, --nplot Non generare un grafico dell'entropia
-H, --high= Imposta la soglia del trigger dell'entropia del bordo ascendente (default: 0.95)
-L, --low= Imposta la soglia del trigger dell'entropia del bordo discendente (default: 0.85)
Opzioni di differenziazione binaria:
-W, --hexdump Esegui un hexdump / differenza di uno o più file
-G, --green Mostra solo le righe che contengono byte che sono uguali tra tutti i file
-i, --red Mostra solo le righe che contengono byte che sono diversi tra tutti i file
-U, --blue Mostra solo le righe che contengono byte che sono diversi tra alcuni file
-u, --similar Mostra solo le righe che sono uguali tra tutti i file
-w, --terse Differenzia tutti i file, ma mostra solo un hexdump del primo file
Opzioni di compressione raw:
-X, --deflate Scansiona per flussi di compressione deflate raw
-Z, --lzma Scansiona per flussi di compressione LZMA raw
-P, --partial Esegui una scansione superficiale, ma più veloce
-S, --stop Fermati 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= Aggiungi un indirizzo base a tutti gli offset stampati
-K, --block= Imposta la dimensione del blocco del file
-g, --swap= Inverti ogni n byte prima della scansione
-f, --log= Registra i risultati in un file
-c, --csv Registra i risultati in un file in formato CSV
-t, --term Format output to fit the terminal window
-q, --quiet Suppress output to stdout
-v, --verbose Enable verbose output
-h, --help Show help output
-a, --finclude= Scansiona solo i file i cui nomi corrispondono a questa regex
-p, --fexclude= Non scansionare i file i cui nomi corrispondono a questa regex
-s, --status= Abilita il server di stato sulla porta specificataScansione delle immagini
Iniziamo a cercare le firme dei file all'interno dell'immagine (immagine dal sito ).
Esecuzione di binwalk con il parametro —signature:
$ binwalk --signature --term archer-c7.bin
DECIMALE ESASIMALE DESCRIZIONE
------------------------------------------------------------------------------------------
21876 0x5574 Stringa di versione U-Boot, "U-Boot 1.1.4-g4480d5f9-dirty (20 Maggio
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 Entrata:
0x80010000, CRC dati: 0xC9CD1E38, SO: 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 Entrata:
0x80060000, CRC dati: 0xBB9D4F94, SO: 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 inodes,
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 (header dell'immagine all'indirizzo 0x5AC0 e l'immagine compressa del bootloader all'indirizzo 0x5B00). Basandoci sull'header uImage all'indirizzo 0x13270, sappiamo che l'architettura del processore è MIPS e il kernel Linux è la versione 3.3.8. E basandoci sull'immagine trovata all'indirizzo 0x11CEA5, possiamo vedere che rootfs è il file system 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 estrarla:
$ 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 dici 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=128MLa variabile d'ambiente di U-Boot bootargs è utilizzata per passare parametri al kernel Linux. E da quanto sopra, comprendiamo meglio la memoria flash del dispositivo.
Che ne dici di estrarre l'immagine del kernel Linux?
$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 records in
1088572+0 records out
1088572 bytes (1,1 MB, 1,0 MiB) copiati, 1,68628 s, 646 kB/sPossiamo verificare che l'immagine è 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, Ven 26 Lug 07:46:14 2019, Load Address: 0x80060000, Entry Point: 0x80060000, Header CRC: 0x78A267FF, Data CRC: 0xBB9D4F94Il formato del file uImage è essenzialmente un'immagine del kernel Linux con un'intestazione aggiuntiva. Rimuoviamo questa intestazione per ottenere l'immagine finale del kernel Linux:
$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 records in
1088500+0 records out
1088500 bytes (1,1 MB, 1,0 MiB) copiati, 1,65603 s, 657 kB/sL'immagine è compressa, quindi procediamo a decomprimerla:
$ unlzma Image.lzmaOra abbiamo l'immagine del kernel 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 per trovare la versione del kernel Linux e informazioni sull'ambiente utilizzato per la compilazione del 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 Lun Mag 20 18:53:02 CST 2019Nonostante il firmware sia stato rilasciato lo scorso anno (2019), mentre scrivo questo articolo, utilizza una vecchia versione del kernel Linux (3.3.8), rilasciata nel 2012, compilata con una versione molto datata di GCC (4.6) anch'essa del 2012!
(nota del traduttore: continuate a fidarvi dei vostri 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
DECIMALE ESADECIMALE DESCRIZIONE
--------------------------------------------------------------------------------
2400 0x960 Istruzioni MIPS, epilogo della funzione
2572 0xA0C Istruzioni MIPS, epilogo della funzione
2828 0xB0C Istruzioni MIPS, epilogo della funzioneE per quanto riguarda il filesystem root? Invece di estrarre manualmente l'immagine, utilizziamo l'opzione binwalk --extract:
$ binwalk --extract --quiet archer-c7.binL'intero filesystem root sarà estratto in una sottodirectory:
$ 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)
---------------------------------------------------------------Ora possiamo fare molte cose diverse.
Possiamo cercare file di configurazione, hash di password, chiavi crittografiche e certificati digitali. Possiamo anche analizzare file binari per e vulnerabilità.
Con 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 (2019-05-20 18:13:49 CST) multi-call binary.
Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.
Usage: busybox [function] [arguments]...
or: busybox --list[-full]
or: function [arguments]...
BusyBox è un binario multi-call che combina molte utilità Unix
comuni in un unico eseguibile. La maggior parte delle persone creerà un
collegamento a busybox per ogni funzione che desiderano utilizzare e BusyBox
si comporterà come qualsiasi altra funzione 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, zcatCiao! Ma tieni presente che la versione di BusyBox è 1.19.4. Questa è una versione molto vecchia di BusyBox, rilasciata nell'aprile 2012.
In questo modo, TP-Link rilascia un'immagine del firmware nel 2019 utilizzando software (toolchain GCC, kernel, BusyBox, ecc.) del 2012!
Ora capisci perché installo sempre OpenWRT sui miei router?
Questo non è tutto
Binwalk può anche eseguire analisi di entropia, stampare dati di entropia grezzi e generare grafici di entropia. Di solito, un'alta entropia si osserva quando i byte nell'immagine sono casuali. Questo può significare che l'immagine contiene file crittografati, compressi o offuscati. Una chiave di crittografia hardcoded? Perché no.

Possiamo anche utilizzare il parametro --raw per cercare sequenze personalizzate di byte grezzi nell'immagine o il parametro --hexdump per eseguire un dump esadecimale che confronta due o più file di input.
possono essere aggiunte a binwalk 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 binwalk
Esiste binwalk, implementato come un modulo Python, può essere utilizzato da qualsiasi script Python per eseguire programmaticamente la scansione binwalk; la utility da riga di comando binwalk può essere quasi completamente duplicata con sole due righe di codice Python!
import binwalk
binwalk.scan()Con l'API Python puoi anche creare per personalizzare ed estendere binwalk.
Esiste anche un e una versione cloud .
Allora perché non scaricare un'immagine del firmware da Internet e provare binwalk? Ti prometto che ti divertirai molto 🙂
Fonte: habr.com
