两个CVE的漏洞分析
根据课题研究方向搜到的2个CVE,师叔让写一个漏洞分析文档,在这留档记录下。
CVE-2011-4860
相关设备:施耐德PLC工控设备
设备型号:NOE71101
漏洞描述:NOE 771设备(又名Quantum 140NOE771* 模块)上的施耐德电气Quantum 以太网模块中的ComputePassword 功能通过对MAC 地址执行计算生成fwupgrade 帐户的密码,这使得远程攻击者更容易获得访问权限通过(1) ARP 请求消息或(2) 邻居请求消息。”
固件下载地址:https://github.com/ameng929/NOE77101_Firmware
漏洞分析
在目录 \FLASH0\wwwroot\conf\exec 下,NOE77101.bin 就是要分析的固件。
使用binwalk提取过后,可以看到固件是Vxworks操作系统,PowerPC架构大端序
最后一行信息能看到符号表的地址是0x301E74,在后边恢复符号表时会用到。
使用IDA32打开385文件,选择PowerPC big endian,之后会让填写ROM的起始地址,这里得到是0x10000(好像也是固件常用基址)。在ROM start address和Loading address 处填入后,一路默认。
进入到主界面后,导入符号表重建脚本重建符号表,上边已经得到了符号表起始地址0x301E74,再通过HxD找到符号表终止地址0x3293B4,idc脚本见rebuild.idc
1 | /* rebuild.idc */ |
修复好后可以在函数栏看到修复后的函数名称,这个固件的漏洞发生在 ComputePassword 函数中,这个函数在 usrAppInit 函数内被调用。首先进入 usrAppInit 函数,使用IDA反汇编后,得到的伪代码如下:
v12 通过调用 GetEthMAC 函数获得设备的 mac 地址,然后下边的 sprintf 函数把 mac 地址赋值给了v13,接着做为 ComputePassword 函数的参数。这里用IDA反汇编的不是特别好,在博客上看到别人用 Ghidra 反汇编得到的结果要比IDA直观些,于是在 ghidra 上进行反汇编,同样要重建符号表,Github上有别人写好的 ghidra 脚本,根据 readme 将脚本导入 ghidra ,运行脚本(vxhunter_firmware_init.py)进行自动修复和分析,反编译后 usrAppInit 的伪代码如下所示:
v12 对应 local_50(mac地址),v13 对应 acStack72 ,从 ghidra 反汇编的结果中 sprintf 函数的参数可以看到,mac 地址是通过数组的形式分段存放的。
进入到 ComputePassword 函数中,反编译查看源码如下:
同样在 ghidra 中看一下:
ComputePassword 函数首先用 strcpy 给 param_2 赋了一个值,这个值可以看到为 0x :
然后用 strcat 函数,把 param_2 和 *(param_1+3) 拼接在一起。param_1 对应 acStack72(mac),接着,函数对包含 mac 的 param_2 经过一些运算后,最后将结果保存在 param_2(也就是 acStack56 )中并返回。
紧接着,usrAppInit 函数调用 loginDefaultEncrypt 函数,参数为 acStack56 和 &DAT_00342044 ,查看该函数:
这个函数看的也不是特别懂,但是大致功能是对 acStack56(通过 ComputePassword 计算得到的)做一些操作,然后保存到 &DAT_00342044 这个地方。紧接着在 loginUserAdd 函数中,将 &DAT_00342044 作为账户 s_fwupgrade 的密码。
整个过程概括下来就是,ComputePassword 函数接收mac地址作为参数输入,计算得到账户 s_fwupgrade 的密码,函数内部的计算过程也不算复杂,从而导致了漏洞的产生。
参考链接:
CVE-2017-8416
相关设备:摄像头
设备型号:D-Link DCS-1100/1130
漏洞描述:设备在UDP端口5978上运行一个自定义守护进程,称为 “dldps2121”,监听设置为255.255.255.255的报文或广播报文。这个守护进程处理自定义 Dlink 基于UDP的协议,允许 Dlink 移动应用程序和桌面应用程序发现本地网络上的 Dlink 设备。这主要是有用的设置设备使用这些应用程序,并提供用户友好性方面。二进制以 “main” 功能处理从任何设备发送的UDP数据包。函数中的一条路径遍历处理数据包的代码块,该代码块执行无界复制操作,允许溢出缓冲区。
Dlink创建的自定义协议遵循以下模式:
1 | Packetlen, Type of packet; M=MAC address of device or broadcast; D=Device Type;C=base64 encoded command string;test=1111 |
dldps2121程序中,从地址 0x0000DBF8 开始的地址函数处理整个UDP数据包,并使用地址 0x0000DC88 的 strcpy 函数执行不安全拷贝。
固件下载地址:http://legacyfiles.us.dlink.com/DCS-1130/REVA/FIRMWARE/DCS-1130_REVA_FIRMWARE_1.08.8707.ZIP
漏洞分析
使用 binwalk 提取固件文件系统,固件为 cramfs 文件系统,32位 arm 架构,dldps2121 程序位于 /cramfs-root-0 目录下,导入到IDA32进行分析。
根据漏洞信息的提示,程序在DBF8函数处理UDP数据包,查看DBF8函数的反编译后的伪代码:
a1 参数应该是接收到的UDP数据包数据,函数首先将数据赋值给 v10 ,然后通过strstr函数找到字符串“D=”在UDP数据包中第一次出现的位置并赋值给 v5,然后将 “D=” 后边的内容通过不安全的strcpy函数复制到 v6 处,这里由于 strcpy 函数本身的不安全性,导致存在缓冲区溢出漏洞。根据UDP数据包的格式:
1 | Packetlen, Type of packet; M=MAC address of device or broadcast; D=Device Type;C=base64 encoded command string;test=1111 |
“D=” 前边是包的类型和设备的 MAC 地址,所以,只要我们获得了设备的 MAC 地址,我们就能利用 strcpy 函数存在的缓冲区溢出漏洞,对该设备发送构造好的UDP数据包执行攻击。
采用文档里的说法:此处的 strcpy 函数会导致在1060个字符之后溢出堆栈指针,从而允许控制PC寄存器并导致代码执行。任何进程都可以发起相同形式的通信,包括手机或桌面上的攻击者进程,这允许设备上的第三方应用程序通过发送一个带有自定义 base64 编码的UDP数据包在设备上执行命令,而无需任何身份验证。
漏洞是在通过对移动应用程序 dink lite 进行渗透测试,并逆向设备上存在的 “dldps2121” 二进制文件发现的。