
Câteva zile în urmă, am decis să fac inginerie inversă pe firmware-ul routerului meu folosind binwalk.
Mi-am cumpărat . Nu este cel mai bun router, dar îmi este suficient pentru nevoile mele.
De fiecare dată când cumpăr un router nou, instalez . De ce? De obicei, producătorii nu se îngrijesc prea mult de suportul pentru routerele lor, iar în timp software-ul devine învechit, apar vulnerabilități și așa mai departe, înțelegeți. Așadar, prefer firmware-ul open-source OpenWRT, care este bine susținut de comunitate.
După ce am descărcat OpenWRT, am de asemenea pentru noul meu Archer C7 de pe site-ul oficial și am decis să-l analizez. Pur și simplu din plăcere și pentru a povesti despre binwalk.
Ce este binwalk?
este un instrument open-source pentru analiza, inginerie inversă și extragerea imaginilor firmware-ului.
Creat în 2010 de Craig Heffner, binwalk poate scana imaginile firmware-ului și găsi fișiere, identifica și extrage imagini ale sistemului de fișiere, cod executabil, arhive comprimate, bootloadere și nuclee, formate de fișiere precum JPEG și PDF și multe altele.
Puteți folosi binwalk pentru ingineria inversă a firmware-ului pentru a înțelege cum este structurat. Să căutați vulnerabilități în fișierele binare, să extrageți fișiere și să căutați backdoor-uri sau certificate digitale. De asemenea, puteți găsi opcodes pentru o mulțime de CPU-uri diferite.
Puteți dezarhiva imaginile sistemului de fișiere pentru a căuta anumite fișiere de parole (passwd, shadow etc.) și încercați să spargeți hash-urile parolelor. Puteți efectua o analiză binară între două sau mai multe fișiere. Puteți efectua analiza entropiei datelor pentru a căuta date comprimate sau chei criptate. Toate acestea fără a avea nevoie de acces la codul sursă.
În general, tot ce este necesar este acolo 🙂
Cum funcționează binwalk?
Principala caracteristică a binwalk este scanarea sa pe bază de semnături. Binwalk poate scana imaginea firmware-ului pentru a căuta diferite tipuri de fișiere și sisteme de fișiere încorporate.
Știți de utilitarul de linie de comandă 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, strippedComanda filese uită la antetul fișierului și caută o semnătură (număr magic) pentru a determina tipul fișierului. De exemplu, dacă fișierul începe cu o secvență de biți 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, știe că acesta este un fișier PNG. Pe există o listă de semnături de fișiere comune.
Binwalk funcționează în mod similar. Dar în loc să caute semnături doar la începutul fișierului, binwalk va scana întreg fișierul. În plus, binwalk poate extrage fișiere găsite în imagine.
Instrumente file și binwalk folosește biblioteca libmagic pentru a identifica semnăturile fișierelor. Dar binwalk suportă de asemenea o listă de semnături magice personalizate pentru a căuta fișiere comprimate / arhivate, anteturi de firmware, kernel-uri Linux, bootloade-ere, sisteme de fișiere și multe altele.
Să ne distram?
Instalarea binwalk
Binwalk este compatibil cu mai multe platforme, inclusiv Linux, OSX, FreeBSD și Windows.
Pentru a instala cea mai recentă versiune a binwalk, puteți și urma sau , disponibil pe site-ul proiectului.
Binwalk are multe opțiuni diferite:
$ binwalk
Binwalk v2.2.0
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
Utilizare: binwalk [OPȚIUNI] [FILE1] [FILE2] [FILE3] ...
Opțiuni pentru scanarea semnăturilor:
-B, --signature Scanează fișierul țintă pentru semnăturile fișierelor comune
-R, --raw= Scanează fișierul țintă pentru secvența specificată de bytes
-A, --opcodes Scanează fișierul țintă pentru semnăturile obișnuite ale opcode-urilor executabile
-m, --magic= Specifică un fișier magic personalizat de utilizat
-b, --dumb Dezactivează cuvintele cheie inteligente ale semnăturii
-I, --invalid Afișează rezultatele marcate ca invalide
-x, --exclude= Exclude rezultatele care se potrivesc cu
-y, --include= Afișează doar rezultatele care se potrivesc cu
Opțiuni de extragere:
-e, --extract Extragere automată a tipurilor de fișiere cunoscute
-D, --dd= Extrage semnături , oferă fișierelor o extensie de , și execută
-M, --matryoshka Scanează recursiv fișierele extrase
-d, --depth= Limitează adâncimea recursiei matryoshka (implicit: 8 niveluri adânc)
-C, --directory= Extrage fișierele/folderele într-un director personalizat (implicit: directorul de lucru curent)
-j, --size= Limitează dimensiunea fiecărui fișier extras
-n, --count= Limitează numărul de fișiere extrase
-r, --rm Șterge fișierele sculptate după extragere
-z, --carve Sculptare date din fișiere, dar nu execută utilitarele de extragere
-V, --subdirs Extrage în subdirectoare denumite după offset
Opțiuni de entropie:
-E, --entropy Calculează entropia fișierului
-F, --fast Folosește o analiză a entropiei mai rapidă, dar mai puțin detaliată
-J, --save Salvează graficul ca un PNG
-Q, --nlegend Omit graficul legendei din graficul de entropie
-N, --nplot Nu generează un grafic de entropie
-H, --high= Setează pragul de declanșare a entropiei pentru marginea în creștere (implicit: 0.95)
-L, --low= Setează pragul de declanșare a entropiei pentru marginea în scădere (implicit: 0.85)
Opțiuni de difuzare binară:
-W, --hexdump Efectuează o dumpare hexa / difuzare a unui fișier sau fișiere
-G, --green Afișează doar liniile care conțin bytes identice între toate fișierele
-i, --red Afișează doar liniile care conțin bytes diferiți între toate fișierele
-U, --blue Afișează doar liniile care conțin bytes diferiți între unele fișiere
-u, --similar Afișează doar liniile care sunt identice între toate fișierele
-w, --terse Difuza toate fișierele, dar afișează doar o dumpare hex a primului fișier
Opțiuni pentru comprimarea raw:
-X, --deflate Scanează pentru fluxuri de comprimare deflate raw
-Z, --lzma Scanează pentru fluxuri de comprimare LZMA raw
-P, --partial Efectuează un scan rapid, dar superficial
-S, --stop Oprește după primul rezultat
Opțiuni generale:
-l, --length= Numărul de bytes de scanat
-o, --offset= Începe scanarea de la acest offset al fișierului
-O, --base= Adaugă o adresă de bază la toate offset-urile imprimate
-K, --block= Setează dimensiunea blocului de fișier
-g, --swap= Inversează fiecare n bytes înainte de scanare
-f, --log= Loghează rezultatele într-un fișier
-c, --csv Loghează rezultatele într-un fișier în format CSV
-t, --term Formatează ieșirea pentru a se potrivi cu fereastra terminalului
-q, --quiet Suprimă ieșirea pe stdout
-v, --verbose Activează ieșirea detaliată
-h, --help Afișează ieșirea de ajutor
-a, --finclude= Scanează doar fișierele a căror denumire se potrivește cu acest regex
-p, --fexclude= Nu scana fișierele a căror denumire se potrivește cu acest regex
-s, --status= Activează serverul de stare pe portul specificatScanarea imaginilor
Să începem cu căutarea semnăturilor fișierelor în interiorul imaginii (imagine de pe site-ul ).
Pornirea binwalk cu parametrul —signature:
$ binwalk --signature --term archer-c7.bin
DECIMAL HEXADECIMAL DESCRIERE
------------------------------------------------------------------------------------------
21876 0x5574 String-ul versiunii U-Boot, "U-Boot 1.1.4-g4480d5f9-dirty (Mai
20 2019 - 18:45:16)"
21940 0x55B4 Tabelul polinomial CRC32, big endian
23232 0x5AC0 Antet uImage, dimensiunea antetului: 64 bytes, CRC-ul antetului:
0x386C2BD5, creat: 2019-05-20 10:45:17, dimensiunea imaginii:
41162 bytes, Adresa datelor: 0x80010000, Punctul de intrare:
0x80010000, CRC de date: 0xC9CD1E38, OS: Linux, CPU: MIPS,
tipul imaginii: Imagine Firmware, tip de compresie: lzma, imagine
numită: "imagine u-boot"
23296 0x5B00 Date comprimate LZMA, proprietăți: 0x5D, dimensiunea dicționarului:
8388608 bytes, dimensiunea necomprimată: 97476 bytes
64968 0xFDC8 Document XML, versiunea: "1.0"
78448 0x13270 Antet uImage, dimensiunea antetului: 64 bytes, CRC-ul antetului:
0x78A267FF, creat: 2019-07-26 07:46:14, dimensiunea imaginii:
1088500 bytes, Adresa datelor: 0x80060000, Punctul de intrare:
0x80060000, CRC de date: 0xBB9D4F94, OS: Linux, CPU: MIPS,
tipul imaginii: Multi-File Image, tip de compresie: lzma,
imagine numită: "MIPS OpenWrt Linux-3.3.8"
78520 0x132B8 Date comprimate LZMA, proprietăți: 0x6D, dimensiunea dicționarului:
8388608 bytes, dimensiunea necomprimată: 3164228 bytes
1167013 0x11CEA5 Sistem de fișiere Squashfs, little endian, versiunea 4.0,
compresie:xz, dimensiunea: 14388306 bytes, 2541 inodes,
dimensiunea blocului: 65536 bytes, creat: 2019-07-26 07:51:38
15555328 0xED5B00 Date comprimate gzip, din Unix, ultima modificare: 2019-07-26
07:51:41Acum avem multe informații despre această imagine.
Imaginea folosește ca bootloader (antetul imaginii la adresa 0x5AC0 și imaginea comprimată a bootloader-ului la adresa 0x5B00). Pe baza antetului uImage de la adresa 0x13270, știm că arhitectura procesorului este MIPS, iar nucleul Linux este versiunea 3.3.8. Iar pe baza imaginii găsite la adresa 0x11CEA5, putem vedea că rootfs este sistemul de fișiere squashfs.
Hai să decompresăm acum bootloader-ul (U-Boot) folosind comanda dd:
$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 înregistrări
41162+0 înregistrări ieșire
41162 bytes (41 kB, 40 KiB) copiate, 0,0939608 s, 438 kB/sDeoarece imaginea este comprimată folosind LZMA, trebuie să o decompresăm:
$ unlzma u-boot.bin.lzmaAcum avem imaginea U-Boot:
$ ls -l u-boot.bin
-rw-rw-r-- 1 sprado sprado 97476 Feb 5 08:48 u-boot.binCe zici de a căuta valoarea implicită pentru 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=128MVariabila de mediu U-Boot bootargs este utilizat pentru a transmite parametrii către nucleul Linux. Din cele de mai sus, înțelegem mai bine flash-ul dispozitivului.
Ce părere aveți despre extragerea imaginii nucleului Linux?
$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 înregistrări în
1088572+0 înregistrări ieșite
1088572 bytes (1,1 MB, 1,0 MiB) copiate, 1,68628 s, 646 kB/sPutem verifica că imaginea a fost extrasă cu succes folosind comanda 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: 0xBB9D4F94Formatul fișierului uImage este în principal imaginea nucleului Linux cu un antet suplimentar. Să eliminăm acest antet pentru a obține imaginea finală a nucleului Linux:
$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 înregistrări în
1088500+0 înregistrări ieșite
1088500 bytes (1,1 MB, 1,0 MiB) copiate, 1,65603 s, 657 kB/sImaginea este comprimată, așa că să o decompresăm:
$ unlzma Image.lzmaAcum avem imaginea nucleului Linux:
$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Feb 5 10:51 ImageCe putem face cu imaginea nucleului? De exemplu, am putea face o căutare a șirurilor în imagine și să aflăm versiunea nucleului Linux și informații despre mediul utilizat pentru compilarea nucleului:
$ 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 2019Deși firmware-ul a fost lansat anul trecut (2019), când scriu acest articol, acesta folosește o versiune veche a nucleului Linux (3.3.8), lansată în 2012, compilată cu o versiune foarte veche de GCC (4.6) de asemenea din 2012!
(notă de traducere: mai aveți încredere în routerele din birou și acasă?)
Cu opțiunea --opcodes putem folosi binwalk pentru a căuta instrucțiuni mașină și a determina arhitectura procesorului imaginii:
$ binwalk --opcodes Image
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
2400 0x960 instrucțiuni MIPS, epilog al funcției
2572 0xA0C instrucțiuni MIPS, epilog al funcției
2828 0xB0C instrucțiuni MIPS, epilog al funcțieiCe facem cu sistemul de fișiere rădăcină? În loc să extragem manual imaginea, să folosim opțiunea binwalk --extract:
$ binwalk --extract --quiet archer-c7.binSistemul complet de fișiere rădăcină va fi extras în subdirectorul:
$ 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)
---------------------------------------------------------------Acum putem face multe lucruri diferite.
Putem căuta fișiere de configurare, hash-uri de parole, chei criptografice și certificate digitale. Putem analiza fișiere binare pentru și vulnerabilități.
Folosind și putem chiar să rulăm (să emulăm) un fișier executabil din imagine:
$ 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) binary multi-apel.
Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko
și alții. Licențiat sub GPLv2.
Vezi distribuția sursă pentru notificarea completă.
Utilizare: busybox [funcție] [argumente]...
sau: busybox --list[-full]
sau: funcție [argumente]...
BusyBox este un binar multi-apel care combină multe utilitare Unix comune
într-un singur executabil. Cei mai mulți oameni vor crea un
link către busybox pentru fiecare funcție pe care doresc să o folosească și BusyBox
va acționa ca oricare ar fi invocat.
Funcții definite în prezent:
[, [[, 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, zcatSuper! Dar rețineți că versiunea BusyBox este 1.19.4. Este o versiune foarte veche de BusyBox, lansată în aprilie 2012.
Așadar, TP-Link lansează o imagine de firmware în 2019 folosind software (GCC toolchain, kernel, BusyBox etc.) din 2012!
Acum înțelegi de ce eu întotdeauna instalez OpenWRT pe routerele mele?
Asta nu e tot
Binwalk poate efectua, de asemenea, analiza entropiei, să imprime datele brute de entropie și să genereze grafice de entropie. De obicei, o entropie mare este observată atunci când byte-urile din imagine sunt aleatorii. Acest lucru poate indica faptul că imaginea conține un fișier criptat, comprimat sau obfuscat. Cheia de criptare scrisă hardcore? De ce nu.

Putem folosi, de asemenea, parametrul --raw pentru a căuta o secvență personalizată de byte-uri brute în imagine sau parametrul --hexdump pentru a efectua un dump hexazimal, comparând două sau mai multe fișiere de intrare.
pot fi adăugate în binwalk fie prin intermediul unui fișier de semnături personalizate, specificat în linia de comandă cu ajutorul parametrului --magic, fie prin adăugarea lor în directorul $ HOME / .config / binwalk / magic.
Puteți găsi mai multe informații despre binwalk în .
Extensia binwalk
Există un binwalk, realizat sub forma unui modul Python, care poate fi utilizat de orice script Python pentru a executa programatic scanarea binwalk, iar utilitarul de linie de comandă binwalk poate fi aproape complet replicat cu doar două rânduri de cod Python!
import binwalk
binwalk.scan()Cu ajutorul API-ului Python, de asemenea, puteți crea pentru a personaliza și extinde binwalk.
Există, de asemenea, și o versiune cloud .
Așa că de ce să nu descărcați o imagine de firmware de pe internet și să încercați binwalk? Promit că vă veți distra mult 🙂
Sursa: habr.com
