【技术分享】TP-Link WR841N路由器任意代码执行漏洞分析(附演示视频)

http://p0.qhimg.com/t0104c41e84052baa42.png

译者:興趣使然的小胃

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

一、前言

最近我们在TP-Link的WR841N V8路由器上发现了两个漏洞,利用这两个漏洞,我们可以在这款路由器上执行我们自定义的代码。与厂商友好协商后,他们在新版路由器固件中修复了这个漏洞,因此我们决定公开我们的研究成果。

我们团队的主要研究方向是网络嵌入式设备,根据研究成果,我们对产品进行改进,同时也会在嵌入式设备生产及安全社区中分享成果。WR841N这款设备刚好是我们在硬件攻击课程中用到的路由器,也是我们在介绍JTAG相关知识时的重点介绍对象。我们在对这款路由器进行研究时,发现它在配置服务的逻辑处理流程中存在一个缺陷,利用这个缺陷,我们能够绕过路由器的访问控制策略,并且能够重置路由器的凭证(CVE-2017-9466)。随后,我们利用获取到的访问权限,通过配置服务中存在的栈溢出漏洞实现了路由器的任意代码执行。

在这类抵近攻击中,我们用到了智能手机的热点功能,通过某个协议重设了路由器的凭证(新的硬件型号已经在固件中删除了这个协议)。不幸的是,尽管老型号可能不再得到官方的支持,但这些设备往往处于关键位置。幸运的是,当我们向TP-Link报告了这个问题后,他们马上同意在这个型号中删除存在漏洞的配置服务。

我们会详细分享这一技术细节,希望我们的研究成果能够帮助大家理解有关抵近攻击、过时版本的固件、加密的逻辑流程或者存在漏洞的配置服务方面的知识。

读者可以直接阅读本文的技术细节部分了解详细信息。

二、漏洞摘要

我们首先做的就是购买这款路由器、下载路由器固件然后开始分析固件。我们之前在配置服务漏洞方面已有所研究,因此我们直接查找并最终在固件中发现了这样一个服务。这个服务允许网络用户读取并写入系统设置。这款路由器要求用户使用基于用户名和密码的密钥对发往路由器的命令参数进行加密,借此保护这个服务的安全性。

参数所使用的加密算法为DES算法,按8个字符块形式对文本进行加密。识别文本加密的逻辑处理缺陷对我们而言并不是难事。因为我们已经从固件中了解了加密前的明文版本,也能够通过路由器的服务掌握加密后的密文版本,因此我们能够复制加密后的文本,并将其以有效参数形式发回路由器。此外,并不是所有的命令都需要参数,这导致这些命令的功能会暴露在公开互联网中,任何人都可以访问。

http://p9.qhimg.com/t016f785b2d070a0c16.png

图2. 使用IDA Pro逆向分析路由器固件时的截图

为了利用这些命令,我们首先找到了某个不需要参数的命令,但这个命令依然能够返回可以预期的经过加密后的文本。我们复制了加密文本的前8个字符,将其作为一个特征名称加以使用。我们将智能手机的名称设为这个特征名称,然后开启手机的热点功能。我们通过网络向路由器发送了一个命令(这个命令同样不需要任何参数),触发路由器搜索附近的热点。在手机名称(即前面提到的特征名)的末尾添加“init”这个字符串后,我们向路由器请求一份包含所有热点的加密列表,通过这个特征名在这份列表中查找我们所提供的那个热点。在这个列表中,经过加密后的“init”会紧跟在特征名之后。这样一来,我们就能将经过加密的“init”作为参数,传递给相应的命令,通过这个命令,我们可以迫使路由器恢复初始设置,这些设置中包含默认的用户名及密码。

http://p1.qhimg.com/t01df80685e31ecf566.png

图3. iPhone上的热点设置界面

成功重置路由器用户名及密码后,我们对参数进行了加密,而没有使用热点技术。如果攻击者想避免引起用户的警觉,他们可以继续使用热点技术,获取后续漏洞利用所需的相关加密文本信息。在这里,我们通过另一条命令挖掘出路由器的一个栈溢出漏洞,成功获取这款路由器上的自定义代码执行权限。为了演示我们所获取的底层控制能力,我们使用自制代码控制路由器的灯光闪烁动作,通过路由器灯光以摩斯编码传递“Hi Senrio”这个信息。现实生活中,攻击者可以利用这种技术,从隔离网络中传递信息,或者修改路由器的设置,将流量重定向到恶意服务器上。

如果读者不想了解技术细节,可以直接跳到本文结尾的总结部分。


三、技术细节

3.1 获取访问权限

首先,我们从TP-Link的支持网页上下载了这个硬件型号的最新固件,使用binwalk工具提取了squashfs文件系统。

http://p6.qhimg.com/t01e4f353b425dc1f4f.png

图4. binwalk的输出信息

       当我们拆掉路由器的顶部外壳后,我们发现了一个4pin引脚头,通过这个引脚头,我们能够使用UART接口访问受密码保护的控制台。我们尝试暴力破解文件系统中shadow文件的密码哈希,但直到我们发现路由器漏洞并完成漏洞利用技术时,暴力破解还是没有得到明文密码。然而,我们成功中断了路由器启动进程,获得了一个控制台接口,这个控制台原本是用于从外部FTP服务器上接收固件及文件系统的更新。我们备份了squashfs文件系统,修改其中的shadow文件,添加一个新的root密码,然后通过我们自己的FTP服务器更新了路由器的文件系统,最终获取到root控制台的访问权限。通过这个控制台,我们能够观察调试输出信息,并且当目标进程崩溃时也能导出内核信息加以分析。

http://p8.qhimg.com/t01836fb4ff78b0946d.png

图5. 连接UART引脚

3.2 分析固件

我们之前已经见到过很多存在漏洞的配置服务,根据以往经验,我们在提取的文件系统中搜索包含recvfrom()以及sendto()的代码,这是UDP服务包含的特征。短暂搜索后,我们发现了一个名为tddp的服务,这个配置服务以任务形式隐藏在web服务器中,它监听用户发来的命令请求,这些命令可以读取及写入系统设置。

这个二进制文件中包含tddp服务所涉及的大部分函数的名称,也包含用于频率调试的打印信息,这些信息对我们的逆向分析工作起了非常大的作用。我们发现了两个不同的函数,用于处理不同类别的命令。第一类命令是使用明文参数的一些简单命令,第二类命令是使用加密参数的系统级命令。

http://p3.qhimg.com/t01dd59c152dba618cc.png

图6. recvfrom()函数以及配置服务的主解析函数

我们对协议进行了逆向,发现第一类命令对攻击者而言用处不大。之后我们枚举了所有可用的第二类命令,这些命令中包含设置广域网和本地网络配置选项的命令、更改系统模式的命令以及获取附近可用访问点的命令。

传递给第二类命令的参数会经过DES加密处理,DES是一种对称加密算法,以8字节块对数据进行加密。我们逆向分析了能够返回加密密钥的那个函数,发现这个函数将路由器用户名及密码连接起来,形成未加盐的md5值,将这个md5值的前8个字节作为加密密钥使用。这样做是为了防止除路由器所有者以外的其他人运行这些命令。

http://p8.qhimg.com/t0141bfea3da1cd5995.png

图7. 两类命令的解析器

3.3 抵近攻击

我们使用手机的热点功能来发起抵近攻击,同时向路由器发送一系列命令来获取所有第二类命令的访问权限。第二类命令中,SetUserConfig命令提供了路由器所有配置的写入访问权限,因此我们可以做许多操作,比如将路由器的DNS服务器地址指向某个恶意服务器,或者以此为跳板攻击网络上的其他设备。然而,展示攻击成果最为有效的一种方式,就是攻击者可以在不掌握路由器凭证的前提下,在路由器上执行命令,并获得路由器的控制权限。

我们在某个参数解析函数中发现了一个栈溢出漏洞。此时此刻,我们无法利用这个漏洞,因为溢出数据来自于命令参数,而这些参数需要经过正确的加密。为了绕过这个限制,我们决定将路由器恢复到出厂设置状态,这样用户凭证就会恢复到默认用户名及密码。为了完成这一任务,我们将sysCommand作为目标,这个函数收到加密版的“init”指令后,会对路由器进行重置。

http://p8.qhimg.com/t0113939974fe9e7013.png

图8. sysCommand()会查找“init”、“save”或者“reboot”命令

由于DES是个对称加密算法,并且会按照8字节块进行加密,因此它并不能实现对命令参数的全面保护,因为攻击者非常容易就能复制这些参数,并能重复使用这些参数以攻击目标。getAPList这个命令会返回附近可用访问点的加密名称,这也是我们为什么会使用手机的热点功能来创建自己的访问点。

我们使用getPhyLinkStatus命令的输出作为特征,识别访问点列表中属于我们的那条信息。getPhyLinkStatus这个命令不需要提供任何参数,并且会返回前缀为“wan_ph_l”的加密字符串。我们通过另一条不需要参数的命令启用了路由器的搜索模式,将手机的名字开头设为“wan_ph_l”,并填充某些字符使手机热点名称在路由器的访问列表中保持8字节对齐。我们查询了getAPList,查找经过加密后的“wan_ph_l”字符串,很快就识别出我们的手机名。之后我们更新了手机的名称,紧挨在“wan_ph_l”之后附加一个“init“字符串,通过getAPList获取加密后的init参数,并将其传递给sysCommand命令,重置了路由器。

简而言之,我们使用如下几个步骤将路由器恢复到出厂设置状态:

1、通过getPhyLinkStatus获取加密后的“wan_ph_l“。

2、设置附近访问热点,热点名为明文形式的“wan_ph_l”+“init”,填充部分字符串以便对齐。

3、使用activateAth0命令启用访问点搜索接口。

4、使用getAPList命令请求访问点状态列表,并保存加密后的“init”参数。

5、将加密过的“init”参数传递给sysCommand命令。

再深入研究一下,如果周围没有可接入热点,但我们还想要获得系统访问权限,这时候应该怎么办呢?我们可以使用常见的用户名及密码对“wan_ph_l”进行加密,构造这样一个彩虹表,生成用户名及密码所对应的哈希值。如果哈希值匹配,那么我们立刻就能获取服务的完全访问权限。

3.4 代码执行

在分析过程中,我们发现某个函数中存在栈溢出漏洞,这个函数负责对传入数据进行处理。我们已经掌握了生成加密参数的方法,因此我们终于能够利用这个漏洞。由于新发布的补丁能够阻止远程攻击者直接访问这个漏洞,因此TP-Link决定不再单独修复这个漏洞。尽管这个漏洞很难对用户造成安全风险,但它目前仍是未修复状态,并且厂商将来也没有要修复它的计划,因此我们决定不在此时透露这个漏洞的详细信息。

我们得到了路由器的代码执行权限,通过编写的shellcode使路由器的LED灯以摩斯码进行闪烁,传递“Hi Senrio”信息,借此展现我们对路由器底层架构的控制能力。现实生活中,攻击者可以利用这种技术实现隔离网络中的数据传输,或者修改路由器的设置,将流量重定向到恶意服务器上。


四、总结

当我们向TP-Link报告这个漏洞时,我们发现这款硬件型号已经停产,因为官方网页上没有早期型号的更新信息。TP-Link同意从我们使用的这款硬件型号的固件版本中删除存在漏洞的服务,这无疑是个利好消息。当我们报告这个漏洞时,Shodan搜索引擎显示全世界至少有93,328个用户正在使用WR841N路由器,然而我们并没有有效的渠道能够告诉他们这一消息,并且他们正在使用的路由器似乎不大可能正在运行最新的固件。

http://p6.qhimg.com/t013f59eb5c44866fb4.png

图9. Shodan的搜索结果

这对我们来说是个重要启示。对整个行业而言,我们过于依赖过时的硬件设施,因为整个行业、企业以及消费者无法承受频繁更新硬件型号所需的时间、精力以及成本。虽然TP-Link为这个过时的型号提供了修复补丁,我们还是需要创新的方法来保护这些过时的设备。


演示视频

完整攻击过程的视频如下所示。读者一定要坚持到视频结尾,欣赏一下路由器LED灯光所传递的欢迎信息。

 

(完)