Inginerie inversă a unui router de acasă folosind binwalk. Ai încredere în software-ul router-ului tău?

Inginerie inversă a unui router de acasă folosind binwalk. Ai încredere în software-ul router-ului tău?

Câteva zile în urmă, am decis să fac inginerie inversă pe firmware-ul routerului meu folosind binwalk.

Mi-am cumpărat routerul de acasă TP-Link Archer C7. Nu este cel mai bun router, dar îmi este suficient pentru nevoile mele.

De fiecare dată când cumpăr un router nou, instalez OpenWRT. 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 descărcat ultima imagine a firmware-ului 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?

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, stripped

Comanda 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 Wikipedia 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 descărca codul sursă și urma instrucțiunile de instalare sau ghidului scurt, 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 specificat

Scanarea imaginilor

Să începem cu căutarea semnăturilor fișierelor în interiorul imaginii (imagine de pe site-ul TP-Link).

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

Acum avem multe informații despre această imagine.

Imaginea folosește U-Boot 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/s

Deoarece imaginea este comprimată folosind LZMA, trebuie să o decompresăm:

$ unlzma u-boot.bin.lzma

Acum avem imaginea U-Boot:

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

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

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

Putem 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: 0xBB9D4F94

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

Imaginea este comprimată, așa că să o decompresăm:

$ unlzma Image.lzma

Acum avem imaginea nucleului Linux:

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

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

Deș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ției

Ce 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.bin

Sistemul 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 a căuta erori și vulnerabilități.

Folosind qemu și chroot 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, zcat

Super! 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.

Inginerie inversă a unui router de acasă folosind binwalk. Ai încredere în software-ul router-ului tău?

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.

Semnăturile personalizate 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 documentația oficială.

Extensia binwalk

Există un API 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 pluginuri Python pentru a personaliza și extinde binwalk.

Există, de asemenea, un plugin IDA și o versiune cloud Binwalk Pro.

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

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster