0x01 漏洞描述
2019年初,我们收到了一新研究人员提交的漏洞报告,此漏洞影响TP-Link TL-WR841N路由器。
TL-WR841N是一款廉价($ 18美元)且在Amazon.com上非常受欢迎的路由器。在提交漏洞时,它是Amazon.com上最畅销的10大路由器之一。作为一种流行的路由器,TP-Link在此设备上发布了数年的更新版本。
OpenWRT支持此路由器的旧版本可能是此路由器如此受欢迎的众多原因之一,OpenWRT是嵌入式设备的Linux发行版。Internet上存在许多关于如何为该设备的旧版本设置硬件调试接口的方法指南和教程。但是,由于OpenWRT不再支持该设备的更高版本,因此有关新的教程数量逐渐减少。
在此博客文章中,我们将使用TL-WR841Nv14路由器,并概述使用BusyBox和gdbserver在此设备上设置远程调试所需的步骤。
图1-TP-Link TL-WR841Nv14路由器
0x02 硬件分析
该路由器使用IEEE 802.11n技术,并提供高达300 Mbps的吞吐量。它有两个不可拆卸的天线,该路由器的机壳仅由机壳底部的两个螺钉固定标签下面没有螺丝。
图2-路由器底部
除螺丝外,盒还通过7个附加的夹子牢固地固定,我们花了很长时间才打开,夹子非常坚固,可以防止强拆。
图3-路由器的内部视图
打开路由器壳子,我们可以看到所有主要组件:带有MIPS24Kc处理器的MEDIATEK MT7628NN片上系统(SoC),ZENTEL A3S56D40GTP-50 256MB SDRAM和GigaDevice 25Q32CSIG SPI闪存。
图4-MEDIATEK MT7628NN SoC的特写图片
图5-Zentel SDRAM的特写图片
图6-GigaDevice SPI闪存的特写图片
通过4个定位标记将电路板固定在适当的位置,无需使用任何螺钉。PCB的下表面仅包含用于通孔组件的焊盘,表面安装组件仅安装在上表面上。这些都是设计细节,表明PCB经过高度优化以降低成本。
图7-PCB的下表面
在电路板的前部附近,J1的SPI闪存附近有一个UART调试接口,电路设计师标记RX和TX引脚。用万用表对Vcc引脚进行快速测量表明它是3.3V接口。为了方便起见,我们焊接了一些排针。
图8-UART调试接口的特写图片
0x03 获取shell
在我们的实验室中,我们只有5V USB到串行TTL线。幸运的是,我们还有一个基于BSS138的双向逻辑电平转换器。逻辑电平转换器通过将USB的5V信号转换为路由器所需的3.3V信号,使我们的5V电缆能够与3.3V UART接口通信。让我们通过逻辑电平转换器将5V电缆的RX,TX和接地引脚连接到PCB的3.3V UART接口。我们故意将Vcc引脚保持未连接状态,以避免损坏目标板。
图9-串行通讯设置的框图
使用PuTTY,我们以115200的波特率连接到串行接口。
图10-UART的输出
成功了!现在,我们有了路由器UART的输出。但是,似乎路由器对键盘输入没有响应。到底是怎么回事?让我们弄清楚!以下是我对设置进行故障排除的步骤:
1-验证串行电缆
电缆的TX连接可能断开并且没有将信号发送到路由器。为了验证电缆,我使用跳线将电缆的RX和TX引脚短路,然后使用PuTTY看到自己的按键出现在屏幕上。这样做有助于我们验证是否有可用的USB到串行电缆。
2-验证逻辑电平转换器是否正常工作
使用硬件时,一切皆有可能,且无法保证。逻辑电平转换器的焊接点较弱,可能无法正确地将TX信号传输到路由器。我们可以通过使用示波器观察逻辑电平移位来验证逻辑电平移位器的功能。我们将CH1设置为探测来自电缆的TX信号,并将CH2设置为探测逻辑电平转换器的输出。在本实验中,我们仅将电平转换器输出连接到示波器的CH2,然后将其与路由器断开连接。
图11-步骤2中设置的调试框图
然后,我们使用PuTTY连接发送空格字符以创建信号,并获得以下输出:
图12-示波器初始输出
从上图可以看出,CH2的波形与CH1匹配,并具有预期的电平移位信号。我们还应注意CH2信号上升沿的舍入,此后可能会成为问题。此外,数字示波器正确解码了UART信号,并显示了正在发送的空格字符(ASCII 0x20)。此步骤有助于我们验证我们是否有一个正常工作的逻辑电平转换器。
到了这个时候,我们知道电缆,逻辑电平转换器和路由器都可以按预期工作,但是以某种方式,当它们连接在一起时它们就无法工作。
3 –调试整个设置
完成上述两个步骤后,我们可以知道所有组件都在单独工作,但没有一起工作。这表明设置中存在系统错误。我们按照图9中的示意图重新连接了所有零件,并继续使用示波器进行研究。这次,我们将CH1设置为探测来自电缆的TX信号,并将CH2设置为探测路由器的RX引脚上的信号。在PuTTY终端中发送空格字符会从示波器产生以下输出:
图13-第二示波器读数
CH2仍在移动电平,除了逻辑高电平现在只有1.52V!我们应该进一步调查…
4 –探测路由器
如果我们仔细研究一下J1 UART接头周围的电路,可以在引脚接头附近找到三个SMT电阻,即R18,R87和R89。使用万用表的连续性测试功能,我们确定R18是连接到RX引脚的1kΩ电阻。这是罪魁祸首!
不想拆焊微型SMT组件,我们接受了损坏路由器的风险,并直接将5V RX信号从串行电缆插入路由器的RX引脚。出现了功能齐全的双向串行终端。
图14-双向串行终端
这是完成的硬件设置(不包括示波器)的图片。
图15-完整的硬件设置
0x04 查看shell文件
在shell中翻了翻,我们看到固件是基于Linux的,并且运行的是非常老的Linux内核。
图16-显示Linux版本
为了节省空间,已从设备中删除了许多Linux实用程序。设备上的shell非常有限,并且设备上的BusyBox实用程序也非常精简。
图17-路由器shell上的可用命令
0x05 上传BusyBox和gdbserver
BusyBox是一个单一的优化的Linux实用程序包。由于占用空间小,因此在嵌入式Linux设备中非常受欢迎。我们从串行接口获得的shell具有有限的功能以及BusyBox的精简版本。通过设备上现有的TFTP客户端上传自己的完整的BusyBox,可以使我们的分析变得更加轻松。可以在官方网站上找到预编译的小字节序MIPS BusyBox二进制文件。
https://busybox.net/downloads/binaries/1.21.1/
使用该mount命令,我们可以看到这/var是存储BusyBox二进制文件的唯一可用分区。由于/var是ramfs类型的文件系统,因此当路由器重启时,我们写入其中的文件将消失。
图18-确定设备上的可写位置
可以使用以下命令将BusyBox和gdbserver二进制文件传输到路由器上:
图19-安装BusyBox和gdbserver
向二进制文件添加执行权限后,我们可以执行我们的BusyBox版本并可以访问更多Linux实用程序。
图20-安装了完整BusyBox的可用命令
0x06 设置GDB
假设我们要调试dropbear路由器上的SSH服务器。在启动GDB之前,我们应该提取目标二进制文件并将其保存到将要运行GDB客户端的计算机上。这将有助于将调试符号加载到GDB客户端中。
找出dropbear SSH服务器的PID之后,请在路由器上运行以下命令以启动GDB服务器:
gdbserver localhost:23947 --attach <PID>
在我们的GDB客户端计算机上,我们将运行以下命令:
gdb-multiarch -x dbgscript
图21-GDB会话的输出
我们的gdbscript的内容如下:
现在,我们已经成功连接到gdbserver,应该能够找到一些错误并进行以下操作:
图22-GDB会话崩溃的输出
https://www.youtube.com/embed/x6SVcCJjYds?wmode=opaque&enablejsapi=1
0x07 漏洞分析
CVE-2019-17147是一个影响httpdWeb服务的缓冲区溢出漏洞。攻击者可以通过向受害者发送带有超长请求Host头的HTTP请求来触发此漏洞。该漏洞的机制很简单,在漏洞函数http_parser_main()中,它将Host请求头复制到strncpy()512字节全局缓冲区中:
当attacker_controlled_buffer变量包含的字符串长于时vulnerable_buffer,将导致缓冲区溢出。
下面是http_parser_main()从httpd固件版本0.9.1 4.16 v007c.0 Build 180613 Rel.42415n中的二进制文件中提取的函数片段。
图1-存在漏洞的“ http_parser_main()”函数的反汇编代码。
在0x405F2C,攻击者控制的Host头缓冲区通过strlen()寄存器传递$a0。strlen()的返回值存储在$v0寄存器中,cstr_strncpy()作为第三个参数(0x405F40)传递给漏洞对象。cstr_strncpy()在0x405F4C处的漏洞调用导致寄存器中引用$a0的攻击者控制的数据溢出寄存器中引用的全局缓冲区$a1。
0x08 漏洞利用
由于漏洞的缓冲区不在堆栈上,因此无法通过覆盖存储在堆栈上的返回地址来实现代码执行。幸运的是,攻击者可以使位于存在漏洞的缓冲区附近的链表Node结构的成员指针溢出。该结构负责跟踪请求参数,并包含指向下一个和上一个节点的指针:
每当httpd服务处理带有参数的HTTP请求时,http_parser_argStrToList()都会调用该函数。此函数通过以下代码来取消链接节点:
图2-“ http_parser_argStrToList()”函数片段。
由于攻击者同时控制next和prev指针,因此攻击者获得了读写原语。在下面的漏洞利用代码段中,攻击者设置了cur和prev指针,以atol()用shellcode地址覆盖全局偏移表(GOT)中的地址:
图3-利用代码片段
漏洞利用中的第三个HTTP请求http_parser_argStrToList()通过向受害者发送带有参数的HTTP请求来触发函数调用并覆盖GOT地址。包含shellcode的最终HTTP请求被发送到受害者,以触发对该调用atol()并实现代码执行。可以在此处找到完整的利用代码。
https://github.com/thezdi/PoC/tree/master/CVE-2019-17147
0x09 漏洞演示
访问路由器web
执行exp脚本
得到一个路由器shell,可以上传文件命令执行
0x10 分析总结
许多研究人员不愿钻研硬件漏洞研究。许多原因之一是,尽管严格按照本教程中概述的步骤进行操作,但仍可能无法按预期进行。发生这种情况时,请首先验证每个组件是否单独工作,然后,从已知的组件中通过测量连续性,电压和信号来验证连接。最后,使用示波器有助于对硬件进行故障排除。
TP-Link已针对多个区域发布了固件更新,以解决此错误和其他错误。但是,某些地区,尤其是欧盟和日本,可能需要等待。
https://www.tp-link.com/us/support/download/tl-wr841n/#Firmware
本文翻译自:https://www.thezdi.com/blog/2019/12/2/mindshare-hardware-reversing-with-the-tp-link-tl-wr841n-router-part-2如若转载,请注明原文地址: https://www.4hou.com/vulnerable/22200.html