Реверс-инженеринг на домашен рутер с помощта на binwalk. Доверявате ли се на софтуера на рутера си?

Реверс-инженеринг на домашен рутер с помощта на binwalk. Доверявате ли се на софтуера на рутера си?

Преди няколко дни реших да проведа реверсивно инженерство на фърмуера на рутера си, използвайки binwalk.

Купих си TP-Link Archer C7 домашен рутер. Не е най-добрият рутер, но за нуждите ми е напълно достатъчен.

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

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

Какво е binwalk?

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

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

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

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

Всичко необходимо е на разположение 🙂

Как работи binwalk?

Основната характеристика на binwalk е неговото сканиране по сигнатури. Binwalk може да сканира образ на фърмуер за търсене на различни вградени типове файлове и файлови системи.

Знаете ли утилитата за команден ред файл?

file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), динамично свързан, интерпретатор /lib64/l, за GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, стрит

Екип файлгледа заглавката на файла и търси подпис (магическо число), за да определи типа на файла. Например, ако файлът започва с последователност от байтове 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, тя знае, че това е PNG файл. На Уикипедия има списък на често срещаните файлови подписи.

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

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

Да се забавляваме?

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

Binwalk се поддържа на няколко платформи, включително Linux, OSX, FreeBSD и Windows.

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

Binwalk има много различни опции:

$ binwalk

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

Използване: binwalk [ОПЦИИ] [ФАЙЛ1] [ФАЙЛ2] [ФАЙЛ3] ...

Опции за сканиране на сигнатури:
    -B, --signature              Сканирай целевите файлове за общи файлови сигнатури
    -R, --raw=              Сканирай целевите файлове за зададената последователност от байтове
    -A, --opcodes                Сканирай целевите файлове за общи сигнатури на изпълними опкодове
    -m, --magic=           Задайте собствен файл с магически стойности за използване
    -b, --dumb                   Деактивирай умни ключови думи за сигнатури
    -I, --invalid                Показвай резултати, маркирани като невалидни
    -x, --exclude=          Изключи резултати, които съвпадат с 
    -y, --include=          Показвай само резултати, които съвпадат с 

Опции за извличане:
    -e, --extract                Автоматично извличай известни типове файлове
    -D, --dd=      Извличай  сигнатури, дайте на файловете разширение  и изпълнете 
    -M, --matryoshka             Сканирай рекурсивно извлечените файлове
    -d, --depth=            Ограничете рекурсивната дълбочина на матрьошката (по подразбиране: 8 нива дълбочина)
    -C, --directory=        Извлечете файлове/папки в специфична директория (по подразбиране: текуща работна директория)
    -j, --size=             Ограничете размера на всеки извлечен файл
    -n, --count=            Ограничете броя на извлечените файлове
    -r, --rm                     Изтрийте извлечените файлове след извличане
    -z, --carve                  Извлечете данни от файлове, но не изпълнявайте утилити за извличане
    -V, --subdirs                Извличайте в подпапки, наречени на основата на отместването

Опции за ентропия:
    -E, --entropy                Изчислете ентропията на файла
    -F, --fast                   Използвайте по-бърз, но по-малко детайлен анализ на ентропията
    -J, --save                   Запазете графиката като PNG
    -Q, --nlegend                Пропуснете легендата от графиката на ентропията
    -N, --nplot                  Не генерирайте графика на ентропията
    -H, --high=           Задайте прага на нарастващата ентропия (по подразбиране: 0.95)
    -L, --low=            Задайте прага на спадаща ентропия (по подразбиране: 0.85)

Опции за бинарно сравнение:
    -W, --hexdump                Извършете хексдамп / сравнение на файл или файлове
    -G, --green                  Показвайте само редове, съдържащи байтове, които са еднакви сред всички файлове
    -i, --red                    Показвайте само редове, които съдържат байтове, които се различават сред всички файлове
    -U, --blue                   Показвайте само редове, които съдържат байтове, които се различават сред някои файлове
    -u, --similar                Показвайте само редове, които са еднакви между всички файлове
    -w, --terse                  Сравнявайте всички файлове, но показвайте само хексдамп на първия файл

Опции за сурова компресия:
    -X, --deflate                Сканирайте за сурови потоци на компресия с deflate
    -Z, --lzma                   Сканирайте за сурови потоци на LZMA компресия
    -P, --partial                Извършете повърхностно, но по-бързо сканиране
    -S, --stop                   Спирайте след първия резултат

Общи опции:
    -l, --length=           Брой байтове за сканиране
    -o, --offset=           Започнете сканирането от това файл отместване
    -O, --base=             Добавете основен адрес към всички принтнати отмествания
    -K, --block=            Задайте размер на файл блок
    -g, --swap=             Обърнете всеки n байта преди сканиране
    -f, --log=             Логирайте резултатите във файл
    -c, --csv                    Логирайте резултатите във файл в CSV формат
    -t, --term                   Форматирайте изхода, за да се побере в терминалния прозорец
    -q, --quiet                  Потиснете изхода в stdout
    -v, --verbose                Активирайте подробен изход
    -h, --help                   Показвайте помощния изход
    -a, --finclude=         Сканирайте само файлове, чиито имена съвпадат с този regex
    -p, --fexclude=         Не сканирайте файлове, чиито имена съвпадат с този regex
    -s, --status=           Активирайте статусния сървър на зададения порт

Сканиране на образи

Да започнем с търсенето на сигнатури на файлове в образа (образ от сайта TP-Link).

Стартиране на binwalk с параметър —signature:

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

ДЕСЕТИЧЕН       ХЕКСАДЕСИМАЛЕН     ОПИСАНИЕ
------------------------------------------------------------------------------------------
21876         0x5574          Стринг на версията на U-Boot, "U-Boot 1.1.4-g4480d5f9-dirty (20 май
                              2019 - 18:45:16)"
21940         0x55B4          CRC32 полиномна таблица, голям край
23232         0x5AC0          uImage заглавие, размер на заглавието: 64 байта, CRC на заглавието:
                              0x386C2BD5, създадено: 2019-05-20 10:45:17, размер на изображението:
                              41162 байта, Адрес на данни: 0x80010000, Начална точка:
                              0x80010000, CRC на данните: 0xC9CD1E38, ОС: Linux, CPU: MIPS,
                              тип на изображението: Firmware Image, тип на компресия: lzma, име на изображението:
                              "u-boot изображение"
23296         0x5B00          LZMA компресирани данни, свойства: 0x5D, размер на речника:
                              8388608 байта, некопресиран размер: 97476 байта
64968         0xFDC8          XML документ, версия: "1.0"
78448         0x13270         uImage заглавие, размер на заглавието: 64 байта, CRC на заглавието:
                              0x78A267FF, създадено: 2019-07-26 07:46:14, размер на изображението:
                              1088500 байта, Адрес на данни: 0x80060000, Начална точка:
                              0x80060000, CRC на данните: 0xBB9D4F94, ОС: Linux, CPU: MIPS,
                              тип на изображението: Multi-File Image, тип на компресия: lzma,
                              име на изображението: "MIPS OpenWrt Linux-3.3.8"
78520         0x132B8         LZMA компресирани данни, свойства: 0x6D, размер на речника:
                              8388608 байта, некопресиран размер: 3164228 байта
1167013       0x11CEA5        Squashfs файлова система, малък край, версия 4.0,
                              компресия:xz, размер: 14388306 байта, 2541 инода,
                              размер на блока: 65536 байта, създадено: 2019-07-26 07:51:38
15555328      0xED5B00        gzip компресирани данни, от Unix, последно модифицирано: 2019-07-26
                              07:51:41

Сега разполагаме с много информация за този образ.

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

Сега да разопаковаме загрузчика (U-Boot) с помощта на командата dd:

$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 записи в
41162+0 записи извън
41162 байта (41 kB, 40 KiB) копирани, 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 Фев  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

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

Какво ще кажете за извличането на образа на ядрото на Linux?

$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 записи в
1088572+0 записи извън
1088572 байта (1,1 MB, 1,0 MiB) копирани, 1,68628 с, 646 kB/s

Можем да проверим, че образът е бил извлечен успешно с командата файл:

$ file uImage
uImage: у-boot наследствен uImage, MIPS OpenWrt Linux-3.3.8, Linux/MIPS, Мултифайлов образ (lzma), 1088500 байта, Пт 26 юли 07:46:14 2019, Адрес на зареждане: 0x80060000, Точка на вход: 0x80060000, Заглавен CRC: 0x78A267FF, Данни CRC: 0xBB9D4F94

Форматът на файла uImage е основно образ на ядрото на Linux с допълнителен заглавен файл. Нека премахнем този заглавен файл, за да получим окончателния образ на ядрото на Linux:

$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 записи в
1088500+0 записи извън
1088500 байта (1,1 MB, 1,0 MiB) копирани, 1,65603 с, 657 kB/s

Образът е компресиран, така че нека го разпакуваме:

$ unlzma Image.lzma

Сега имаме образа на ядрото на Linux:

$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Фев  5 10:51 Image

Какво можем да направим с образа на ядрото? Можем, например, да направим търсене по низове в образа и да намерим версията на ядрото на Linux и да научим за средата, използвана за компилирането на ядрото:

$ strings Image | grep "Linux version"
Linux version 3.3.8 (leo@leo-MS-7529) (gcc version 4.6.3 20120201 (предварителна версия) (Linaro GCC 4.6-2012.02) ) #1 Пн 20 май 18:53:02 CST 2019

Въпреки че фърмуерът беше освободен миналата година (2019 г.), когато пиша тази статия, той използва стара версия на ядрото на Linux (3.3.8), освободена през 2012 г. и компилирана с много стара версия на GCC (4.6), също от 2012 г.!
(прим. прев. все още ли се доверявате на вашите рутери в офиса и у дома?)

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

$ binwalk --opcodes Image
ДЕСЕТИЧЕН       ШЕСТНАДЕСЕТЕН     ОПИСАНИЕ
--------------------------------------------------------------------------------
2400          0x960           MIPS инструкции, функция епилог
2572          0xA0C           MIPS инструкции, функция епилог
2828          0xB0C           MIPS инструкции, функция епилог

Какво ще кажете за кореновата файлова система? Вместо да извличаме образа ръчно, нека да използваме опцията 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 е многофункционален бинарен файл, който комбинира много общи Unix
    утилити в един единствен изпълним файл.  Повечето хора ще създадат
    връзка към busybox за всяка функция, която искат да използват и BusyBox
    ще действа като каквото е било извикано.

В момента дефинираните функции:
    [, [[, 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 година, използвайки софтуер (GCC toolchain, kernel, BusyBox и т.н.) от 2012 година!

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

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

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

Реверс-инженеринг на домашен рутер с помощта на binwalk. Доверявате ли се на софтуера на рутера си?

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

Потребителските сигнатури могат да бъдат добавени в binwalk либо чрез файл с потребителски сигнатури, указан в командния ред с параметър --magic, либо чрез добавянето им в директорията $ HOME / .config / binwalk / magic.

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

Разширение binwalk

Съществува API интерфейс binwalk, реализиран като Python модул, който може да бъде използван от всеки Python скрипт за програмирано изпълнение на сканиране с binwalk, а командният инструмент binwalk може да бъде почти напълно дублиран с две реда Python код!

import binwalk
binwalk.scan()

С помощта на Python API можете също да създавате плъгини под Python за настройка и разширение на binwalk.

Съществува също плъгин IDA и облачна версия Binwalk Pro.

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

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster