7.1.6 CVE-2017-9430 DNSTracer 栈溢出漏洞
漏洞描述
DNSTracer 是一个用来跟踪 DNS 解析过程的应用程序。DNSTracer 1.9 及之前的版本中存在栈缓冲区溢出漏洞。攻击者可借助带有较长参数的命令行利用该漏洞造成拒绝服务攻击。
漏洞复现
操作系统
Ubuntu 12.04
体系结构:32 位
调试器
gdb-peda
版本号:7.4
漏洞软件
DNSTracer
版本号:1.9
首先编译安装 DNSTracer:
$ wget http://www.mavetju.org/download/dnstracer-1.9.tar.gz
$ tar zxvf dnstracer-1.9.tar.gz
$ cd dnstracer-1.9
$ ./confugure
$ make && sudo make install传入一段超长的字符串作为参数即可触发栈溢出:
漏洞分析
这个漏洞非常简单也非常典型,发生原因是在把参数 argv[0] 复制到数组 argv0 的时候没有做长度检查,如果大于 1024 字节,就会导致栈溢出:
补丁
要修这个漏洞的话,在调用 strcpy() 前加上对参数长度的检查就可以了:
Exploit
首先修改 Makefile,关掉栈保护,同时避免 gcc 使用安全函数 __strcpy_chk() 替换 strcpy(),修改编译选项如下:
最后关掉 ASLR:
因为漏洞发生在 main 函数中,堆栈的布置比起在子函数里也要复杂一些。大体过程和前面写过的一篇 wget 溢出漏洞差不多,但那一篇是 64 位程序,所以这里选择展示一下 32 位程序。
在 gdb 里进行调试,利用 pattern 确定溢出位置,1060 字节就足够了:
所以返回地址位于栈偏移 1049+4=1053 的地方。
在下面几个地方下断点,并根据偏移调整我们的输入:
所以栈位于 0xbfffeb3f,执行这一行代码即可将 0xbffff174 处的 "A" 字符串复制到 argv0 数组中:
同时字符串 "BBBB" 覆盖了返回地址。所以我们用栈地址 0xbfffeb3f 替换掉 "BBBB":
然后就可以在栈上布置 shellcode 了,这一段 shellcode 长度为 23 字节,前面使用 nop 指令填充:
根据计算,shellcode 位于 0xbfffef45。
然而当我们执行这个程序的时候,发生了错误:
错误发生在 0xbfffef55,而 shellcode 位于 0xbfffef45,两者相差 16 字节:
所以这里采用的解决办法是去掉前面的 16 个 nop,将其加到 shellcode 后面。
成功获得 shell。
那如果我们开启了 ASLR 怎么办呢,一种常用的方法是利用指令 jmp esp 覆盖返回地址,这将使程序在返回地址的地方继续执行,从而执行跟在后面的 shellcode。利用 objdump 就可以找到这样的指令:
exp 如下:
Bingo!!!
参考资料
Last updated
Was this helpful?