1. 前言
D-Link_GORTAC750多CVE漏洞的复现,东西写的比较拉跨,凑合看吧。
2. 环境搭建
FirmAE一键搭建
nmap扫描,发现upnp端口为49152
固件下载链接
1 | https://media.dlink.eu/support/products/go/go-rt-ac750/driver_software/go-rt-ac750_fw_reva_1-01b03_eu_multi_20141017.zip |
复现漏洞:
CVE-2023-34800
CVE-2023-26822
CVE-2022-37057
CVE-2022-37056
CVE-2022-36523
3. 背景知识
3.1 CGI(Common Gateway Interface)通用网关接口
CGI规定了Web服务器调用CGI程序的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互,即CGI程序接受Web浏览器发送给Web服务器的信息并进行处理,将处理后的结果返回给Web服务器。组成CGI通信系统的是两部分:一部分是html页面,用于在浏览器上显示;另一部分则是运行在服务器上的CGI程序。
通常情况下,服务器和CGI程序在Web环境变量的协作下,通过标准输入(stdin)和标准输出(stdout)来进行数据传递。以Go-RT-AC750的Web服务器工作流程为例:
- 服务器接受到浏览器传来的URL,识别URL中指定的脚本,如xx.php或xx.cgi并将其交给cgibin解析处理。
- 服务为CGI程序(cgibin)执行做准备,比如准备环境变量和相关参数。
- CGI程序(cgibin)读取标准输入和相关环境变量,执行相应处理,处理完后将结果由标准输出返回到服务器。
- 服务器将接收到的处理结果返回浏览器。
CGI程序继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在CGI程序结束时销毁。当CGI程序被HTTP服务器调用时,它的环境变量就会增加一些和HTTP服务相关的环境变量。下面是一些常见的和HTTP相关的环境变量(CGI程序使用getenv()函数获取环境变量,例如getenv(“CONTENT_TYPE”):
变量 | 含义 |
---|---|
REQUEST_METHOD | 服务器与CGI程序之间的信息传输方式 |
QUERY_STRING | 采用GET时所传输的信息 |
CONTENT_LENGTH | 传来的有效信息长度 |
CONTENT_TYPE | 传来的信息的MIME类型 |
SERVER_NAME | 服务器的IP或名字 |
SERVER_PORT | 服务器的端口号 |
SERVER_ID | 服务ID |
REMOTE_ADDR | 客户机的主机名 |
REMOTE_HOST | 客户机的IP地址 |
3.2 UPnP(Universal Plug and Play)通用即插即用
UPnP时由微软提出的一种通用即插即用技术,后续联合英特尔等多家科技公司共同制定了UPnP标准。UPnP主要是为了实现在“零配置”的前提下在互联网设备间能自动连接和协同工作。UPnP的协议栈结构图如下:
UPnP协议体系结构中主要协议和规范包括:
- SSDP(Simple Service Discovery Protocol)简单服务发现协议,用于发现网络中的UPnP设备。
- GENA(Generic Event Notification Architecture)通用事件通知结构,用于及时通知状态变化。
- SOAP(Simple Object Access Protocol),简单对象访问协议,用于保证UPnP设备具有互操作能力。
- XML(Extensible Markup Language)可扩展标记语言,对设备和服务进行统一的描述。
当加入一个新的UPnP设备时,工作流程如下:
- 设备加入网络后通过设备寻址(addressing)就可以自动获得IP地址;
- 通过设备发现(discover)控制点就可知道网络上存在哪些设备;
- 通过设备描述(description)控制点就可知道设备详细信息以及设备提供哪些服务;
- 通过设备控制(control)控制点就可以使用设备的服务;
- 通过设备事件(event)就可以将其状态变化及时告诉给订阅的控制点;
- 通过设备展示(presentation)控制点可以用浏览器查看设备状态和控制设备。
通过上述六个步骤,UPnP设备可以做到在“零配置”的前提下提供联网设备之间的自动发现、自动声明、“直接”信息交换和互操作等功能,真正实现“设备即插即用”。
4. 漏洞复现
4.1 CVE-2023-34800
4.1.1 漏洞分析
查找漏洞详情
知道了漏洞和genacgi_main
函数有关,那么查找相关字符串,匹配到相关文件htdocs/cgibin
IDA分析该文件,直接定位到函数genacgi_main
处
上图中在cgibin_main
函数中判断是否为gena.cgi
genacgi_main
函数的功能时:检查HTTP请求方法和判断URI中是否有?service=
,若HTTP请求方法为SUBSCRIBE
或UNSUBSCRIBE
则调用对应的函数处理。当REQUEST_METHOD
为SUBSCRIBE
时,获取一些环境变量并使用sprintf
函数拼接成字符串传入到xmldbc_ephp
函数中处理:
xmldbc_ephp
函数将拼接的subscribe_string
通过/var/run/xmldb_sock
传入到/htdocs/upnp/run.NOTIFY.php
文件中进行处理并返回处理结果到服务器。
subscrib_string
的内容形式为:
1 | 假设传入:SUBSCRIBE URL ?service=service_xx |
查看/htdocs/upnp/run.NOTIFY.php
文件内容
查找文件中涉及到的GENA_subscribe_new
函数
查看gena.php
内容
综上可知,漏洞点在fwrite(a, $shell_file, "rm -f ".$shell_file."\n");
代码中的目的是为了执行rm -f shell_file
命令删除shell_file
文件,但shell_file
可通过SUBSCRIBE
传入的服务参数进行控制并且全程没有任何对服务参数的检查,从而可实现命令注入。
4.1.2 POC
该漏洞涉及到的是UPnP的GENA(通用事件通知结构)相关内容,当设备服务状态发生变化时,会通过event通知控制点。控制点能收到通知的前提是先订阅(SUBSCRIBE)该服务的指定event。订阅特定服务的事件的方法是:发送订阅消息到该服务的事件URL。通过分析可知,此漏洞的触发条件是要路由器发送UPnP订阅服务的请求。根据UPnP官方文档可知订阅请求格式如下:
结合UPnP文档和/var/run/httpd.conf
文件内容,可知要构造的subscriber的请求头如下:
1 | SUBSCRIBE /gena.cgi?service=;telnetd -p 7080 HTTP/1.1 |
POC脚本如下,执行后成功getshell
1 | from socket import * |
4.2 CVE-2023-26822
4.2.1 漏洞分析
查找漏洞详情
根据漏洞披露的信息可知漏洞点和service参数
以及soapcgi_main
有关,在文件系统中查找soapcgi_main
并定位到所在文件cgibin
,将其拿到IDA中逆向分析,通过函数名查找,定位到soapcgi_main
函数,调用该函数的代码如下:
soapcgi_main
中关键代码如下:
这段代码是在获取与请求相关的环境变量,可获得的信息有:
- REQUEST_METHOD:POST
- CONTEXT_TYPE:text/xml
- REQUEST_URI:含?service=
- HTTP_SOAPACTION:含有””,且””中含有#
综上分析可知,漏洞出现的原因是POST的URI中?service=
后面的内容可由输入控制,全程没有对该输入进行检查,直接sprintf
后由system
函数执行。
4.2.2 POC
此漏洞涉及到的是UPnP的SOAP(简单对象访问协议)相关内容,SOAP主要是用于保证UPnP设备具有互操作能力。控制点可以调用UPnP设备上的服务,并接收返回结果。根据UPnP官方文档,要调用UPnP设备上的服务,控制点必须以POST方法发送以下格式的请求:
由上面的分析可知要构造的POST请求头如下:
1 | POST /soap.cgi?service=;telnetd -p 7080 HTTP/1.1 |
POC脚本如下,执行后成功getshell
1 | from socket import * |
4.3 CVE-2022-37057
4.3.1 漏洞分析
查找漏洞详情
根据漏洞披露的信息可知与ssdpcgi_main
函数以及cgibin
文件有关,IDA分析该文件,直接搜索ssdpcgi_main
函数,调用该函数的代码为:
根据前面分析的漏洞可知,这次漏洞请求URL中的文件是ssdpcgi
。ssdpcgi_main
函数中漏洞点关键代码如下:
根据上图代码可知,实现命令注入需要的环境变量如下:
- HTTP_ST:uuid;
- REMOTE_ADDR
- REMOTE_PORT
- SERVER_ID
这些数据被传入lxmldbc_system
函数,在该函数中直接拼接执行,没有任何检查。这几个环境变量中只有HTTP_ST
是需要请求头设定的,即HTTP_ST
是可控制的输入,因此HTTP_ST
的值即为漏洞点。
4.3.2 POC
此漏洞涉及到的是UPnP的SSDP(简单服务发现协议)相关内容,该协议主要是用于发现网络中的UPnP设备。控制点(用户操作的HTTP客户端)可通过使用简单服务发现协议,根据自己的需要在网络中查询能够提供特定服务的设备。相应的设备(也就是该路由器)向控制点发出回应,声明自己的存在及能提供的服务。该协议在HTTP之下使用的是UDP。控制点需要用以下格式发送请求:
综上分析,结合UPnP文档和/var/run/httpd.conf
文件内容可知,构造的请求如下:
1 | M-SEARCH * HTTP/1.1 |
POC脚本如下,执行后成功getshell
1 | from socket import * |
4.4 CVE-2022-37056
4.4.1 漏洞分析
查看漏洞详情
根据漏洞披露信息可知,和hnap_main
函数以及cgibin
文件有关,IDA分析cgibin
文件,直接搜索hnap_main
函数,调用该函数的代码为:
hnap_main
函数中关键代码如下:
代码中没有对HTTP_SOAPACTION
的值进行检查,直接将其内容中"/"
后的内容拼接到buffer
中执行。要想HTTP_SOAPACTION
的值被作为注入点执行,请求方式不能为POST
,可设定为GET
,URL为/HNAP1/
。
4.4.2 POC
POC构造如下,执行后成功getshell
1 | from socket import * |
4.5 CVE-2022-36523
4.5.1 漏洞分析
查看漏洞详情
根据披露的信息,可知此漏洞和/htdocs/upnpinc/gena.php
文件有关。查看该文件内容:
查看漏洞点发现和CVE-2023-34800最终产生漏洞点的位置和原因一样,不做具体分析。
4.5.2 POC
直接上POC测试,和CVE-2023-34800的POC一样
1 | from socket import * |
5. 参考链接
1 | D-Link Go-RT-AC750命令注入漏洞复现 |
发布时间: 2023-08-23
最后更新: 2023-09-15
本文标题: D-Link_GORTAC750多漏洞复现
本文链接: https://foxcookie.github.io/2023/08/23/D-Link_GORTAC750多漏洞复现/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!