前言
在进行IOT安全领域的学习和实践中,经典漏洞的复现是必不可少的一环。本文将介绍一个经典漏洞,涉及到Binwalk、firmware-mod-kit、FirmAE等工具的使用,以及对DIR-815路由器中多次溢出漏洞的复现过程。
固件下载地址:https://legacyfiles.us.dlink.com/DIR-815/REVA/FIRMWARE/
这个漏洞属于经典范畴,很多人选择通过此漏洞进行IOT安全入门的学习与实践。我们将一起回顾这个经典漏洞,踏入IOT安全的世界,并对DIR-815路由器中的多次溢出漏洞进行复现。
根据报告显示,此漏洞主要源于COOKIE长度未被限制,导致COOKIE长度过长时引发栈溢出问题。在本文中,我们将提供exp和poc,需要注意的是,在我的本地环境中,如果使用973作为偏移量,则调试无法成功连接,但不进行调试则可以成功连接。然而,如果使用1007作为偏移量,则调试可以成功连接,但不进行调试则无法成功连接。这种情况可能与仿真环境相关,欢迎大家积极尝试并探索。
工具安装
我的环境是
Ubuntu 22.04.4 LTS x86_64
Binwalk
我们要安装这个工具用来给FirmAE调用:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
firmware-mod-kit
首先安装依赖:
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
然后进行安装:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
可以进入https://github.com/mirror/firmware-mod-kit查看详细使用方法,本文不赘述。
FirmAE
我们需要安装FirmAE,和相关依赖进行固件仿真:
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
接着进入FirmAE
目录运行:
./download.sh
./install.sh
./init.sh
随后,使用如下命令尝试是否能够仿真:
sudo ./run.sh -c <brand> <firmware>
我们这篇文章的brand
是d-link
。如果成功仿真,使用如下命令进入仿真调试模式:
sudo ./run.sh -d <brand> <firmware>
注意,仿真之后要输入2,进入shell之后运行如下命令关闭随机化,因为真机也是不开启的:
echo "0" >> /proc/sys/kernel/randomize_va_space
基础知识
溢出漏洞
溢出漏洞是指由于缓冲区溢出等原因导致的内存溢出问题。这些漏洞可以让攻击者执行恶意代码,进而对路由器进行攻击和控制。
它可以使得黑客控制程序执行的pc
,从而达到控制程序流的目的。要知道,pc
可是指示程序下一条指令的地方!一旦攻击者成功控制了它,就能为所欲为了。
首先,我们来说说shellcode。Shellcode是一段精心编写的机器码,通常用于执行特定的操作,比如获取系统特权或者执行其他恶意行为。攻击者可以通过溢出漏洞将shellcode注入到受影响的程序中,并控制程序执行,从而执行这段恶意代码。
另一种方法是使用ROPchain(Return-Oriented Programming)。ROPchain是一种利用已存在的代码片段(称为gadgets)来构建攻击代码的技术。攻击者可以通过溢出漏洞,将栈上的返回地址(Return Address)改写为指向这些gadgets的地址,然后利用这些gadgets的序列来实现特定的功能,比如执行系统调用或者跳转到其他函数。
HTTP协议
HTTP协议是一种用于传输超文本的协议,它由请求和响应组成。让我们来看一下HTTP请求的各个部分,分别是请求行、消息报头、请求正文。IoT安全当中传输信息,大多数需要HTTP协议来进行。
请求行
HTTP请求的第一行是请求行,它由三部分组成:请求方法、请求的资源路径(Request-URI)和HTTP协议的版本。格式如下:
Method Request-URI HTTP-Version CRLF
例如:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
0
消息报头
请求的消息报头包含了一系列的键值对,每个键值对由名字、冒号、空格和值组成。它们用于传递关于请求的额外信息。例如:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
1
表示请求GIF图像格式的资源。
一个完整的请求消息报头可能包含多个键值对,像这样:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
2
请求正文
请求正文是可选的,它包含了请求的主体内容。它位于消息报头和消息主体之间的一个空行。请求正文可以包含各种数据,例如表单数据、JSON、XML等等。例如:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
3
实际上,请求正文可以包含更多内容,具体取决于请求的目的和需要。
我们在具体使用的时候,会使用python的相关库request
或者http.client
进行编程。
成因分析
• Cookie来自
char *getenv("HTTP_COOKIE")
。• cgibin链接到其他的cgi的时候,此时cgibin里除了main,还会有别的cgi文件的main。
根据漏洞报告,搜索了HTTP_COOKIE
字符串,找到相关函数sess_get_uid
及其引用,这个函数有对uid
的比较,分析得出COOKIE的数据组织形式是uid=payload
。
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
4
• 如果FirmAE无法直接解压固件,可以用fmk解压以后再压缩为tar.gz交给FirmAE。
• FirmAE如果出现文件依然存在的情况,使用如下方案:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
5
将其停止,可以重新启动仿真。
调试方法
仿真成功后,进入FirmAE进行如下输入——进入shell,查询http服务的进程号:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
6
随后输入进程号(此处是2387)启用gdb-server:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
7
宿主机保存如下脚本准备使用:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
8
假如保存为了gdb_script,那么在开启gdb-server以后使用如下命令进入调试:
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install
9
POC编写
定位到漏洞点应该在下面的sprintf
处,由char v27[1024]
可以知道,溢出至少要1024的数据。源码如下。
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
0
构造poc如下:
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
1
成功覆盖pc
如下。
EXP编写
ROPchain_system(cmd)
接下来编写exp。
cyclic可以这么使用:
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
2
从而轻松找到偏移。
我们修改一下poc如下,设置了payload,用如上方法找到偏移:
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
3
得到段错误如下。
找偏移:(注意,此处导入pwntools也是一样的,这只是我自己写的封装库)
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
4
再次修改poc确认偏移,成功控制返回地址。修改如下:
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
5
结果如下,成功控制pc
。
我们发现路由器里有telnetd
服务,这样只要执行system("telnetd")
,就可以在宿主机运行telnet 192.168.0.1
getshell了。其中a0就是第一个参数。
我们看看MIPS的寄存器作用:
寄存器 | 缩写 | 含义 |
$0 | $zero | 常量0(constant value 0) |
$1 | $at | 保留给汇编器(Reserved for assembler) |
$2-$3 | $v0-$v1 | 函数调用返回值(values for results and expression evaluation) |
$4-$7 | $a0-$a3 | 函数调用参数(arguments) |
$8-$15 | $t0-$t7 | 暂时的(或随便用的) |
$16-$23 | $s0-$s7 | 保存的(或如果用,需要SAVE/RESTORE的)(saved) |
$24-$25 | $t8-$t9 | 暂时的(或随便用的) |
$28 | $gp | 全局指针(Global Pointer4) |
$29 | $sp | 堆栈指针(Stack Pointer) |
$30 | $fp | 帧指针(Frame Pointer) |
$31 | $ra | 返回地址(return address) |
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
6
用上述命令,找到下面的gadget:
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
7
这样的情况,我们只要控制$sp + 0x10的位置是命令,并且s0是返回地址即可。
我们再次使用cyclic确定偏移,得到:
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
8
也就是
sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
9
s0往后就是s1,s2以此类推。
不过我们遇到了一个新的问题,那就是system的地址偏移是0x53200,是以00为结尾的,我们需要绕过。我尝试过用0x531fc,这里是nop,但是由于$t9的值不正确,所以后面的变量会错误,导致程序无法正常运行,那么我们只能另寻出路。
这里我们要用到一个技巧:
也就是说,执行jalr的同时,下一个指令也会执行。
我们用这个指令:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
0
找到gadget:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
1
他会在跳转到$s5的同时,将s0+1,也就是说我们传入偏移为0x531ff即可,且$$t9不会受到任何影响!
于是我们构造了如下的情况:
首先在s0传入system-1的地址,s5传入了0x000159cc的gadget。溢出之后,首先返回到s5的地址,同时,s0++,变为system的地址。此时执行第二个gadget,将"telnetd"传入s5,并且跳转到$s0也就是system,同时s5被赋值到a0也就是第一个参数,成功执行system("telnetd -l /bin/sh -p 55557")。
设置端口是担心原本的被占用了。
如图,成功。
附exp:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
2
shellcode
使用网站进行汇编转字节码:https://shell-storm.org/online/Online-Assembler-and-Disassembler/
第一步:socket(2,1,0)
在socket()
系统调用中,参数的含义如下:
• 第一个参数:套接字的域(domain)。对于IPv4网络套接字,通常使用AF_INET或者PF_INET,其值为2。
• 第二个参数:套接字的类型(type)。常见的套接字类型包括SOCK_STREAM(流套接字,用于TCP)和SOCK_DGRAM(数据报套接字,用于UDP)。
• 第三个参数:协议(protocol)。通常情况下,如果域和类型已经指定了,协议参数可以设为0,让操作系统自动选择合适的协议。在这里,值为0。
socket(2,2,0)
的意思是创建一个IPv4的UDP套接字。
如下:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
3
为了绕过x00
限制改为:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
4
得到:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
5
存入栈:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
6
得到:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
7
第二步:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
8
将标准输入输出错误流重定向到sock对象。
如下:
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
9
得到:
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
0
第三步,执行int connect(int sockfd, const **struct** sockaddr *addr,socklen_t addrlen);
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
1
此时是绑定在了192.168.0.2 5566
,也就是攻击机器的地址。ip和端口涉及大端小端的问题,参考文章的时候是大端,我说怎么调了这么久都不对……
要构造为(这是192.168.0.2 5566)
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
2
得到:
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
3
最后一步,执行execve("/bin/sh",["/bin/sh","-i"],0)
,注意,此处的第二个参数是个数组,让其能够交互:
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
4
得到:
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
5
监听:
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
6
发现一个好工具:https://bbs.kanxue.com/thread-275619-1.htm
利用以上shellcode,成功反弹shell:
完整exp如下:
git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium
7
至此完成复现。
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...