Обратно инженерство на фърмуера на домашен рутер с помощта на binwalk

Оригиналът е на embeddedbits. Описва се работата на един от софтуерните инструменти на дистрибуцията Kali Linux

Най-четени

Даниел Десподов
Даниел Десподов
Новинар. Увличам се от съвременни технологии, информационна безопасност, спорт, наука и изкуствен интелект.

Преди няколко дни решиха да направя обратно инженерство на фърмуера на моя рутер. Аз използвам TP-Link Archer C7 home router, който може да не е най-добрият рутер, но мен ме устройва.

Всеки път, когато купувам нов рутер, инсталирам OpenWRT. Защо? Почти винаги производителите не се грижат за поддръжката на своите рутери и с времето техния софтуер остарява, появяват се уязвимости и най-различни неприятни промени. Мисля че ме разбирате. Ето защо предпочитам добре поддържания от open-source общността фърмуер OpenWRT.

След като изтеглих OpenWRT, аз изтеглих и най-новата версия на фърмуера на моя рутер Archer C7 от официалния сайт на производителя и реших да го прегледам и анализирам. Научих много нови неща, а и искам да покажа възможностите на binwalk.

Какво е binwalk

Binwalk е софтуерен инструмент с отворен код, който се използва за анализ, обратно инженерство и създаване на файлови образи на фърмуерите.

Създаденият през 2010 година от Крейг Хафнър binwalk може да сканира образите на фърмуерите, да намира файловете в тях, да идентифицира използваната файлова система, да открива модулите с изпълним код, да се справя с компресираните файлове, да разпознава форматите на файловете – JPEG и PDF, и още много други.

Обратно инженерство на фърмуера на домашен рутер с помощта на binwalk

Binwalk може да се използва за обратно инженерство на фърмуерите и по този начин да се разбере как са устроени. Програмата може да търси уязвимости в двоичните файлове, да изважда вградените във фърмуера файлове, да търси задни врати и цифрови сертификати. Ако имате съмнение, че във вашия рутер има задна врата, binwalk ще я открие. Програмата дори може да намира opcodes за различните процесори.

Приложението може да разархивира образите на файловата система и да търси файлове с пароли – passwd, shadow и т.н. Можете да се опитате да разбиете хешовете на тези пароли. Възможен е бинарния анализ на два и повече файла. Има възможност за анализ ентропията на данните с цел търсене на компресирана информация или кодирани криптиращи ключове. Всичко това става без да е необходим достъп до сорс кода на фърмуера.

Как работи binwalk

Знаете ли как работи помощната програма 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

Командата file преглежда заглавието на файла и търси уникална поредица от байтове, за да определи типа на файла. Така например, ако файлът започва с байтовете 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, то това означава, че това е PNG файл. В Уикипедия има списък на повечето уникални поредици за различните файлове.

Binwalk работи по същия начин, но вместо да търси само в началото на файла, сканира целия файл.

И двете помощни програми file и binwalk използват библиотеката libmagic за идентификация на тези уникални байтове. Но binwalk поддържа и списък с уникалните поредици байтове и на видовете компресирани файлове, на видовете фърмуер, на Linux ядрата, зареждащите програми, на различните видове файлови системи и т.н.

Да започваме

Инсталиране на binwalk

Binwalk има версии за няколко операционни системи, включително Linux, OS X, FreeBSD и Windows.

За да се инсталира най-новата версия на binwalk може да се изтегли сорс кода на програмата, и да се следват инструкциите за инсталиране или да се използва краткото ръководство, предлагано в уеб сайта на проекта.

Binwalk има голям брой най-различни параметри:

$ binwalk

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

Usage: binwalk [OPTIONS] [FILE1] [FILE2] [FILE3] ...

Signature Scan Options:
    -B, --signature              Scan target file(s) for common file signatures
    -R, --raw=<str>              Scan target file(s) for the specified sequence of bytes
    -A, --opcodes                Scan target file(s) for common executable opcode signatures
    -m, --magic=<file>           Specify a custom magic file to use
    -b, --dumb                   Disable smart signature keywords
    -I, --invalid                Show results marked as invalid
    -x, --exclude=<str>          Exclude results that match <str>
    -y, --include=<str>          Only show results that match <str>

Extraction Options:
    -e, --extract                Automatically extract known file types
    -D, --dd=<type:ext:cmd>      Extract <type> signatures, give the files an extension of <ext>, and execute <cmd>
    -M, --matryoshka             Recursively scan extracted files
    -d, --depth=<int>            Limit matryoshka recursion depth (default: 8 levels deep)
    -C, --directory=<str>        Extract files/folders to a custom directory (default: current working directory)
    -j, --size=<int>             Limit the size of each extracted file
    -n, --count=<int>            Limit the number of extracted files
    -r, --rm                     Delete carved files after extraction
    -z, --carve                  Carve data from files, but don't execute extraction utilities
    -V, --subdirs                Extract into sub-directories named by the offset

Entropy Options:
    -E, --entropy                Calculate file entropy
    -F, --fast                   Use faster, but less detailed, entropy analysis
    -J, --save                   Save plot as a PNG
    -Q, --nlegend                Omit the legend from the entropy plot graph
    -N, --nplot                  Do not generate an entropy plot graph
    -H, --high=<float>           Set the rising edge entropy trigger threshold (default: 0.95)
    -L, --low=<float>            Set the falling edge entropy trigger threshold (default: 0.85)

Binary Diffing Options:
    -W, --hexdump                Perform a hexdump / diff of a file or files
    -G, --green                  Only show lines containing bytes that are the same among all files
    -i, --red                    Only show lines containing bytes that are different among all files
    -U, --blue                   Only show lines containing bytes that are different among some files
    -u, --similar                Only display lines that are the same between all files
    -w, --terse                  Diff all files, but only display a hex dump of the first file

Raw Compression Options:
    -X, --deflate                Scan for raw deflate compression streams
    -Z, --lzma                   Scan for raw LZMA compression streams
    -P, --partial                Perform a superficial, but faster, scan
    -S, --stop                   Stop after the first result

General Options:
    -l, --length=<int>           Number of bytes to scan
    -o, --offset=<int>           Start scan at this file offset
    -O, --base=<int>             Add a base address to all printed offsets
    -K, --block=<int>            Set file block size
    -g, --swap=<int>             Reverse every n bytes before scanning
    -f, --log=<file>             Log results to file
    -c, --csv                    Log results to file in CSV format
    -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=<str>         Only scan files whose names match this regex
    -p, --fexclude=<str>         Do not scan files whose names match this regex
    -s, --status=<int>           Enable the status server on the specified port
Да започваме със сканирането на фърмуера

Първо, да потърсим уникалните поредици от байтове във файловия образ, който изтеглих от сайта на TP-Link.

За тази цел трябва да се стартира binwalk с параметър –signature и да се укаже името на фърмуера по следния начин:

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

Получаваме следното:

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

DECIMAL       HEXADECIMAL     DESCRIPTION
------------------------------------------------------------------------------------------
21876         0x5574          U-Boot version string, "U-Boot 1.1.4-g4480d5f9-dirty (May
                              20 2019 - 18:45:16)"
21940         0x55B4          CRC32 polynomial table, big endian
23232         0x5AC0          uImage header, header size: 64 bytes, header CRC:
                              0x386C2BD5, created: 2019-05-20 10:45:17, image size:
                              41162 bytes, Data Address: 0x80010000, Entry Point:
                              0x80010000, data CRC: 0xC9CD1E38, OS: Linux, CPU: MIPS,
                              image type: Firmware Image, compression type: lzma, image
                              name: "u-boot image"
23296         0x5B00          LZMA compressed data, properties: 0x5D, dictionary size:
                              8388608 bytes, uncompressed size: 97476 bytes
64968         0xFDC8          XML document, version: "1.0"
78448         0x13270         uImage header, header size: 64 bytes, header CRC:
                              0x78A267FF, created: 2019-07-26 07:46:14, image size:
                              1088500 bytes, Data Address: 0x80060000, Entry Point:
                              0x80060000, data CRC: 0xBB9D4F94, OS: Linux, CPU: MIPS,
                              image type: Multi-File Image, compression type: lzma,
                              image name: "MIPS OpenWrt Linux-3.3.8"
78520         0x132B8         LZMA compressed data, properties: 0x6D, dictionary size:
                              8388608 bytes, uncompressed size: 3164228 bytes
1167013       0x11CEA5        Squashfs filesystem, little endian, version 4.0,
                              compression:xz, size: 14388306 bytes, 2541 inodes,
                              blocksize: 65536 bytes, created: 2019-07-26 07:51:38
15555328      0xED5B00        gzip compressed data, from Unix, last modified: 2019-07-26
                              07:51:41

Сега вече имаме много информация за този фърмуер.

И така, фърмуерът използва U-Boot за зареждаща програма (разпозната по поредицата байтове на адрес 0x5AC0 и нейният компресиран файл на адрес 0x5B00. А от параметъра uImage на адрес 0x13270 виждаме, че процесорът е с MIPS архитектура, а Linux ядрото е версия 3.3.8. Вижда се и че на адрес 0x11CEA5 има дисков образ с файловата система squashfs.

Обратно инженерство на фърмуера на домашен рутер с помощта на binwalk

Да разархивираме зареждащата програма (U-Boot) с помощта на командата dd:

$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 records in
41162+0 records out
41162 bytes (41 kB, 40 KiB) copied, 0,0939608 s, 438 kB/s

Тъй като този файлов образ е компресиран с помощта на LZMA, то можем да разархивираме по следни начин:

$ unlzma u-boot.bin.lzma

Сега вече разполагаме с файла на U-Boot:

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

Да погледнем какво използва по подразбиране 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

Променливата bootargs на U-Boot се използва за предаване на параметри на Linux ядрото. Оттук можем да видим капацитет на флаш паметта на този рутер.

А сега да измъкнем файла на 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) copied, 1,68628 s, 646 kB/s

Можем да проверим, че файлът успешно е разархивиран с помощта на командата 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

Форматът uImage включва Linux ядрото с допълнителна заглавна част. Да я махнем и да получим чистото 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) copied, 1,65603 s, 657 kB/s

Но и то е компресирано и ще трябва да го разкомпресираме:

$ unlzma Image.lzma

Сега вече разполагаме с това Linux ядро:

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

И какво можем да направим с него? Немалко. Можем да извършим търсене и да намерим версията на Linux 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 2019

Ето: въпреки, че фърмуерът е представен през миналата година (2019 г), когато пиша тази статия, в него се използва много стара версия на Linux ядрото – Linux Kernel 3.3.8, излязло през 2012 година и компилирано с много стара версия на GCC (4.6) компилатора, излязла също през 2012 година! Това не е безопасно!

С опцията opcodes може да използваме binwalk за търсене на машинни инструкции за определяне архитектурата на процесора.

$ binwalk --opcodes Image
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
2400 0x960 MIPS instructions, function epilogue
2572 0xA0C MIPS instructions, function epilogue
2828 0xB0C MIPS instructions, function epilogue

А каква ли е кореновата файлова система? Вместо да губим време в ръчно търсене и извличане на необходимия файлов образ, може да използваме binwalk с опцията –extract:

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

Цялата коренова файлова система ще бъде разкомпресирана в отделна подпапка:

$ 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)
 ---------------------------------------------------------------

Сега вече можем да направим много неща.

Можем да потърсим конфигурационните файлове, хешовете на паролите, криптографските ключове и цифровите сертификати. Може да анализираме двоичните файлове и да търсим бъгове и уязвимости.

С помощта на qemu и chroot дори можем да стартираме чрез емулация изпълнимия файл от фърмуера:

$ 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 is a multi-call binary that combines many common Unix
	utilities into a single executable.  Most people will create a
	link to busybox for each function they wish to use and BusyBox
	will act like whatever it was invoked as.

Currently defined functions:
	[, [[, 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

Супер! Но обърнете внимание, че версията на BusyBox е 1.19.4. Това е много стара версия на BusyBox, излязла през месец април 2012 година.

Тоест, TP-Link през 2019 година предлага фърмуер за свой рутер, в който се използва софтуер от 2012 година – GCC toolchain, kernel, BusyBox?

Сега навярно разбирате защо винаги инсталирам OpenWRT на своите рутери?

Това не е Всичко

Binwalk може да извършва анализ на ентропията, да показва данните на ентропията и да създава графики на ентропията. Обикновено, голяма ентропия имаме, когато байтовете във файловия образ на фърмуера са случайни. Това може да означава, че във фърмуера има криптиран, компресиран и/или обфускиран файл. А може би и мъртво записан криптиращ ключ?

Обратно инженерство на фърмуера на домашен рутер с помощта на binwalk

Тук можем да използваме параметъра –raw за търсене на определена поредица от байтове или да използваме параметъра –hexdump за сравняване на два файла.

Повече информация за binwalk е дадена в документацията на програмата.

Разширяване възможностите на binwalk

Има API интерфейс за binwalk, който е написан на Python. А s помощта на Python API може да се създават плъгини на програмния език Python, които служат за настройка и разширяване възможностите на binwalk.

Има и IDA плъгин, предлага се и облачна версия Binwalk Pro.


И така, защо да не изтеглите някой фърмуер от интернет и да пробвате binwalk. Обещавам ви, че ще бъде много интересно 🙂

АбонаментВсичко важно от света на технологиите, директно в пощата ти.

С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.


Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!

11 Коментара
стари
нови оценка

Нови ревюта

Подобни новини