如何通过UART访问并转储固件
2020-12-28 19:39:00 Author: www.secpulse.com(查看原文) 阅读量:250 收藏

原文地址:https://www.cyberark.com/resources/threat-research-blog/accessing-and-dumping-firmware-through-uart

简介

在作者的硬件黑客系列的第一篇文章中,我们讨论了通过SPI闪存芯片转储固件的方法。在这篇文章中,我们将演示如何通过一个叫做UART(通用异步接收发送器)的替代串行接口来访问和转储设备固件。首先,我们将讨论什么是UART,以及为什么我们要通过UART来访问设备,最后,介绍如何识别并访问任何设备上的任意UART接口。

什么是UART

在我们开始破解设备并通过其UART接口访问设备之前,我们先来讨论一下什么是UART以及其使用方法。

通常来说,UART可用于异步串行通信,从设备上发送和接收数据,从而实现手动更新固件、调试测试或与底层系统对接(有点像在Ubuntu中打开一个新的终端)的目的。UART的工作原理是通过两根线(一根发射线和一根接收线),直接与芯片上的微控制器或系统(即设备的大脑)进行通信。

image.png 

需要注意的是,接收器和发射器(分别标有RX和TX),需要连接到对应的UART设备的TX和RX上才能进行通信。

image.png 

一旦UART通信开始,比特就会以一种被称为“波特率”的特定频率被读取,在比特的时序被破坏之前,不同设备之间的波特率可以相差10%左右。

经过适当的布线和波特率设定,两个设备现在可以成功地进行通信了。通过访问设备的UART接口,通常会看到一个bash终端,用于访问固件。通过该终端,我们可以遍历文件系统并执行任意命令,这样,我们就可以查看Web文件,在二进制文件中查找漏洞、计划任务、后门,以及了解设备工作机制等。 

为什么要使用UART

现在,你可能会想:既然我们已经可以通过闪存芯片转储设备的固件了,那为什么还要通过UART访问或转储设备固件呢?

在该系列文章的第一篇中讲过,当用户试图转储SPI闪存芯片时,可能偶尔会遇到一个问题:通过VCC连接向设备提供的电流过大,迫使SoC(片上系统)使用闪存芯片,从而导致无法转储固件。为了解决这个问题,可以直接对闪存芯片进行去焊处理,然后再试一次,但这需要额外的工具(如热*等),有时我们的手头可能正好没有这些工具。即使你成功了,你也可能会发现转储的是一个经过加密的固件,所以,你也必须进行解密。

通过使用UART,我们可以在固件尚未在内存中进行加密并实时运行时直接与设备通信,如果这时候进行转储,则无需拆焊闪存芯片或对加密的固件进行解密。此外,当我们尝试访问系统并查找漏洞时,我们还可以实时查看系统的变化情况。 

从哪里找UART接口?

在嵌入式设备领域,UART接口通常通过在电路板上靠近微控制器/SoC的四个孔/接头的地方进行查找。前面说过,UART只有两个连接,为什么要在四个接头的地方进行寻找?很简单,其中两个接头用于通信的TX和RX,而另外两个:一个用于VCC单独为UART供电,另一个用于用于同步设备之间连接的接地。

image.png 

如上所示,您将注意到电路板边缘靠近器件SoC和内脏的四个孔。这是TP-Link Archer C7 AC1750路由器的UART接口(感谢https://openwrt.org/toh/TP-Link/archer-c7-1750)。

不幸的是,正如这里所看到的,我们可能已经识别出了一个潜在的UART接口,但这些连接并没有清楚地标明哪个是RX、TX、VCC或GND。但是,我们可以使用我们别致的Jtagulator(http://www.grandideastudio.com/Jtagulator/)和万用表来解决这个问题。

如何访问UART

在这篇文章中,我们将访问上一篇文章中提到的Belkin N300路由器中的UART接口。首先,在使用Jtagulator执行任何操作之前,我们需要确定两个器件之间的公共接地,而这两个器件则可以使用我们的万用表来识别。

image.png 

为了找到接地,请将万用表设置为连续模式(见上图)。然后,将黑色探头设置在电路外部器件上的任何屏蔽层或金属上,并将红色探头设置在每个连接上,直到出现0(或接近0)值或听到连续的蜂鸣声。这个值为0/引起蜂鸣的引脚是我们要找的公共接地。

image.png 

上图显示了四根焊接在一起的公对公跳线,以简化连接到第二个UART器件进行通信的过程。图中还显示了连接在一起的万用表探头,它们正在检查每根导线是否接地。在最左边的引脚上发现了接地。 

image.png 

现在,我们可以连接电缆,并开始使用Jtagulator识别RX和TX电缆。将路由器上地线接到Jtagulator上的地线,并将最后三个引脚连接到通道0-2(确保不要插入VADJ,因为这会向设备提供额外的电流,并可能烧毁它!)如上图所示,我们已经准备好使用“暴力搜索”了。

现在,我们需要使用一个串行控制台访问工具来访问我们的Jtagulator(我是picocom的粉丝)。由于Jtagulator的通信波特率为115200,所以我们将使用picocom连接到它的串行接口,波特率为115200,这时应该会出现一个shell。

image.png 

在与picocom连接后,我们得到了一个用于JTagulator的终端。通过菜单选项,我们可以找到UART暴力搜索工具,并用开关“u”切换到它上面。一旦进入UART模式,我们必须通过“V”为SoC设置目标电压。我们可以通过识别电路板上的SoC并查找相关数据手册来确定UART电压。对于我们的Belkin N300来说,对应的是RTL8196C SoC芯片,相关数据手册可在以下网址找到:https://www.datasheetq.com/datasheet-download/706925/1/realtek/RTL8196C。我们芯片的合适电压为3.3V。

image.png 

image.png 

最后,通过输入"u"开始暴力搜索。在解释我们输入的选项之前,不妨先来了解一下暴力搜索的工作原理。 

Jtagulator暴力搜索UART的方式为:尝试通过各种波特率向各个引脚发送和读取数据,并向用户显示数据,这样用户就可以确定哪种组合可能是正确的。我们可以选择通过TX发送的内容(在本例中,默认为回车符,或换行符),然后我们选择只显示可打印ascii字符,以确保输出的文字正确易读。就本例而言,我们希望在所有的通道上发送换行符,以便在某个时刻返回人类可读的输出。我们还要确保让Jtagulator知道0-2引脚已经全部插好,并准备好进行暴力搜索。但是,这并不总是立即返回输出,所以建议您在开始暴力搜索之前,也要立即插上被测试的设备,以便在它启动的时候查看输出(另外,万一你的TX因为某些原因失败,至少还可以用这种方法识别RX)。完成上述工作后,我们点击回车键,开始暴力搜索,之后发现:当0号针脚是TXD,1号针脚是RXD,波特率是38400时,我们得到的似乎是人类可读的输出。

image.png 

为了确认这些参数是有效的,我们只需用“p”参数将UART切换到passthrough模式,将TXD设置为0,RXD设置为1,波特率设置为38400。然后,我们输入“help ”并按下回车键以进行验证。

image.png 

成功了!我们已经成功识别了设备上的UART引脚,并建立了一个串行控制台连接。但不幸的是,我们当前的控制台好像没有提供很多的访问权限,但解决这个问题很简单。

再次重启设备查看引导输出,我们可以观察到引导到第二个root shell的过程:当引导过程被按下任何键中断时,就会出现这个shell。

image.png 

image.png 

不幸的是,在这个shell内,我们仍然受到各种限制,因为它似乎不是完整Linux shell。很难说这是一个某种形式的jail或沙箱,或者如果这是固件呈现控制台的“本色”方式。通过尝试不同的命令,我们发现flash命令是从设备上转储固件的一种潜在有效的替代途径。 

image.png 

image.png 

我们可以看到flash命令会接受一个偏移参数和一个计数参数,这让我联想到:它可以用来转储一定数量的闪存字节,并且可以从任何偏移开始。通过这个方法,我们成功转储了固件的所有字节,但还是遇到了一个麻烦:用flash命令转储大量字节实际上会导致设备崩溃和重启!这到底是安全机制还是故障呢?

image.png 

不管这是安全机制还是固件本身的故障,我们都很难确定,但是借助于Python语言,我们能够开发一个脚本来建立串行连接,一次转储4096个字节,以绕过这个限制,并通过512个请求缓慢转储所有200万个字节。由于偏移量与字节一起输出,我们也能够实现一个简单的完整性检查,以确保所有的字节都存在并具有适当的长度,如果不正确,我们应该能够强制重试当前的数据块。用于转储这个固件的脚本可以在这里找到:https://github.com/waldo-irc/IOTToolkit/tree/master/FlashDumpScript。

image.png 

大约2个小时后,该脚本运行结束,并生成了一个output.bin文件,其中所有的字节都是明文。借助于本人提供的DumpToBin.py脚本,我们可以将文本文件转换为有效的固件bin文件。

image.png 

小结

正如我们所看到的,UART是直接访问和转储闪存芯片的一种非常可行的替代方案。我们可以在机器运行时访问底层固件,并通过固件bin文件的静态分析和IOT设备运行时的动态分析来观察所有操作并识别固件中的任何安全缺陷。

在这个例子中,尽管UART给我们提供的是一个功能受限的shell,但是,我们可以利用这个shell以另一种方式转储固件,并在运行时给我们提供设备的未加密固件进行分析(这也可以提供一些有趣的数据,比如解压的文件系统,否则我们可能无法访问)。不过在大多数设备中,UART可以提供设备的完整的root shell,允许像在其他Linux设备上一样遍历它,甚至允许在操作系统内轻松安装后门,而不必直接嵌入到固件内,这对于攻击者来说是相当有用的。 

本文作者:mssp299

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/150363.html


文章来源: https://www.secpulse.com/archives/150363.html
如有侵权请联系:admin#unsafe.sh