OneShell

I fight for a brighter tomorrow

0%

CVE-2016-11021 dlink DCS-930L远程代码执行

D-Link DCS-930L 的一个认证远程代码执行漏洞。漏洞存在于固件版本 2.0.1 且在版本 2.12 被修复。漏洞发生在路由器的后端服务器 alphapd 中,允许经过登录认证的用户通过向 /setSystemCommand 发送 POST 请求包执行命令。

漏洞分析

通过分析 exploit.db 上的 exp,根据关键字符串 SystemCommand 可以大概得到如下的函数调用关系:

函数 sub_421D30 根据 uri 中的 /setSystemCommand 调用函数 sub_41E264。

1
2
3
4
5
int sub_421D30()
...
sub_409D24("setSystemCommand", sub_41E264);
...
}

在函数 sub_41E264 中,通过调用函数 sub_409340 从 POST 数据中解析出 SystemCommand 字段的值作为执行命令,然后传递到函数 sub_438A10 执行传入的命令。

1
2
3
4
5
6
7
8
9
int __fastcall sub_41E264(int a1)
{
const char *v3; // $s0
...
v3 = (const char *)sub_409340(a1, (int)"SystemCommand", (int)"");
sub_400320(1, "DoCommaon=%s\n", v3); // 日志记录
sub_438A10((int)v3); // 命令执行
return sub_405528(a1, 0, (int)"ReplySuccessPage", (int)"ReplyErrorPage");
}

那么真正执行命令的函数是 sub_438A10,通过这个函数传入的参数也大概可以猜到这是用来命令执行的。

1
2
3
4
5
6
int __fastcall sub_438A10(int a1)
{
...
sub_43C0C0((int)"/bin/sh", (int)"sh", "-c", a1, 0);// 这个函数应该是执行命令注入
...
}

再理清一下函数调用链,就是:

1
start -> sub_400B4C -> sub_409DE4 -> sub_421D30 -> sub_41E264 -> sub_438A10 -> sub_43C0C0
  • start:启动函数
  • sub_400B4C:初始化操作,例如检查 nvram,设置 HTTP 服务端口等
  • sub_409DE4:调用 sub_421D30
  • sub_421D30:根据访问 uri 的不同设置响应的回调函数
  • sub_41E264:解析 POST 包中的 SystemCommand 字段获取需要执行的命令
  • sub_438A10:调用命令执行函数 sub_43C0C0
  • sub_43C0C0:命令执行

通过遍历固件中的所有 htm 文件,搜索字符串 setSystemCommand,可以定位到存在漏洞的页面

1
2
3
# kali @ kali in ~/firmware/dcs-930l/2.01.03/cpio-root [22:10:04]
$ find . -name "*htm" | xargs grep "setSystemCommand"
./etc_ro/web/docmd.htm:<FORM ACTION="/setSystemCommand" METHOD="POST">

环境搭建

使用 qemu-mipsel-static

解决报错:cannot open pid file

打开固件根目录,

1
sudo chroot . ./qemu-mipsel-static ./bin/alphapd

在 IDA 中搜索报错字符串,因为没有 /var/run/alphapd.pid 文件的存在,在根目录中创建该文件

1
2
mkdir ./var/run
touch ./var/run/alphapd.pid

解决报错:waiting for nvram_daemon

在 IDA 中搜索报错字符串,同样因为没有 /var/run/nvramd.pid 文件,在固件根目录中创建

1
touch ./var/run/nvramd.pid

创建需要的设备

1
2
3
touch ./dev/nvram
touch ./dev/urandom
touch ./dev/random

解决报错:Can’t get lan ip from sysinfo! 和 failed to convert to binary ip dataalphapd: Shutdown!

这个报错是启动 http 服务的关键,需要对程序进行 patch,patch 的地方如下:

undifined

然后可以启动 http 服务了,但是依旧会报错。第一个报错应该是 qemu 没有实现对应的系统调用,第二个可以不用管,如果只是启动 http 而不需要 https 的话,可以忽略。

1
2
ioctl: Function not implemented
failed to read certificates in websSSLOpen

漏洞利用

此处无需太多的调试,直接通过定位的漏洞页面 0.0.0.0:80/docmd.htm,看能否命令执行

成功命令执行
undifined
undifined

小结

漏洞比较简单,可以想想如何进行的漏洞挖掘工作。

参考链接