D-Link DIR505路由器溢出漏洞实战

D-Link DIR505路由器溢出漏洞复现

一.基本IOT试验环境准备

本试验需要基于一些常用二进制以及模拟器工具,实践之前请提前安装和准备:

binwalk及sasquatch 插件安装:
binwalk用于IOT固件解包以及文件系统、二进制文件提取。

buildroot交叉编译环境安装
用户在X86 环境下编译其他CPU架构的二进制程序。

qemu模拟器安装
虚机程序,可使用它在X86环境下模拟运行其他CPU架构的二进制程序。

wine模拟器安装
Linux环境下的windows程序运行模拟器。本实践采用在Linux环境下运行IDA 逆向工具。

二.漏洞复现及利用过程

2.1淘硬件:

在咸鱼平台上淘这类IOT小设备作为试验用途还是挺实惠的,如下图40元包邮搞定DIR505路由器硬件:
在这里插入图片描述

2.2固件包获取及二进制提取:

如果是从二进制着手去挖掘漏洞固件获取是第一步。在能够通过互联网手段下载到固件包的情况下优先直接下载;否者需要采用编程器这类设备进行固件提取,本次实践直接在网上找到了固件包,版本为:DIR505A1_FW105CNB01.bin

预先安装好binwalk工具,并安装sasquatch 文件系统补丁,进行文件系统提取,拿到my_cgi.cgi二进制文件,供后续分析。采用binwalk -Me 命令进行解包、提取后,拿到sasquatch文件系统如下图所示:

在这里插入图片描述

my_cgi.cgi文件在 /usr/bin路径之下:

在这里插入图片描述

2.3伪代码溢出点分析:

经过相关资料的查阅,得知该漏洞发生的位在my_cgi.cgi的get_input_entries函数。由于该文件的访问没有权限控制,所以一旦它的溢出漏洞被发现并且没利用成功,威胁程度非常高。

IDA工具逆向my_cgi.cgi二进制文件,得到C语言伪代码, 如下图所示:
在这里插入图片描述
在这里插入图片描述

如上图所示,get_input_entries的入参content_length 控制while循环次数,每次循环给buf赋值写入数据。而数据来源用户POST报文的数据字段,当数据的长度content_length 超过buf的大小即会产生溢出。由于没有异常保护,这个溢出点完全是攻击者可控的

2.4二进制模拟调试确认溢出漏洞:

通过逆向分析伪代码找到漏洞位置之后,需要进行模拟调试进行漏洞确认。

在IDA 通过 jump to xref 找到 my_cgi.cgi 中main函数调用 get_input_entries 函数的位置,如下图所示:

在这里插入图片描述

如上图所示,get_input_entries 入参 my_entries buf长度 为477456,故当POST数据长度content_length > 477456时有机会触发溢出。

使用file命令得知my_cgi.cgi二进制程序是一个mips 32位大端ELF:
在这里插入图片描述

所以需要使用 qemu 的 qemu-mips 的模拟程序。

故构造如下shell脚本,调用qemu-mips 调试 my_cgi.cgi 二进制程序:

在这里插入图片描述

如上图所示,qemu-mips 通过 -E参数设置HTTP头的参数。qemu构造的是一个HTTP POST报文其数据内容为‘storage_path=’+ 490000个‘Q’(需要明显大于 my_entries buf的长度,确保能够溢出) HTTP 头 CONTENT_LENGTH字段值即POST数据的长度。脚本运行结果如下:
在这里插入图片描述

如上图所示my_cgi.cgi跑出了段错误。出现段错误,可能是由于RA寄存器的被改写,程序访问了程序段地址空间之外的地址所导致。

为了证明这个段错误是由于溢出引起的,我们重新构造脚本,让POST数据小于 my_entries buf的长度,并运行:

在这里插入图片描述
在这里插入图片描述
如上图所示,当POST数据填充长度为490 远小于 my_entries buf 长度时,my_cgi.cgi运行时不会出现段错误的。正常返回了Web页面数据。

至此,我们确认了my_cgi.cgi二进制程序中 get_input_entries 溢出漏洞的存在。

2.5EXP编写及漏洞利用:

上一节我们通过QEMU的模拟运行确认了溢出漏洞的存在,现在我们需要精确控制溢出,实现对IOT设备的控制。

2.5.1MIPS溢出漏洞利用原理:

RA通用寄存器:

MIPS 有$0-$31 32通用寄存器。其中$31 也称为$RA (返回地址Return Address)寄存器**。也就是说当一个函数执行完成后可以通过$RA寄存器的函数地址决定后续程序执行走向。

MIPS架构下非叶子子函数程序执行流程:

当函数A调用函数B时,函数调用步骤:

01 当函数A调用B时,函数调用指令复制$PC寄存器(指令寄存器)的值到$RA。

02 当程序跳转到B执行,由于B不是叶子函数,函数指令会将函数返回地址即A的地址存入堆栈。

03 B函数执行完成准备返回时,指令会将堆栈内存储的A函数地址反写会$RA寄存器,然后通过jr $RA 的指令,将执行流程重新转向A

终上所述,若我们能够精确的控制溢出,改写堆栈上保存函数的返回地址,那么攻击者就能够控制程序执行走向造成系统被完全控制等严重后果(本次实践,拿到路由器shell)。

2.5.2精确控制$RA寄存器的值:

在2.4节,我们通过调试脚本(run_script.sh),确认了溢出漏洞的存在,现在需要反复调试run_script.sh脚本中 storage_path= Padding 数据的长度,直到正好能够覆盖$RA寄存器中的值。

在这里插入图片描述
如上图所示,脚本中 增加 -g $PORT 参数,使得my_cgi.cgi 运行之后,能够被IDA 进行远程调试。由于my_entries buf 长度为477456,所以从该长度开始尝试,反复试验后,发现填充 4777464个字符Q后,再写入4个字节A正好可实现对$RA寄存器数据的覆盖。

在这里插入图片描述

如上图所示,在get_input_entries函数的return 处增加断点。采用IDA 连接4444端口反复进行远程调试。每次修改Pading字符(Q)字符后,观看RA寄存器的值,直到$RA寄存器的值正好被4个A覆盖之后,则说明Pading字符(Q)的个数调试OK了。测试脚本数据应该为:

**‘storage_path=’+'Q’477464+'A’4

2.5.3寻找可以利用的函数:

能够精确控制$RA寄存器的值之后,现在我们现在需要找到可利用的函数。通常拿到shell,我们可以使用系统函数system 开启telnet服务的方式实现。所以通过搜索system的调用者,来寻找可利用的函数:

在这里插入图片描述

如上图所示,通过system函数的引用关系,选定了get_remote_mac 函数,其中地址为405234的地方调用了system

在这里插入图片描述

如上图所示,get_remote_mac函数,通过sprintf函数,将cmd入参拼接至v11,然后调用system函数进行系统命令执行。

为了给cmd入参传入有效数据,需要找到cmd参数相对get_remodte_mac函数地址的偏移量。
在这里插入图片描述

如上图所示,cmd参数相对于get_remote_mac函数地址的偏移量为0x64-0x3c=0x28

2.5.4构造EXP:

根据2.5.2和2.5.3的分析结果,为了调用system函数,实现对溢出漏洞的利用拿到shell,我们需要构造如下ROP Chain(Return-Oriented Programming)
在这里插入图片描述

将上述ROP Chain转换为Python3 EXP脚本如下图所示:
在这里插入图片描述

如上图所示,利用上述EXP可以实现命令注入,开启路由器的telnet服务。

2.6 采用EXP攻击路由器:

如下图所示,运行EXP Python3脚本,然后直接尝试采用默认IP 192.168.0.1 telnet登录:
在这里插入图片描述

如上图所示,执行EXP脚本之后,telnet服务被打开.telnet登录之后,直接获取root权限,至此路由器完全被控制。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值