dir-815 栈溢出漏洞复现
本文最后更新于:2023年7月2日 晚上
dir-815 栈溢出漏洞复现
CNVD-2013-11625是Dir-815路由器在hedwig.cgi
实现中会存在缓冲区溢出的漏洞。漏洞不正确过滤用户提交的参数数据,允许远程攻击者利用漏洞提交特制请求触发缓冲区溢出,可使应用程序停止响应,造成拒绝服务攻击。
漏洞分析
固件提取
使用 binwalk -Me DIR-815A1_FW101SSB03.bin
解压固件。
根据官方提示,漏洞存在于hedwig.cgi
中,直接使用find ./ -name '*.cgi' 2>/dev/null
搜索。
事实上,该固件cgi都是实现在/htdocs/cgibin
中的。我们对cgibin
进行分析即可。
程序分析
main
在IDA中打开,首先分析main函数。
可以看到,通过比较第一个参数是否为hedwig.cig
,从而调用关键函数hedwigcgi_main
函数。
hedwigcgi
首先,获取环境变量request_methed
。判断是否为POST请求,若不是,则直接失败返回。
接下来,会调用cgibin_parse_request
函数进行解析。
cgibin_parse_request
首先,获取环境变量CONTENT_TYPE
与CONTENT_LENGTH
之后,获取环境变量REQUEST_URI
,并使用**?**对该参数进行分割,之后调用sub_402b40
函数对后续进行分割。
sub_402b40
对后续参数继续进行分割。若遇到**&,则递归调用sub_402b40
继续分割参数;若遇到=,就添加到变量v14中。也就是对URI**进行更细致的分割。
我们继续向下分析cgibin_parse_request
函数。
获取环境变量CONTENT_TYPE
,然后与**application/**进行比较,之后调用数组off_42c014
中的函数。该数组在data段,查看该数组内容。
大致就是,根据CONTENT_TYPE
类型,调用不同的函数进行初始化。
这里也可以得到,我们的参数类型大致为 CONTENT_TYPE/x-www-form-urlencoded
。
我们继续看hedwigcgi
函数。
之后,会打开文件,并读入文件到v26中,貌似没什么用。
之后调用sess_get_uid
函数,这个函数是溢出的一个关键函数。
若是string足够大,即可溢出v27[1024]数组了。
sess_get_uid
首先,获取环境变量HTTP_COOKIE
,然后对cookie进行处理。
逐个拆分获取cookie字段,直到获取uid字段,并返回该字段内容。注意,这个字段是我们可控的。
继续分析hedwigcgi
函数。
我们需要绕过如下两个判断,其实这也不需要我们刻意绕过,正常机器下都是可以通过的。
之后,对上述**/var/tmp/temp.xml**字段进行处理,这里也没有判断逻辑,就是顺序执行。若是真机,则不需要处理。否则,需要直接创建一个新的空白xml文件即可。
上述执行都未对v4进行处理,所以v4还是uid字段内容。这里就是真正的栈溢出。
至此,分析完毕。下面我们对该漏洞进行验证。
漏洞验证
对上述漏洞进行验证。验证脚本大致如下,这里我是直接参考winmt师傅的验证脚本,主要是太菜了。
可以看到,我们触发了一个段错误。但是为了避免是其他原因引起的,我们添加-g 4321
进行动态调试。
这里我们确实覆盖了返回地址。且溢出长度为1009。
漏洞复现
路由器一般都是没有开启地址随机化的,我们可以直接获取到libc基地址,从而进行任意函数调用。
这里使用vmmap查看libc基址,可以看到为libc_base = 0x7f738000。
接着,就是mips架构的栈溢出了。
若是对mips架构不太了解的,大致可以看看笔者之前的博客。
mips架构的程序大都未开启NX保护,栈可以直接执行shellcode。mips架构的栈溢出一般都有一条稳定的rop链。大致是sleep(1) + shellcode
。
这里rop链子的构造的原理可以参考笔者另一篇博客。
最终构造的wp如下:
1 |
|
成功获取shell。
对上述payload做一个简单的解释。
- 测试得到的offset=1009,但是payload使用的offset=0x3cd?
我们的目的不是仅仅覆盖$ra,包括其他$s?参数,以便于我们更好的控制程序执行流程
- 第二段payload是从0x28开始的,其目的在于控制$ra与$r4寄存器,以便在
sleep(1)
执行后依然可以控制程序流程。
参考文章