
Давайте повеселимся, копаясь в прошивке маршрутизатора Zyxel и архитектуре MIPS
Учебные материалы предназначены только для информационных и образовательных целей. Я считаю, что этичный хакинг, информационная безопасность и кибербезопасность должны быть знакомыми темами для всех, кто использует цифровую информацию и компьютеры. Я считаю, что невозможно защититься от хакеров, не зная, как осуществляется взлом.
$ IDA Pro +7.0 (можно использовать Radar2, так как IDA довольно дорогая)
$ Маршрутизатор с Rompager 4.07: их огромное количество, например TP-Link TD-W8951*, ZyXEL P-660R, Billion BiPAC 51**/52**
$ UART-USB
Уязвимость «Misfortune Cookie» существует уже некоторое время, но в открытом доступе по-прежнему не хватает анализа, иллюстрирующего технические детали уязвимости. По данным Check Point, уязвимым программным обеспечением является встроенный веб-сервер RomPager от AllegroSoft. Сканирование в интернете показывает, что RomPager, вероятно, является самым популярным веб-серверным программным обеспечением в мире по количеству доступных конечных точек. RomPager обычно встроен в прошивку, поставляемую с устройством. Эта конкретная уязвимость была внесена в кодовую базу в 2002 году. Кроме того, уязвимы устройства, использующие службы RomPager версий до 4.34 (и особенно 4.07).
Для этого урока я буду использовать ZXHN H108L с Rompager 4.07
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="ZXHN H108L"
Content-Type: text/html
Transfer-Encoding: chunked
Server: RomPager/4.07 UPnP/1.0
EXT:
Теперь воспользуемся последовательным портом. Сначала нужно определить скорость передачи данных (Baud rate).
$ sudo stty -F /dev/ttyUSB0
ВЫВОД:
speed 115200 baud; line = 0;
-brkint -imaxbel
device
Я использую minicom, вы можете использовать что угодно, от screen до HyperTerminal, но я предпочитаю этот из-за его стабильности ;)
$ sudo minicom -s
+-----------------------------------------------------------------------+
| A - Serial Device : /dev/modem |
| B - Lockfile Location : /var/lock |
| C - Callin Program : |
| D - Callout Program : |
| E - Bps/Par/Bits : 115200 8N1 |
| F - Hardware Flow Control : No |
| G - Software Flow Control : No |
| |
| Change which setting? |
+-----------------------------------------------------------------------+
| Screen and keyboard |
| Save setup as dfl |
| Save setup as.. |
| Exit |
| Exit from Minicom |
+--------------------------+
Теперь можно начинать:
$ sudo minicom -D /dev/ttyUSB0 -b 115200
Bootbase Version: VTC_SPI1.26 | 2012/12/26 16:00:00
RAM: Size = 8192 Kbytes
Found SPI Flash 2MiB GD25Q16 at 0xbfc00000
SPI Flash Quad Enable
Turn off Quad Mode
RAS Version: ZXHN H108LV4.0.0a_ZRQ_MA
System ID: $2.12.162.0(G94.BY.2)3.20.19.0| 2014/03/21 20140321_v006 | 2014
Press any key to enter debug mode within 3 seconds.
..........
Чтобы просмотреть возможные команды:
$ ATHE
======= Debug Command Listing =======
AT just answer OK
ATHE print help
ATBAx change baudrate. 1:38.4k, 2:19.2k, 3:9.6k 4:57.6k 5:115.2k
ATENx,(y) set BootExtension Debug Flag (y=password)
ATSE show the seed of password generator
ATTI(h,m,s) change system time to hour:min:sec or show current time
ATDA(y,m,d) change system date to year/month/day or show current date
ATDS dump RAS stack
ATDT dump Boot Module Common Area
ATDUx,y dump memory contents from address x for length y
ATRBx display the 8-bit value of address x
ATRWx display the 16-bit value of address x
ATRLx display the 32-bit value of address x
ATGO(x) run program at addr x or boot router
ATGR boot router
ATGT run Hardware Test Program
ATRTw,x,y(,z) RAM test level w, from address x to y (z iterations)
ATSH dump manufacturer related data in ROM
ATDOx,y download from address x for length y to PC via XMODEM
ATTD download router configuration to PC via XMODEM
ATUR upload router firmware to flash ROM
< press any key to continue >
Эта прошивка содержит набор скрытых команд, очень полезных для нашего динамического анализа. Проблема в том, что мы не можем видеть регистры или устанавливать точки останова, но, надеюсь, с помощью этих скрытых команд мы сможем получить такие возможности. Чтобы увидеть и использовать их, нужно использовать ATEN. Однако эта команда требует пароль. Итак, что мы можем сделать сейчас? Давайте проведем реверс-инжиниринг прошивки, чтобы найти алгоритм генерации пароля.
(Статический анализ) Сначала посмотрим на файл прошивки:
$ binwalk ras
binwalk1
$ dd if=ras of=rom1.lzma bs=1 skip=85043 count=66696
$ dd if=ras of=rom2.lzma bs=1 skip=350259 count=3350556
$ lzma -d <rom1.lzma> rom1
$ lzma -d <rom2.lzma> rom2
Теперь посмотрим на сигнатуру в извлеченных файлах:
$ binwalk -Y rom1
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 MIPS executable code, 32/64-bit, big endian, at least 1250 valid instructions
string — отличный инструмент, чтобы получить представление о том, что такое двоичный файл или что он содержит. Посмотрим, сможем ли мы найти алгоритм пароля:
$ strings rom1 | grep -i aten
$ strings rom2 | grep -i aten
По-видимому, мы не можем его увидеть, потому что прошивка все еще сжата, а значит, мы должны извлечь ее из маршрутизатора с помощью режима отладки:
$ ATDO bfc00000, 1f0000
xmodem
Первое, что приходит на ум, — начать поиск таблицы диспетчеризации. Почему? Просто интуиция. Единственная альтернатива — длинная цепочка if-elif, чтобы проверить правильность введенного пользователем пароля. Вот что я получил:
ROM:800158A0 CmdTable: .word unk_80015C20 # DATA XREF: sub_8000E3D8+4Co
ROM:800158A0 # sub_8000E3D8+90o ...
ROM:800158A4 .word sub_8000E6D0
ROM:800158A8 .byte 0
ROM:800158A9 .byte 0
ROM:800158AA .byte 0
ROM:800158AB .byte 0
ROM:800158AC .word aJustAnswerOk # " just answer OK"
ROM:800158B0 .word aAthe # "ATHE"
ROM:800158B4 .word CMD_SHOW_HELP_ATHE
ROM:800158B8 .byte 0
ROM:800158B9 .byte 0
ROM:800158BA .byte 0
ROM:800158BB .byte 0
ROM:800158BC .word aPrintHelp # " print help"
ROM:800158C0 .word aAtba # "ATBA"
ROM:800158C4 .word CMD_ATBA
...
ROM:800158D0 .word aAten # "ATEN"
ROM:800158D4 .word CMD_ATEN
Помните, что слово MIPS состоит из 4 байт. Теперь посмотрим на CMD_ATEN:
ROM:8000FF84 lw $a0, 8($s0)
ROM:8000FF88 jal sub_80013654
ROM:8000FF8C li $a1, 0
ROM:8000FF90 jal passwd_generator
и далее: passwd_generator
ROM:80010A2C passwd_generator: # CODE XREF: CMD_ATEN+50p
ROM:80010A2C lui $t9, 0xA11F
ROM:80010A30 lw $v1, ptrDO_GTABLE
ROM:80010A34 lw $t8, dword_80017050
ROM:80010A38 lw $v1, 0x18($v1) # взять часть seed, сгенерированную командой ATSE
ROM:80010A3C lbu $t8, 0x6D($t8) # взять последний байт MAC-адреса
ROM:80010A40 sll $v1, 8 # $v1 = v1 << 8
ROM:80010A44 andi $t7, $t8, 7 # $t7 = t8 & 0x7
ROM:80010A48 li $t8, 0 # $t8 = 0
ROM:80010A4C srl $v1, 8 # $v1 = v1 >> 8
ROM:80010A50 li $t9, 0xA11F5AC6 # $t9 = MAGIC
ROM:80010A54 j loc_80010A68
ROM:80010A58 addu $t9, $v1, $t9 # $t9 = $v1 + $t9
ROM:80010A5C # ---------------------------------------------------------------------------
ROM:80010A5C
ROM:80010A5C loc_80010A5C: # CODE XREF: passwd_generator+40j
ROM:80010A5C sll $t9, 31 # $t9 = $t9 << 31
ROM:80010A60 or $t9, $t6, $t9 # $t9 = $t6 | $t9
ROM:80010A64 addiu $t8, 1 # $t8 = $t8 + 1
ROM:80010A68
ROM:80010A68 loc_80010A68: # CODE XREF: passwd_generator+28j
ROM:80010A68 sltu $t6, $t8, $t7 # $t6 = (t8 < t7? 1:0)
ROM:80010A6C bnez $t6, loc_80010A5C # переход, если $t6 != 0
ROM:80010A70 srl $t6, $t9, 1 # $t6 = $t9 >> 1
ROM:80010A74 jr $ra # все готово, выход
ROM:80010A78 xor $v0, $t9, $v1 # $v0 = $t9 ^ $v1
Что мы можем заключить:
Теперь напишем программу на C, которая делает то же самое, и скомпилируем её:
U32 passwd_generator(U32 seed, U8 last_mac_octet)
{
U32 b = seed & 0x00FFFFFF;
U32 r = ROR(b + 0xA11F5AC6, last_mac_octet & 7);
return r^b;
}
Теперь выполним ATSE, чтобы получить seed и использовать его (например, я получил 088521A78838):
$ ./gen_pass 088521A78838
Выполним волшебную команду, которую мы только что взломали :p
$ ATEN1, A12F5AC6
ATEN1, A12F5AC6
OK
ATHE
======= Debug Command Listing =======
AT just answer OK
ATHE print help
ATBAx change baudrate. 1:38.4k, 2:19.2k, 3:9.6k 4:57.6k 5:115.2k
ATENx,(y) set BootExtension Debug Flag (y=password)
ATSE show the seed of password generator
ATTI(h,m,s) change system time to hour:min:sec or show current time
ATDA(y,m,d) change system date to year/month/day or show current date
ATDS dump RAS stack
ATDT dump Boot Module Common Area
ATDUx,y dump memory contents from address x for length y
ATWBx,y write address x with 8-bit value y
ATWWx,y write address x with 16-bit value y
ATWLx,y write address x with 32-bit value y
ATRBx display the 8-bit value of address x
ATRWx display the 16-bit value of address x
ATRLx display the 32-bit value of address x
ATGO(x) run program at addr x or boot router
ATGR boot router
ATGT run Hardware Test Program
AT%Tx Enable Hardware Test Program at boot up
ATBTx block0 write enable (1=enable, other=disable)
< press any key to continue >
ATRTw,x,y(,z) RAM test level w, from address x to y (z iterations)
ATWEa(,b,c,d) write MAC addr, Country code, EngDbgFlag, FeatureBit to flash ROM
ATCUx write Country code to flash ROM
ATCB copy from FLASH ROM to working buffer
ATCL clear working buffer
ATSB save working buffer to FLASH ROM
ATBU dump manufacturer related data in working buffer
ATSH dump manufacturer related data in ROM
ATWMx set low 6 digits MAC address in working buffer
ATMHx set hight 6 digits MAC address in working buffer
ATBS show the bootbase seed of password generator
ATLBx xmodem upload bootbase,x is password
ATSMx set 6 digits MAC address in working buffer
ATCOx set country code in working buffer
ATFLx set EngDebugFlag in working buffer
ATSTx set ROMRAS address in working buffer
ATSYx set system type in working buffer
ATVDx set vendor name in working buffer
ATPNx set product name in working buffer
ATFEx,y,... set feature bits in working buffer
ATMP check & dump memMapTab
ATDOx,y download from address x for length y to PC via XMODEM
< press any key to continue >
ATTD download router configuration to PC via XMODEM
ATUPx,y upload to RAM address x for length y from PC via XMODEM
ATUR upload router firmware to flash ROM
ATDC hardware version check disable during uploading firmware
ATLC upload router configuration file to flash ROM
ATUXx(,y) xmodem upload from flash block x to y
ATERx,y erase flash rom from block x to y
ATWFx,y,z copy data from addr x to flash addr y, length z
ATXSx xmodem select: x=0: CRC mode(default); x=1: checksum mode
ATLD Upload Configuration File and Default ROM File to Flash
ATBR Reset to default Romfile
ATCD Convert Running ROM File to Default ROM File into Flash
OK
Наконец, мы получили целый новый набор команд, которые позволяют нам извлекать память.
$ ATMP
ROMIO image start at bfc30000
code version:
code start: 80008000
code length: 1A5D4E
memMapTab: 18 entries, start = bfc44000, checksum = 9770
$RAM Section:
0: BootExt(RAMBOOT), start=80030000, len=18000
1: HTPCode(RAMCODE), start=80048000, len=E0000
2: RasCode(RAMCODE), start=80048000, len=420000
$ROM Section:
3: BootBas(ROMIMG), start=bfc28000, len=4000
4: DbgArea(ROMIMG), start=bfc2c000, len=2000
5: RomDir2(ROMDIR), start=bfc2e000, len=2000
6: BootExt(ROMIMG), start=bfc30030, len=13FD0
7: MemMapT(ROMMAP), start=bfc44000, len=C00
8: HTPCode(ROMBIN), start=bfc44c00, len=8000
(Compressed)
Version: HTP_TC V 0.05, start: bfc44c30
Length: 10488, Checksum: CB32
Compressed Length: 41CF, Checksum: D5A5
9: termcap(ROMIMG), start=bfc4cc00, len=400
10: RomDefa(ROMIMG), start=bfc4d000, len=2000
11: LedDefi(ROMIMG), start=bfc4f000, len=400
12: LogoImg(ROMIMG), start=bfc4f400, len=2000
13: LogoImg2(ROMIMG), start=bfc51400, len=2000
14: StrImag(ROMIMG), start=bfc53400, len=32000
15: StrImag2(ROMIMG), start=bfc85400, len=32000
16: Rt11nE2p(ROMIMG), start=bfcb7400, len=400
17: RasCode(ROMBIN), start=bfcb7800, len=246C00
(Compressed)
Version: ADSL ATU-R, start: bfcb7830
Length: 321D2C, Checksum: 582D
Compressed Length: 11E54B, Checksum: B30B
$USER Section:
Msecs 128
Heap0 16 300 16
Heap1 32 64 4
Heap2 64 64 4
Heap3 128 160 4
Heap4 192 256 4
Heap5 256 80 4
Heap6 320 20 4
Heap7 384 4 2
Heap8 448 20 2
Heap9 512 34 2
Heap10 1024 52 4
Heap11 2048 20 2
Heap12 3172 4 2
Heap13 4096 2 2
Heap14 0 0
...
То, что мы только что узнали, поможет нам анализировать файлы ROM, которые мы извлекли ранее.
code start: 80008000
code length: 1A5D4E
Теперь мы можем установить начальный адрес ROM и адрес загрузки (Loading address) на 0x80008000 после извлечения нового файла ROM с помощью:
$ ATDO 80008000, 1A5D4E
Мы знаем, что ATGR загружает маршрутизатор, поэтому мы могли бы отследить его, чтобы найти инструкции, которые передают выполнение второй части прошивки.
atgr1
ROM:80011E8C loc_80011E8C: # CODE XREF: LoadAndRunImage+D8j
ROM:80011E8C jal sub_80009B24
ROM:80011E90 li $a0, 0x1F4
ROM:80011E94
ROM:80011E94 execute_image: # execute image
ROM:80011E94 jalr $s0 # jump and link to address in $s0
ROM:80011E98 nop
Теперь нужно понять, какой адрес хранится в $s0? Очевидно, что мы все еще не можем установить точку останова, мы не можем просматривать регистры, поэтому нам нужно его извлечь с помощью некоторого трюка. К счастью, мы можем читать и писать в память. Взгляните на следующую команду:
ATWL 80011E94, ae30001c
ATGR
Судя по всему, эта команда заменяет инструкцию по адресу 0x80011E94 на ae30001c (байтовое представление инструкции MIPS sw $s0, 0x1C($s1)). Перезаписав исходную jalr $s0 на sw $s0, 0x1C($s1), мы заставили программу сохранить содержимое регистра $s0 в адрес памяти 0x8001FF1C. Теперь вторая часть прошивки не будет выполнена, вместо этого появится сообщение "ERROR", и у нас все еще будет доступ к консоли первого этапа. Ура! Итак, давайте посмотрим, что было сохранено по адресу 0x8001FF1C.
ATRL 8001FF1C
8001FF1C: 80020000
Попался! ... Используя 0x80020000, мы можем извлечь и должным образом проанализировать вторую часть прошивки.
Продолжение следует ...