借鉴复现笔记:
- cve-2018-17066复现 | 1uckyc's blog
- DIR-816 模拟执行与命令注入漏洞分析 - IOTsec-Zone
- VulInfo/D-Link/DIR-816/cmd_injection_0/README.md at master · PAGalaxyLab/VulInfo (github.com)
- 物联网终端安全入门与实践之玩转物联网固件(中) - SecPulse.COM | 安全脉搏
- Debugging D-Link: Emulating firmware and hacking hardware (greynoise.io)
CVE-2018-17066漏洞概述:在该路由的前端页面中存在时间设置页面,但是我们手动输入的时间并没有被过滤,就会直接将数据传输到后端处理,经过一段函数调用后会将参数传入system作为参数从而实现命令注入!(任意命令执行)
环境准备:kali2023因为自带bp不用安装了!!!
利用链:
前端发送post请求将时间数据发送给后端-》websOpenListen监听请求-》收到请求后使用sub_4572A4函数进行时间设置-》由于未进行任何过滤导致doSystem("date -s \"%s\"", Var);
会直接将传入的参数作为system的参数-》从而实现命令注入!
D-Link固件提取
固件下载地址:D-Link Technical Support (dlink.com.cn)
下载后就可以检查一下文件的属性了:
文件属性:U-Boot: OS Kernel Image("Linux Kernel Image")[Linux,MIPS,lzma]
直接到Ubuntu里面提取一下固件文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ~ / Pwn_CVE / CVE - 2018 - 17066 $ binwalk - Me DIR - 816.img
DECIMAL HEXADECIMAL DESCRIPTION
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4280396 0x41504C Linux kernel version 2.6 . 36
4280496 0x4150B0 CRC32 polynomial table, little endian
4327552 0x420880 CRC32 polynomial table, little endian
4348800 0x425B80 SHA256 hash constants, little endian
4350160 0x4260D0 AES Inverse S - Box
4350928 0x4263D0 AES S - Box
4642928 0x46D870 xz compressed data
4675640 0x475838 Unix path: / var / run / goahead.pid
4764032 0x48B180 Unix path: / etc / Wireless / RT2860AP / RT2860AP.dat
4789596 0x49155C XML document, version: "1.0"
4819148 0x4988CC HTML document header
4819285 0x498955 HTML document footer
4839035 0x49D67B Neighborly text, "neighbor %.2x%.2x.%pM lostd_delay_timer"
5018336 0x4C92E0 CRC32 polynomial table, little endian
5021872 0x4CA0B0 AES S - Box
|
·
binwalk 是一种常用于数字取证和二进制分析的工具。你提供的命令 binwalk -Me DIR-816.img 是用来执行 binwalk 的特定操作的。下面解释一下命令中每个部分的含义:
- binwalk:这是命令本身,表示你想要使用 binwalk 工具。
- -Me:这些是修改 binwalk 行为的选项或标志。具体来说,-M 告诉 binwalk 在发现文件时自动提取它们,-e 告诉它递归地从其他文件中提取文件。
- DIR-816.img :这是你想要 binwalk 分析并从中提取文件的文件或目录的名称。
提取出来的文件:
SquashFS 是一套基于Linux内核使用的压缩只读文件系统。该文件系统能够压缩系统内的文档,inode以及目录,文件最大支持2^64字节,简介:squashfs介绍和安装_unsquashfs-CSDN博客
squashfs-root就是我们需要找到的根目录!
D-Link路由模拟执行
我们主要分析的是goahead:
查看一下goahead的属性和链接:
1 2 3 | brinmon@brinmon - virtual - machine:
~ / Pwn_CVE / CVE - 2018 - 17066 / _DIR - 816.img .extracted / squashfs - root$ file . / bin / goahead
. / bin / goahead: ELF 32 - bit LSB executable, MIPS, MIPS - II version 1 (SYSV), dynamically linked, interpreter / lib / ld - uClibc.so. 0 , stripped
|
两种启动方法:
1 2 3 4 5 6 7 8 | 1. * * 动态版本 (`qemu - mipsel`) * * :适合在有所有必要共享库的系统上使用,可以节省磁盘空间。
注:通过 - L设置根目录
sudo qemu - mipsel - L . / . / bin / goahead
2. - * * 静态版本 (`qemu - mipsel - static`) * * :由于不依赖外部库,它更便于分发和在各种环境中运行。
注:chroot . 设置根目录
cp $(which qemu - mipsel - static) . /
sudo chroot . . / qemu - mipsel - static . / bin / goahead
|
goahead.pid未找到报错
运行后发现报错!
在ida找到该字符串:
分析该文件的报错原因是因为没有"/var/run/goahead.pid"
解决方案手动创建一个:
1 2 3 4 | 注:删除文件夹:rm - rf . / var / run
mkdir . / var / run
touch . / var / run / goahead.pid
|
var/run/nvramd.pid未找到报错
完成第一个报错修复后重新仿真程序,程序继续执行时出现错误:"waiting for nvram_daemon",如下图所示。
根据ida继续找到字符串,发现不可以使用交叉引用,大概率是因为进行了混淆!
根据下面的字符串"goahead.c"的交叉引用找到了目标位置!还可以通过动态调试来定位!
分析发现原因,这两个字符串是通过偏移来定位的,还发现个问题这里的fopen的第二个参数是再调用fopen后才传入的不理解:
1 2 3 4 5 6 7 8 | li $s3, dword_480000
li $s2, aEttimeoutDocum
...
loc_45C72C:
la $t9, fopen
addiu $a0, $s3, - 0x3124
jalr $t9 ; fopen
addiu $a1, $s2, 0x4CDC
|
这里就算IDA的伪代码了!
解决方案继续手动创建文件。
1 | touch . / var / run / nvramd.pid
|
缺少二进制ip数据报错
继续运行发现有很多东西不存在继续创建,再看下最主要的报错是:
initWebs: failed to convert to binary ip data,缺少二进制ip数据
根据字符串锁定位置:
报错原因:nvram_bufget函数无法读取lan_ipaddr,而nvram_bufget是从/dev/nvram中读取数据。
1 2 3 4 | 知识的拓展:
在Linux操作系统中,硬件设备也被看做文件来处理, / dev / nvram是非易失性存储器nvram设备_(具体概念在 5.3 . 2 章节进行介绍)_。
` / dev / nvram` 提供了一种方便的方式来访问和管理系统的非易失性存储器,可以用于存储系统配置、启动参数和硬件设置等重要信息,是其他硬件用来存储信息的地方
|
这里的解决方案:
- RT-AX55环境搭建 | ioo0s's blog
- pr0v3rbs/FirmAE:面向物联网固件的大规模仿真,用于动态分析 --- pr0v3rbs/FirmAE: Towards Large-Scale Emulation of IoT Firmware for Dynamic Analysis (github.com)
还有其他解决方案:
- 解劫持动态链接库
- patch 原程序来实现
a. 使用LD_PRELOAD方式劫持动态链接库实现nvram设备的模拟(实现失败原因未知)
由于报错函数是nvram_bufget所以我们只需要劫持这个函数所在的so文件我们就可以实现正常的ip地址获取了!
FirmAE提供的libnvram库源码:FirmAE/sources/libnvram/config.h at master · pr0v3rbs/FirmAE (github.com)
为了适配环境做一些相应的修改:
- 修改config.h的挂载路径:
1 2 3 4 | / / Mount point of the base NVRAM implementation.
/ / Location of NVRAM override values that are copied into the base NVRAM implementation.
|
- 修改config.h中启动web页面的ip地址
1 2 | ENTRY( "lan_ipaddr" , nvram_set, "192.168.126.130" ) \
ENTRY( "lan_bipaddr" , nvram_set, "192.168.126.255" ) \
|
接下来成功编译:
1 2 | mipsel - linux - gnu - gcc - c - O2 - fPIC - Wall nvram.c - o nvram.o
mipsel - linux - gnu - gcc - shared - nostdlib nvram.o - o libnvram.so
|
经过上面的步骤发现网卡不对,在ubnutu上网卡为ens33,还是切换到kali进行实现步骤如上:
1 2 | ┌──(root㉿kali) - [ / home / … / Pwn_CVE / CVE - 2018 - 17066 / _DIR - 816A2_FWv1 . 10CNB05_R1B011D88210 .img.extracted / squashfs - root]
└─
|
b.patch 原程序来实现
先ida动态调试一下手动修改值:
1 2 | ┌──(root㉿kali) - [ / home / … / Pwn_CVE / CVE - 2018 - 17066 / _DIR - 816A2_FWv1 . 10CNB05_R1B011D88210 .img.extracted / squashfs - root]
└─
|
IDA动态调试附加上这个端口!
修改地址:0x45CDD4 (将v0的赋值修改为0,就不会报错了)
成功运行之后就会出现登录页面,在浏览器访问ip地址后:
1 | http: / / 192.168 . 126.131 / dir_login.asp /
|
成功!!
开始寻找存在漏洞的页面
在这里需要绕过路由的账号和密码!
有两种方式可以绕过:
1.修改前端的asp页面的js代码
1 | / home / kali / Pwn_CVE / CVE - 2018 - 17066 / _DIR - 816A2_FWv1 . 10CNB05_R1B011D88210 .img.extracted / squashfs - root / etc_ro / web / dir_login.asp
|
找到这个页面并且修改里面的前端检验逻辑,将非空检查这些代码去除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function onlogin() {
return true ;
}
|
这样就可以成功绕过!将账号密码都置空,从而绕过strcmp的对比!!
2.动态调试修改strcmp的比对结果
成功锁定函数:
在该位置下断点并且修改v0为0
3.登录界面前后端通信原理
- 前端js代码通过submit提交post请求将参数传给后端来处理
- 后端通过websOpenListen函数持续监听前端发送过来的post请求并进行处理
- 成功处理后,后端会发送新的页面信息给前端,实现前端页面跳转!
成功绕过登录验证
成功登入之后就可以访问访问:
1 | http: / / 192.168 . 126.131 / d_wizard_step1_start.asp
|
由于kali2023自带bp,所以可以直接使用bp拦截实现命令注入:
将ls
写入date数据段,实现命令注入成功!
最后总结分析
通过拼接字符串将ls嵌入命令中实现任意命令执行!
linux知识点:
反引号用于命令替换,即在反引号内的命令会先执行,其输出结果会替换反引号的内容。现代脚本中,推荐使用 $()
形式,因为它更易读且支持嵌套。
┌──(kali㉿kali)-[~/tools/BurpSuite V2024.3.1.2]
└─$ date -s "`ls`2024-6-05 01:58:39"
date: 无效的日期 "清除许可证和数据.bat\n使用说明.txt\nBurpSuite\nCNBurp(无CMD窗口).VBS\nCN-JRE Burp.bat\nENBurp(无CMD窗口).VBS\nEN-JRE Burp.bat\njre\nLinux\nStart.bat\nStart.VBS2024-6-05 01:58:39"
┌──(kali㉿kali)-[~/tools/BurpSuite V2024.3.1.2]
└─$ "`ls`"
清除许可证和数据.bat
使用说明.txt
BurpSuite
CNBurp(无CMD窗口).VBS
CN-JRE Burp.bat
ENBurp(无CMD窗口).VBS
EN-JRE Burp.bat
jre
Linux
Start.bat
Start.VBS:未找到命令
利用链:
前端发送post请求将时间数据发送给后端-》websOpenListen监听请求-》收到请求后使用sub_4572A4函数进行时间设置-》由于未进行任何过滤导致doSystem("date -s \"%s\"", Var);
会直接将传入的参数作为system的参数-》从而实现命令注入!
最后于 4分钟前
被Loserme编辑
,原因: mkdown文本有问题