欢迎访问本站!

首页科技正文

行使污点剖析批量挖掘路由器固件平安破绽

admin2021-08-1283技术

欧博手机版下载

欢迎进入欧博手机版下载(www.aLLbetgame.us),欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

,

在已往的几个月里,我们开发了一个污点剖析工具,专门用于寻找路由器中的平安破绽。我们还参考编号为CVE-2019-8312到CVE-2019-8319之间平安破绽开发了一个检测工具;这些破绽都是固件版本为1.12A1的D-Link DIR-878路由器中的下令注入破绽。我们的目的是自动检测此类破绽。在理想情形下,使用该工具应该比手动查找破绽更快。

在本文中,我们将分享我们所使用的方式,以及通过该工具在PROLiNK PRC2402M、D-Link DIR-1960和D-Link DIR-X1560路由器上找到的平安破绽。

关于工具

现有工具

现在,现成的污点剖析工具已经有许多了。其中,我最感兴趣的是Triton和bincat,由于两者已经相当成熟。然而,我们却无法使用这两种工具,由于它们不支持目的装备所使用的MIPS架构。

使用angr举行符号执行测试

因此,我们把事情重点放在行使angr打造自己的工具上;angr是一个基于Python的二进制剖析框架。我们之以是选择angr,是由于它支持大多数架构,包罗我们所针对的MIPS和ARM架构。早些时刻,@puzzor曾经对angr举行了一些自界说修改,用于静态污点剖析:在angr的辅助下,通过符号执行模拟程序,然后凭证天生的VEX IR程序跟踪信息举行静态剖析。通过这种方式,我们乐成地在测试固件中发现了下令注入破绽。

然而,我们很快就遇到了一个问题:为了天生程序跟踪信息,我们需要angr通过模拟每条指令来模拟每个函数,并使用符号执行来决议是否追随一条分支指令。

详细来说,angr会维护一个状态客栈。一个状态包罗诸如寄存器值和内存内容方面的信息。因此,当模拟一个函数时,它只会从一个状态最先。当遇到一个分支指令时,若是angr不确定是否追随该分支,angr将重复该状态,其中一个将追随该分支,而另一个则不追随。

大多时刻,函数中都市存在循环。若是循环条件是基于一些用户的输入,那么,状态的客栈就会“爆炸”。由于angr将始终不确定是继续照样从循环中跳出,以是,它会不停复制状态。此外,还需要注重的一件事是,这些状态并不是同时模拟的。相反,每次只有一个状态被模拟。在这种情形下,需要很长的时间才会有一个状态到达易受攻击的代码;或者,若是该函数基本没有易受攻击的代码,那么,模拟历程可能永远不会终止。

作为一个符号执行框架,angr提供了多种可定制设置(称为模拟手艺)来决议先模拟哪个状态。而且,在实验了许多差其余手艺后,我们仍然无法改善执行时间。

例如,在为待剖析二进制代码中的每个函数设置了2分钟的超时的情形下,有时刻纵然经由了2小时,仍然无法完成对二进制文件的剖析(由于若是一个函数没有破绽,它将一直模拟执行下去,直到超时位置)。更糟糕的是,angr中存在一个未知的内存泄露问题,以是,2小时后,电脑的内存早就耗尽了……

别忘了,我们之前的目的是希望这个工具比手工方式更快一些。以是,通过这种方式是不能能的,以是,我们继续寻找改善方式或替换方案。

应用angr的Reaching Definition剖析手艺

最终,我们有时发现了这个破绽后,燃起了我们对于angr的Reaching Definitions剖析手艺的热情,于是仔细阅读了下面的资料:

◼A reaching definition engine for binary *** ysis built-in in angr

◼Handle function calls during static *** ysis in angr

◼CSE545 Guest Lecture: Binary Analysis

Use-def关系

总之,这种剖析方式将天生函数中原子之间的use-def关系。在这里,所谓原子类似于变量,而且,原子也具有种种类型,如寄存器、栈变量、堆变量。现实上,只要把原子看作变量,事情就很简朴了,下面,我们举例说明:


在上面的函数中,存在一个显著的下令注入破绽:含有破绽的代码为system(command),其中注入的下令来自querystring的参数name。在这个函数中,querystring和其他原子之间的use-def关系如下所示:

 


首先,我们看到querystring被界说为函数vuln的参数,并被get_querystring_value函数作为参数querystring使用。除此之外,函数get_querystring_value还界说了一个参数name。最后,get_querystring_value函数界说了一个返回值,并用到了上面界说的两个参数。

然后,通过下图我们可以看到,在挪用sprintf函数时,还用到了name变量(函数get_querystring_value的返回值)和一个字符串echo %s >> /tmp/log。这一次,情形略有差异。由于我们知道sprintf函数的第一个参数是目的,以是,我们必须对command举行适当的界说,从而让它周全使用提供应spritnf函数的2个参数,而不是仅使用返回值。天生的use-def关系如下所示:

 


使用相同的看法,通过这种剖析方式可以为函数中的所有原子天生响应的use-def关系。正如我们在上面看到的,这种关系可以被建模为一个图:“使用”用边示意,“界说”用节点示意。 因此,我们可以将其转换为图剖析问题。

在污点剖析术语中,source点是程序中发生污点数据的地方,而sink点是污点数据可能到达也可能不到达的地方。污点剖析是确定来自source点的数据是否到达sink点。在上面的例子中,get_querystring_value函数是source点,由于它从用户输入中提取一些值,而system函数是sink点。就本例来说,来自source点的数据确实到达了sink点。

在我们的use-def图中,我们可以确定source点和sink点的界说(即节点),然后用一些启发式方式遍历该图,以确定source点的数据是否被sink点所使用。若是是,那么我们就把source点符号为易受攻击的,并继续对其举行筛查。

工具总结

总而言之,我们的工具首先行使angr的Reaching Definitions剖析方式,天生一个由路由器固件中的函数的组成的use-def关系图。然后,对该图举行响应的剖析,以检测可能的平安破绽,好比,若是(来自source点)用户输入到达一个危险的函数(即sink点),如system函数,我们就以为发现了一个潜在的平安破绽。

现实上,我们的工具与CodeQL或Joern等引擎的功效异常类似,只是我们的工具缺乏壮大的查询界面而已。

测试效果

前面我们曾提到,使用符号执行的方式时,有时剖析一个程序需要破费2个多小时。然则,使用上面先容的方式,剖析同样的程序只需2分钟左右就能搞定了。以是,这看起来简直是一个不错的工具。 在对该工具举行改善以消除假阳性并笼罩更多的假阴性后,我们在DLink和PROLiNK路由器上举行了测试。

PROLiNK PRC2402M

使用该工具,我们立刻发现了近20个下令注入破绽,其中10个不需要身份验证,可以直接通过WAN接口举行接见。我们马上向PROLiNK讲述了这些破绽,他们也很快做出了回应。在这些破绽被修复后,我们申请了响应的CVE编号,它们划分为CVE-2021-35400到CVE-2021-35409。 下面是一些易受攻击的代码片断,其中source点和sink点划分是:

◼Source点:web_get

◼Sink点:system, do_system, popen


硬编码的密码,照样后门?

在这个历程中,我还发现了一些其他的平安破绽。似乎有一个硬编码的密码或后门密码,可以用来登录到路由器的治理面板:治理页面将用户提供的密码的md5哈希值发送到login.cgi举行验证,响应的伪代码如下所示:


然而,在它后面另有一段可疑的代码:


通过将user作为密码,我们竟然乐成登录到治理页面。通过这种方式登录后,显示的仪表板会略有差异,它似乎比通过现实密码上岸的用户提供的功效要少。然而,我们仍然可以接见http://prc2402m.setup/setting.shtml,这就足以控制路由器的设置了。

我们向供应商讲述了这一情形,他们很快就更新了固件。为了确定该后门已经消逝,我再次打开了统一个函数。这次,我并没有再看到strcat(salted_password, "user"),却看到了以下内容:


现实上,通过nvram查找Password_backup的值也不是什么难事。


我们很快又向供应商讲述了这个问题。幸运的是,经由再次修复后,已经找不到Debugdoor或后门密码了。

基于客栈的缓冲区溢出

由于缺乏界限检查,我们还发现了许多基于客栈的缓冲区溢露马脚。通过行使这些破绽,攻击者可以笼罩客栈上的返回地址,从而获得对程序执行的控制。在上面的一些下令注入的例子中可以看到,用户的输入是通过sprintf函数而不是snprintf函数复制到一个字符串中的。

拒绝服务破绽

在测试缓冲区溢露马脚的PoC时,我还发现了一个破绽,它导致路由器住手响应请求,直到用电源按钮手动重启为止。在下面的伪代码中,cli_num被作为参数传给/ *** in/sta_qos.sh剧本。


通过检查剧本内容,我发现以下for循环,其中$sta_num用于保留cli_num的值。

南美洲2022世界杯预选赛赛程www.9cx.net)实时更新比分南美洲2022世界杯预选赛赛程数据,南美洲2022世界杯预选赛赛程全程高清免费不卡顿,100%原生直播,南美洲2022世界杯预选赛赛程这里都有。给你一个完美的观赛体验。


若是cli_num是一个很大的值,例如999999999,那么这个剧本险些会永远困在循环中,现实上,这就是陷入了一个无限的循环。通过向路由器发送这样的请求,会有许多这种剧本被执行并卡在循环中。 一段时间后,路由器会住手响应任何请求,这时,只能通过手动重启,它们才气再次正常事情。

时间线

●6月9日:向供应商讲述了10个下令注入破绽。

●6月11日:供应商修复了响应的破绽。

●6月11日:建议供应商使用一些分外的过滤器来防止此类破绽。

●6月28日:供应商凭证我们的建议举行了修复。

●7月9日:向供应商讲述了另外3个破绽(后门、缓冲区溢出、DoS)。

●7月23日:供应商举行了修复。

DLink DIR-1960

除了PROLiNK路由器外,我们还在DIR-1960固件上运行了该工具。这一次,该工具返回了近200个检测效果。然而,在对效果举行筛查后,发现只有4个是通过HNAP API的下令注入破绽(我们已经在前面讲述过了),而且所有这些都需要认证。(由此看来,在消除假阳性方面,另有很大的改善空间!)

对于HNAP,这里简朴先容一下:它是Home Network Administration Protocol的首字母缩写,它现实上就是一个基于SOAP的协议,用于与路由器治理面板举行通讯。

DLink DIR-X1560

接着,我决议也在DIR-X1560固件上试一下这个工具。上面的两个路由器都是基于MIPS架构的,但DIR-X1560是在ARM处置器上运行的。通过稍加调整,该工具就可以准确地剖析基于ARM的固件。由此证实,这个工具具有很好的架构兼容性,这让我很开心。

然而,由于抽象层许多,识别固件上的破绽并不那么简朴。有鉴于此,该工具在固件逆向工程中提供了伟大的辅助。我不确定固件所基于的框架简直切名称,但我想法在GitHub上找到了一些源代码,这异常有辅助,由于其中含有许多注释。我在源代码中找到的最靠近的术语是CMS(CPE治理系统)、CPE(客户驻地装备)和TR-069。然则,请注重,此repo不包罗任何特定于dlink的代码,因此需要执行一些逆向剖析。

在我看来,它类似于MVC(模子-视图-控制器)架构,只管它也可能不是这样的。


关于术语和缩略语的进一步注释,请参考这里。

DAL(数据聚合层)API,顾名思义,是用来与数据举行交互的,主要是转达路由器的设置。然则数据的现实存储是由MDM(内存数据模式)和ODL(工具调剂层)API完成的。DAL使用cmsObj_get和cmsObj_set函数(或其变体)作为与MDM/ODL的接口,以获取或设置某些工具的值。例如,获取IP_PING_DIAG MDM工具并将其存储在ipPingObj中,然后在修改后将其保留回来的代码如下所示:


下面注释用到的参数: 

◼MDMOID_DEV2_IP_PING_DIAG:一个枚举变量,指定接见IP_PING_DIAG工具。

◼iidStack:一些我们不需要体贴的内部数据。

◼ipPingObj:IP_PING_DIAG工具的内容。

除此之外,另有RCL(运行时设置层)和RUT(运行时使用工具)API。每个MDM工具(例如MDMOID_DEV2_IP_PING_DIAG)都有一个响应的RCL处置程序(rcl_dev2IpPingDiagObject)。每次挪用cmsObj_set时,ODL都市挪用该工具的RCL处置程序,它又会进一步挪用RUT的适用工具函数。

通过逆向剖析,我们发现其事情流程如下所示:    

1、用户提出一个POST请求,与HNAP API举行交互(例如SetTimeSettings)。

2、HNAP API处置程序挪用DAL API(例如:cmsDal_setNtpCfgDLink_dev2)。

3、DAL API挪用MDM/ODL API(cmsObj_set)来设置MDM工具(例如Dev2TimeDlinkObject)。         例如 cmsObj_set(MDMOID_DEV2_TIME_DLINK, &iidstack, 0, &timeDlinkObj)    

4、ODL API挪用RCL处置程序(例如rcl_dev2TimeDlinkObject)。

5、RCL处置程序挪用RUT API(例如rut_TZ_Nvram_update)。

若是我们查看上面提到的HNAP和RUT函数,我们会看到:


经由漫长的旅程,NTPServer参数最终泛起在一个转达给system的下令中。

正如我们在上面看到的,用户输入字符串(来自 HNAP)途径许多函数后,最终到达system挪用(在RUT中),从而导致下令注入破绽。若是我手动查看固件,除非我很幸运,否则我险些要花很长时间才气找到它。然而,在这个工具的辅助下,虽然无法直接实现HNAP到RUT的毗邻,但至少我能把相关的DAL函数列出来看看,从而节约了我许多时间。

DAL和RCL/RUT之间的关系

在这里,我们进一步科场一下DAL API与RCL/RUT API的关系。其中,cmsDal_setNtpCfgDLink_dev2(如前所述由HNAP API挪用的DAL API)的伪代码如下所示:


上面的代码片断展示了DAL函数设置/更新MDM工具的典型历程。请注重,cmsObj_get是以值为0x416的MDMOID(MDM工具ID)举行挪用的。由于没有源代码,我只看到值(0x416),而没有看到枚举名称(MDMOID_DEV2_TIME_DLINK),这些都是从固件中的函数名称和一些字符串推断出来的。

如前所述,当cmsObj_set被挪用时,ODL API将挪用响应的RCL处置程序,在这种情形下是rcl_dev2TimeDlinkObject。我没有研究cmsObj_set的实现细节,由于它相当庞大——需要执行许多检查和函数挪用。若是你有兴趣,可以考察这一行,它将挪用RCL处置函数。

获得MDMOID和RCL处置程序之间的映射关系并不难题,由于它存储在固件的OID表中,详细如下所示:


在这个表中,我们很容易看出0x416是TimeDlink MDM工具的MDMOID,而rcl_dev2TimeDlinkObject是RCL处置程序。在这里,我们也看到了一个叫做STL处置程序的器械,然则它并没有做太多事情。

现在,RCL处置程序rcl_dev2TimeDlinkObject看起来像下面这样:


我们看到,newMdmObj被转达给易受攻击的函数rut_TZ_Nvram_update(前面讲过)。而这个newMdmObj正是适才DAL函数转达给cmsObj_set的谁人timeDlinkObj。以是,DAL和RCL的关系如下图所示:


DAL会为cmsObj_set提供一个MDMOID和一个工具,然后    

◼MDMOID决议挪用哪个RCL处置程序

◼该工具被交给RCL处置程序举行处置

我们看到,从一个DAL函数中,找出哪个RCL函数被挪用并谴责事,由于我们不仅有MDMOID,而且还可以参考上面的OID表。但在寻找下令注入破绽时,步骤就反过来了。

首先,通过这个工具,我找到了可能有破绽的RCL/RUT函数,source点是函数的参数,sink点是system函数(或其变体)。这里没有什么新器械。然则现在,我需要找到接见相关MDM工具的DAL函数。换句话说,就像上面一样,虽然我知道MDMOID,但这次,我不是找RCL处置程序,而是回覆下面的问题:哪些DAL函数用这个MDMOID挪用cmsObj_set?


早先,我使用的是一种笨方式:逐一查看cmsObj_set的交织引用,直到找到一个被挪用的MDMOID准确为止。由于这里的交织引用太多,足足有200多个,几分钟后,我就放弃了。以是,我决议用这个工具来辅助我过滤出使用某个MDMOID的函数。稀奇是,我只体贴作为字符串/缓冲区的MDM工具字段。若是一个字段保留一个整数值,那么它对于下令注入或缓冲区溢出实在是没有用的。

回首一下,一个MDM工具的字符串字段是这样设置的:


以是,我不需要对这个工具做太多的修改,只需把source点设置为cmsObj_get,把sink点设置为cmsMem_free即可。效果,我乐成了。对于每个MDMOID,我过滤出了修改相关MDM工具的几个DAL函数。然后,我检查这些DAL函数的交织引用,看它们是若何被HNAP API挪用的,以找出用户输入是若何被传入MDM工具的。 借助于这个工具,事情效率获得了伟大提升,最后,我乐成地在这个固件中找到了4个下令注入破绽。

演示视频

现在是演示时间,演示视频地址见这里。

小结

现在,该工具仍处于开发的低级阶段:只能挖掘下令注入破绽。此外,在剖析像DIR-X1560这样庞大的固件时,仍然需要做一些手工事情,由于它不能自动判断出哪些HNAP函数是易受攻击的。我会继续对这个工具举行改善,希望有一天它能协助发现其他类型的破绽,如固件中的缓冲区溢出、UAF等破绽。

本文翻译自:https://starlabs.sg/blog/2021/08/identifying-bugs-in-router-firmware-at-scale-with-taint- *** ysis/

网友评论