摘要:被识别的模糊触发器在执行时产生有效但受约束的输入,从而实现物联网设备的有效模糊性。我们表明,对于大多数IOT设备和支持应用,识别和使用模糊触发器来产生错误的触发输入是非常重要的。
本文记录了阅读黛安论文的总结和阅读过程中不理解的一些补充。我是搬运工。
IEEE S&P 2021介绍会,Nilo Redini、Andrea Continella、Dipanjandas、Giulio de Pasquale、Noah Spahn、Aravind Machiry、Antonio Bianchi、Christopher Kruegel *和Giovanni Vigna *作者UC Santa Barbara University of Twente Purdue大学摘要:物联网(IoT)。设备已经扎根于数十亿人的日常生活中。因此,研究人员已经应用自动缺陷发现技术来提高他们的整体安全性。然而,由于提取和仿真定制固件的困难,black-box fuzzing通常是唯一可行的分析选项。不幸的是,这种解决方案大多会产生无效输入,这些输入很快会被目标物联网设备丢弃,并且不会穿透其代码。另一种提议的方法是利用配套应用程序(即通常用于控制物联网设备的移动应用程序)来生成well -结构化模糊输入。不幸的是,现有的解决方案会产生模糊的输入,这些输入受到app -端验证代码的约束,从而大大限制了发现漏洞的范围。在本文中,我们提出了一种新的方法来克服这些限制。我们的主要观察结果是,配套应用程序中存在可用于生成最佳(即有效但低于-约束)模糊输入的函数。这样的函数,我们称之为模糊触发器,在任何data -转换函数(例如,网络串行化)之前执行,但是在输入验证代码之后执行。因此,它们生成不受app -端净化代码约束的输入,同时,由于其无效格式,不会被所分析的物联网设备丢弃。我们设计并开发了DIANE,这是一种结合静态和动态分析的工具,可以在Android配套应用程序中找到模糊触发器,然后使用它们自动模糊物联网设备。我们使用DIANE来分析11个流行的物联网设备,并确定11个bug,其中9个是零天。我们的结果还表明,在不使用模糊触发器的情况下,不可能为许多设备生成bug -触发输入。摘要:物联网(IoT)设备已经在数十亿人的日常生活中扎根。因此,研究人员应用自动错误发现技术来提高其整体安全性。然而,由于很难提取和模拟定制固件,黑盒模糊测试通常是唯一可行的分析选项。不幸的是,这种解决方案通常会产生无效的输入,这些输入会很快被目标IOT设备丢弃,并且不会穿透它的代码。另一个建议的方法是通过使用支持应用程序(即通常用于控制IOT设备的移动应用程序)来生成结构良好的模糊测试输入。不幸的是,现有解决方案生成的模糊输入受到应用程序端验证码的限制,这极大地限制了所发现漏洞的范围。在本文中,我们提出了一种新的方法来克服这些局限性。我们的主要观察结果是,在支持应用程序中,存在可用于生成最佳(即,有效但不充分的约束)模糊输入的函数。这种函数,我们称之为模糊触发器,在任何数据转换函数(比如网络序列化)之前执行,但是在验证码输入之后。因此,它们生成的输入不受应用端清理代码的约束,也不会因格式无效而被分析的物联网设备丢弃。我们设计开发了DIANE,这是一个静态和动态分析相结合的工具,可以在Android支持的应用中找到模糊测试触发器,然后利用它们对物联网设备进行自动模糊测试。我们使用DIANE分析了11款流行的IOT设备,发现了11个错误,其中9个是零日漏洞。我们的结果还表明,如果不使用模糊触发器,就不可能为许多设备产生触发错误的输入。
大多数IOT设备具有配套应用程序(即,用于与设备交互的移动应用程序),其包含为相应设备生成有效输入的必要机制。基于这种观察,陈等人提出了一个工具IoTFUZZER(本文很多部分都是用IoTFuzzer来比较的,建议先看完这篇文章),利用设备的配套应用来模糊物联网设备。IoFuzzer分析伴随应用程序,并检索将应用程序的用户界面(UI)连接到网络相关方法或数据编码方法的所有路径。然后,IoTFuzzer对处理这些路径上的用户输入的第一个函数的参数进行模糊化,从而为物联网设备生成有效的模糊输入。虽然这种方法比通过网络直接发送到IOT设备的数据的随机模糊化产生更好的结果,但在实践中,它在从UI获得变量之后,在应用程序执行任何输入验证或数据处理之前立即变异变量。因此,当应用程序净化提供的输入时,IoTFuzzer的有效性会受到很大影响。我们的实验(IV-E部分)显示,51%的物联网应用执行应用端输入验证。事实上,最近的研究表明,移动应用程序经常执行输入验证来触发不同的行为[86]。由于这些原因,IoTFuzzer的方法无法生成约束不足(即不受应用端消毒影响)但结构良好(即被物联网设备接受)的模糊输入,可以到达更深的代码位置,发现更多漏洞。我们所做的。在本文中,我们提出并实现了一种使用支持应用程序为分析设备生成输入的方法。为了克服IoTFuzzer的局限性,我们精确地确定(并模糊)支持应用程序中的最佳代码位置,从而为物联网设备生成有效但有限的输入。我们的方法将应用程序的执行视为一系列将用户引入的数据(例如,通过应用程序的UI)转换为网络数据的功能。我们的直觉是,这个序列中的第一个函数通常将用户输入转换为内部数据结构,并生成受应用程序端验证约束的数据。相反,这个序列中的最后一个函数对用户数据进行完全编码,并在网络上将其序列化。我们的方法的新颖性在于通过调用物联网支持应用程序中的特定函数来隐藏物联网设备。我们称这些函数为模糊触发器。在调用时,模糊触发器生成的输入不受应用端验证的约束,具有良好的结构,因此不会立即被模糊IOT设备丢弃。我们的方法使用静态和动态分析的新组合,并执行两个主要步骤:I)模糊触发识别和ii)模糊化。为此,首先,我们在应用程序中自动检索向IOT设备发送数据的功能。然后,对于这些函数中的每一个,我们构造一个进程间向后切片,我们动态地分析它以最终识别模糊触发器。最后,我们使用动态工具,用不同的参数反复调用这些模糊触发器。这会产生网络数据流,模糊IOT设备的功能,最终找到漏洞。我们在一个名为DIANE的工具中实现了我们的方法,并测试了不同类型和制造商的11个流行的IOT设备。DIANE正确识别了模糊触发器,并成功识别了11个bug,其中9个是以前未知的漏洞。此外,我们比较了DIANE和IoTFuzzer,结果表明模糊触发器的识别对于产生导致崩溃的约束输入是非常重要的。总之,我们做出了以下贡献:我们提出了一种识别模糊触发器的方法,模糊触发器是应用控制流中介于应用端验证逻辑和数据编码函数之间的函数。执行时,被识别的模糊触发器产生有效但受约束的输入,从而实现IOT装置的有效模糊性。我们使用我们的方法实现了DIANE,一个用于物联网设备的自动黑盒模糊化器。我们针对11种流行的现实网络设备评估了我们的工具。在我们的实验中,我们表明,通过识别模糊触发器并使用它们为所分析的设备生成输入,我们可以有效地发现漏洞。具体来说,我们在5种不同的设备中发现了11个漏洞,其中9个是以前未知的。我们表明,对于大多数IOT设备和支持应用,识别和使用模糊触发器来产生错误的触发输入是非常重要的。
激励我们的方法并说明它解决的挑战,考虑图1中的代码片段。应用程序使用PTZ方法(第2行)向IOT摄像机发送位置命令(即空间坐标)。为此,PTZ调用本地函数SendMsg(第7行),该函数准备要发送的数据(第15行)并将其存储在共享缓冲区中(第16行)。同时,另一个线程从同一个缓冲区读取数据(第20行),并向设备发送命令(第21行)。请注意,IOT相机需要一个密码来验证命令,应用程序对密码字符串执行完整性检查(第5行和第6行)。这个例子显示了从配套应用程序生成物联网输入时必须面临的两个关键挑战:首先,应用程序使用结构化数据与IoT设备通信,这些数据由已知协议(如HTTP)或供应商定义的自定义协议编码。不符合预期格式的消息将被设备立即丢弃,因此不会在其代码中触发深度错误。在这个例子中,应用程序使用函数prepare_msg(第15行)来创建一个结构良好的消息。其次,尽管生成正确结构化的输入非常重要,但有效的方法必须避免生成受应用程序端验证码约束的输入。在本例中,函数PTZ(第2行)禁止密码包含字符&和”。然而,这些字符的存在对于生成碰撞触发的模糊输入可能非常重要。作者对IoTFuzzer的看法是,通过使用支持应用程序,以设备可以处理的格式生成模糊输入。这意味着,在应用程序被“打包”并发送到设备之前,需要对输入值进行变异。虽然这是真的,但我们的关键见解是,在应用程序打包输入之前和应用程序执行任何输入验证之后,突变确实必须发生。请注意,在表达式app-side -验证中,我们指的是应用程序对发送到IOT设备的数据施加的所有类型的约束。这些约束可能是由典型的清理检查(例如,限制字符串的长度)或生成的请求中硬编码的参数(例如,JSON对象中硬编码的属性)强加的。我们的工作填补了这一空白:我们确定了生成输入的战略执行点,这些输入不受应用程序逻辑强加的约束的影响。为了实现这一目标,我们分析了物联网设备的支持应用,重点是确定有效的模糊触发器:当用作模糊入口点时,这些函数可以最大化设备固件上执行的唯一代码量,这可能会触发安全相关的bug。例如,应用程序被执行为从UI接收数据并通过网络发送数据的一系列功能。一方面,如果模糊化的函数离UI太近,那么模糊化是无效的,因为应用端验证可能会出现在后期执行中。另一方面,选择离数据放入网络的点太近的功能可能是无效的。事实上,早期应用的一些特定于协议的数据转换将被跳过,这将导致物联网设备丢弃生成的输入。在图1中,函数sendMsg表示一个模糊触发器。我们的方法依赖于动态和静态分析的结合来自动识别这些模糊触发器,而无需任何关于被分析的物联网设备所使用的固件或网络协议的先验知识。此外,以前的工作[25]依赖于特定的输入源(例如,应用程序UI中的文本框)来指导其分析,并且不改变从未指定的源生成的数据(例如,通过由计时器触发的配套应用程序的固件更新)。我们的自底向上方法(在第3节中解释)没有对输入源做任何假设,所以它更通用。我们在本节中讨论的示例是在Wansview应用程序中实现的代码的简化版本。我们还注意到,应用端验证在现实应用中非常普遍,我们描述的挑战不仅仅适用于这个例子。
方法我们的方法不做任何关于应用程序的用户界面如何影响发送到受控IOT设备的数据的假设,并且避免了生成的数据的应用程序端净化。我们的分析并不是从UI处理功能的考虑开始的。相反,我们使用了“自下而上”的方法。具体来说,我们从识别可能产生网络流量的低级功能开始,然后在应用程序调用图中逐渐“上移”(即从低级网络功能到高级UI处理功能)。该方法允许我们识别产生有效但受限的输入的函数,并跳过由数据处理函数执行的所有清理检查。然后,我们使用这些函数(我们称之为模糊触发器)来有效地模糊所分析的物联网设备,同时监控它们的异常行为,这些行为指示何时触发错误。图二。使用静态分析,DIANE首先确定候选sendMessage函数。然后,它运行支持应用程序并重放记录的用户交互,以验证候选sendMessage功能。接下来,DIANE使用混合分析来识别数据转换函数,从而识别模糊触发器。最后,DIANE fuzzy测试已验证的触发器,并通过监控设备响应来识别崩溃。
模糊触发器的识别直观地说,模糊触发器是应用程序端验证逻辑和任何数据转换(例如,消息序列化)函数之间的函数,发生在应用程序的控制流中通过网络发送数据之前。准确地说,给定从输入源(例如,从UI接收的数据)到通过网络发送数据的函数的执行轨迹,模糊触发器被定义为支配所有数据转换函数然后支配所有输入验证函数的函数(我们参考调用图理论的支配概念,其中如果从入口节点到N的每条路径都必须经过D,则节点D支配节点N..另外,如果从N到出口节点的每条路径都经过P,我们说节点P支配N)。我们认为跟踪中的第一个数据转换函数是一个有效的模糊触发器,因为它支配所有其他数据转换函数(包括它自己)。我们的自底向上模糊触发识别算法由四个步骤组成:I)发送消息候选的识别,ii)发送消息的验证,iii)数据转换函数的识别,IV)top -链函数的收集。算法1列出了我们方法的伪代码。步骤1:识别1:sendmessage候选功能我们首先确定在支持应用程序中向IOT设备发送消息所需的逻辑功能。我们称这些函数为sendMessage函数。很难以自动化和可扩展的方式识别这些功能。支持应用程序可能依赖于调用由系统直接调用的特殊本机函数来实现sendMessage函数。此外,我们发现这些函数可能在多带线程中执行,这使得任何分析(静态或动态)都难以准确跟踪应用程序UI和sendMessage函数之间的数据流。然而,我们的关键见解是,支持应用程序必须包含一个“边界”函数,它位于应用程序的核心函数和外部组件(即Android框架或原生库)之间,当执行时,它最终会触发发送到IOT设备的消息。在本文的其余部分,我们将这些边界函数视为sendMessage函数。在我们的方法中,我们首先通过支持应用程序的静态分析来识别候选sendMessage函数。我们的目标是找到所有可能与被分析的IOT设备实现网络交互的边界方法(算法1中的函数getBorderMethods)。具体来说,我们收集了所有执行(至少)对本机函数的调用的方法,或者在Android框架中实现网络I/O函数的方法(详见附录A)。
附录A:为了在支持应用程序中找到初始sendMessage候选集,我们分析了它的内部表示。具体来说,我们选择所有那些包含原生方法(具有原生属性)(中间的Soot代表调用指令)或Android框架中已知的方法来实现网络I/O操作的调用(例如,java.lang.net,java.lang.net。或者android.net.*)。通过应用这些规则,我们获得了一个函数列表,这些函数在被调用时可能会向物联网设备发送网络消息。步骤2:发送一条消息来验证我们动态执行应用程序,并使用API挂钩来验证候选sendMessage函数。为了确定边界函数是否是有效的sendMessage函数,理论上我们可以I)多次动态执行该函数并检查每次是否产生网络流量,ii)阻止应用程序执行该函数并检查是否仍然产生网络流量。不幸的是,我们发现阻止一个函数执行并强迫一个应用程序多次执行同一个函数通常会导致应用程序本身崩溃。为了解决这些问题,我们采用了一种不同的基于时间戳和机器学习的方法。首先,我们动态挂钩所有候选函数并运行应用程序。当我们观察网络活动时,我们注册最后一个候选sendMessage函数。特别是,每次执行候选sendMessage函数时,我们将收集它的执行和观察到的网络活动之间的时间。然后,我们使用K-均值算法对观察到的运行时间度量进行聚类。具体来说,我们将候选分为两个簇(即k = 2)。因此,我们将每个特征向量计算为每个候选人经过时间的平均值、标准差和模式。基本原理是导致网络活动的函数具有较小的均值和标准差,因为它们受噪声的影响较小。最后,在sendMessage候选者中,我们选择平均运行时间最小的那些集群。在我们分析的下一步中,将只考虑集群中的sendMessage函数。该方法由算法1中的函数dynamicFilter表示。步骤3:数据转换函数的识别虽然sendMessage函数直观上是执行模糊化的良好触发器,但是应用程序可以在sendMessage函数之前执行的函数中应用数据转换。数据转换函数的一个典型示例由编码方法表示,该方法将整数列表作为输入,并将其序列化为字节序列。如前所述,模糊触发器是应用程序控制流中任何数据转换函数之前的函数。模糊数据转换函数和sendMessage函数之间的函数可能会生成无效输入,这些输入将被IOT设备丢弃。因此,为了找到模糊触发器,我们首先需要确定应用于发送数据的数据转换函数。这项任务提出了不同的挑战。首先,被发送的数据可能包含在一个类字段中,sendMessage函数引用该字段。理论上,这个字段可以设置在应用程序代码中的任何位置,包括其他线程。此外,对于每个字段,我们需要考虑它的父类,因为保存要发送的消息的变量可能被不同的类继承。在我们的方法中,我们考虑这些问题。首先,我们静态地确定存储sendMessage函数发送的数据的可能变量,并设置这些变量在应用程序中的代码位置(算法1中的函数getArgAndObjLocs)。为此,我们创建一个包含元组(v,cl)的集合Sv,其中v是sendMessage使用的变量(即sendMessage参数或sendMessage正文中引用的对象),cl是setting的代码位置。然后,我们确定数据转换函数。对于Sv中的每个tuple (v,cl)∈,我们执行一个静态的进程间反向切片(算法1中的第6行),以从任何函数中检索任何UI对象的值。然后,我们将计算出的程序片划分成函数作用域(第7行的getFunctionScopes)。给定一个程序片,函数作用域被定义为片内属于同一函数的顺序指令的子序列。对于每个收集的函数范围,我们执行活动分析:我们考虑函数范围中引用的变量(即局部变量和类字段),并计算存在于范围开始处的变量集和存在于范围结束处的变量集(第8行)。例如,如果一个函数是由片遍历的,那么函数作用域开头的变量就是在写之前读取的参数和类字段。范围末尾的变量是返回的变量以及创建或修改的类字段。为了确定数据转换函数,我们使用相关工作中讨论的观察结果,即这些函数增加了它们所消耗的数据的熵。因此,我们挂钩切片中标识的函数,并动态运行应用程序。并且计算在运行时对包含在Li F中的Li _ {f}的分布。Lif和l0f Lo _ { f } Lof中的每个变量v的数据的香农熵。(有关如何计算熵的更多详细信息,请参见附录C)。如果是基本变量(比如int)或者是已知类型(比如String、Integer、Float、Double),我们就把它包含的数据转换成字节表示,计算这个字节表的香农熵。相反,如果它是一个类字段,则检索其类定义,并考虑其类型为原始或已知的每个字段变量。然后,我们计算每个变量的熵,并根据活动集将它们添加到集合或集合中。最后,我们检查每个收集的函数的范围,并计算中所有变量的最大熵和中所有变量的最小熵之间的商(第11行)。如果它大于某个阈值(在我们的实验中设置为2,如前面的工作所建议的),我们认为该函数是一个数据转换函数(第12行)。补充熵相关知识:第四步:top -链函数集数据转换函数通常按照准确的顺序执行,为要发送到IOT设备的数据做好充分准备。例如,一个配套的应用程序可能用base64编码一些用户数据,然后将其封装在HTTP request X中..我们将数据转换函数序列称为转换数据链,并使用术语“顶级链函数top-chain”来指代序列中的第一个函数。如果修改变量f的内容最终会影响v的值,我们说顶链函数f会影响变量v,我们对影响sendMessage变量的顶链函数特别感兴趣。事实上,如果我们控制这些顶级链的变量,我们就可以控制发送到被分析的物联网设备的数据。特别是,这些数据是有效的(即,被IOT设备接受),并且不受不必要的应用程序输入验证的影响。因此,影响sendMessage变量的顶级链函数代表了模拟联网设备功能的最佳模糊测试触发器。为了识别顶链函数,我们构建在先前步骤(第13行)中检测到的每个数据转换函数的支配树(其中每个节点的子节点是直接受其支配的那些节点的图),并选择不受任何其他数据转换函数支配的那些数据转换函数(第16行)。最后,我们认为fuzzing触发了集合的顶级链功能。注意,如果没有数据转换函数支配SM消息函数,我们将SM视为模糊触发器(第14、15和16行)。例如,当伴随应用程序不包括数据转换功能时,这可能发生。最后,请注意,原则上,应用程序端清理代码可能存在于转换数据链的函数中。我们将在第5节讨论这一点。举个简单的例子,考虑图3,它代表了我们在8月份在智能锁设备上发现的数据链路之一。假设我们之前将sendToDevice标识为sendMessage函数,我们将{c}设置为可能包含要发送的数据的初始变量集,并确定设置c的代码位置,由于c是函数参数,我们检索sendMessage调用站点(第15行)并从调用站点向后引导程序片,直到函数解锁(第1行)。这是通过追溯变量e的数据流来实现的:sendToDevice使用变量e,这是调用函数encrypt的结果。然后,我们继续从encrypt函数的末尾向后切片,直到它的入口点,然后返回到sendCommand函数。最后,我们到达函数的入口点,并考虑其调用方继续切片(即函数unlock)。根据上面对函数作用域的定义,这个向后切片包含以下函数作用域:i)sendCommand:第15行;Ii)加密:6到9行;Iii)sendCommand:第12和13行;Iv)解锁:第3行;v)命令构造器(本例中不报告代码);以及vi)解锁:行1和行2。为了简洁起见,在下文中,我们只考虑相关的功能范围:ii)加密,iii)发送命令,以及vi)解锁。它们的活动变量集是:encrypt: L i f Li_{f} Lif ={b},L o f Lo _ { f } Lof = { enc }sendCommand: L i f Li_{f} Lif ={cmd},L o f Lo _ { f } Lof = { cmd }并解锁:L i f Li_{f} Lif ={},L o f Lo_{f} Lof ={cmd} .一旦我们确定了切片中函数的范围,我们运行应用程序并计算分配给每个活动变量的数据的熵。然后,我们计算每个函数范围引入的熵,并检查其值是否超过阈值。函数unlock没有引入任何熵,因为集合是空的。当集合为空时,我们不将该函数视为候选数据转换函数,因为它不接受任何输入。对于encrypt函数,B中存储的数据的熵是5.94,而enc中返回的数据的熵是53.16。由于熵δ大于我们的阈值(d ed _ {e} de = 53.16/5.94 > 2),我们将加密视为一种数据变换函数。此外,函数sendCommand引入了一个低熵(d e d_{e} de =1.03),因此它不被视为数据转换函数。最后,因为encrypt函数控制sendToDevice函数,所以encrypt是唯一的顶层链函数,并且被用作唯一的模糊触发器。UI模拟我们的方法多次执行同一个应用程序,在不同的运行中是一致的。因此,理想情况下,我们希望应用程序总是遵循相同的执行路径。为了实现这个目标,我们要求分析师运行应用程序一次,DIANE记录生成的UI输入。然后,通过使用RERAN,在后续操作中自动重放相同的输入。我们没有明确处理不确定性的其他来源,因为我们发现它们不会显著影响我们的方法。模糊中间数据转换函数。原则上,转换数据链路可以任意长。因为DIANE的目标是刺激联网设备的核心功能,所以我们的方法忽略了中间数据转换功能(即由顶链功能支配的数据转换功能),因为它们生成的消息可能会被IOT设备丢弃。但是,由于物联网设备在解码接收到的消息的过程中也可能包含bug,因此我们为DIANE提供了模糊所有中间数据转换功能的选项。类似地,DIANE提供了一个选项来直接混淆sendMessage函数,即使它是由顶级链函数控制的。在IV-C小节中,我们已经从经验中证明了模糊的sendMessage函数不会导致新bug的发现,反而会拖慢工具的执行速度。
模糊化在我们方法的第一阶段之后,我们获得一组模糊触发器,它们是模糊化器的输入。测试用例生成对于每个模糊触发器,我们通过改变已识别的模糊触发器的参数来生成一组测试用例,最后修改sendMessage函数发送的数据。我们以循环的方式一次模糊一个不同的模糊触发器。为了改变它的参数值,我们使用以下策略:字符串长度:我们改变字符串的长度来触发缓冲区溢出和越界访问。我们生成不同长度的随机字符串。数值:我们改变整数、双精度或浮点值的值,以引起整数溢出或越界访问。我们生成非常大的值,负值和零值。空值:我们提供空值是为了试图引起误解、未初始化的变量漏洞和空指针取消引用。数组长度:我们通过删除或添加元素来修改数组的内容。重要的是,我们不仅模糊基本变量(如int和float),而且模糊对象识别崩溃通过模糊对象成员变量。最近的一项研究表明,在没有侵入式物理访问的情况下,识别IOT设备的所有基于网络的服务故障是一项挑战。同时,获得对IOT设备的侵入式物理访问需要大量的工程工作,因为供应商通常会阻止这种类型的访问。由于这些原因,当设备被混淆时,DIANE将自动分析响应以识别崩溃。具体来说,DIANE首先执行应用程序的正常操作,并在正常活动期间监视设备的响应。然后,在混淆过程中,DIANE再次监控应用程序和设备之间的网络流量。如果满足以下任一条件,则认为输入可能导致崩溃。连接已断开。如果设备突然终止正在进行的连接,我们认为这表明设备有错误。具体来说,对于TCP连接,我们寻找应用程序发送FIN包但没有收到响应(FIN+ACK)的情况,然后发送两个或更多SYN包序列。HTTPInternalServerError(500).应用程序通过HTTP与设备通信,设备返回内部服务器错误(状态代码500)的实例被视为设备进入故障状态的信号。网络流量不规则。如果应用程序和设备之间交换的数据量超过阈值,我们将保存当前导致崩溃的输入。我们的直觉是,当设备进入故障状态时(例如,由于崩溃),它通常暂时对应用程序不可用,从而大大减少了交换的数据量。在我们的实验中,我们从经验上验证了当数据交换量小于50%(与正常运行相比)时,设备会出现异常。因此,我们将阈值设置为50%。心率监测。当混淆一个给定的设备时,我们不断地ping它并监控它的响应时间。我们报告任何导致响应时间超过特定阈值的崩溃引发的输入。在我们的实验中,我们将时间设置为10秒,因为根据我们的经验,在正常情况下,IOT设备的平均响应时间在1秒以内。最后,我们使用另一款Android智能手机,我们称之为watchdog设备,从中立的角度监控IOT设备的状态(也就是说,我们没有检测到该设备上的支持应用程序)。我们在看门狗设备上运行支持应用,并自动重放之前记录的UI输入,从而定期运行不同的物联网设备功能。然后,人类分析师可以观察看门狗设备执行的功能(例如,按下灯开关的UI按钮)是否对物联网设备产生了预期的效果(例如,打开灯)。如果检测到意外的效果,说明Diane可以让被分析的设备进入无效状态。
在原始实验中,作者使用DIANE对11种不同的物联网设备进行模糊,并与现有的网络级模糊设备进行比较。这里只介绍与LOTFUZZER比较的实验。
为了将我们的方法与IOT fuze进行比较,我们联系了作者并得到了他们的工具。我们还试图购买用于评估IoTFuzzer的相同设备,但我们只能获得设备3和6,因为其他设备仅在中国可用。IoTFuzzer需要手动干预,以适应不同的设备和支持应用程序。特别是,我们必须I)将分析范围(即挂钩函数的数量)限制在Android应用程序中现有的Java包的子集内——以使分析易于处理并避免崩溃——以及ii)手动指定任何加密应用程序中现有的函数。在这个手动配置步骤之后,我们可以为我们可以获得的设备(设备3和设备6)复制原始文档中显示的结果。另外,IoTFuzzer基于TaintDroid,其最新版本最高支持Android 4.3 (2012)。由于这个原因,我们无法分析设备10和设备11,因为它们的支持应用程序需要更新版本的Android SDK。我们的结果如表3所示。IoTFuzzer销毁了设备3和6(原始文件中使用的两个设备)和设备2,但没有在其他八个设备中发现任何缺陷。对于设备2,IoTFuzzer确定了五个要进行模糊测试的功能。我们手动分析了这些功能,发现其中有三个是误报,因为它们是用来在Android手机上保存用户信息的。为了证实我们的发现,我们模糊了这些函数,并观察到它们不会产生网络流量。然后,我们继续模糊剩下的两个函数,即HouseExtProperty和changeCameraUsernamePassword。当模糊化HouseExtProperty函数一个小时时,我们发现生成的消息被定向到供应商的云,而不是实际的设备,因此没有为物联网设备生成有意义的模糊化输入。changeCameraUsernamePassword函数用于更改物联网设备上的凭据。我们混淆了这个功能24小时,IoTFuzzer重新发现了DIANE在这个设备上发现的七个bug中的两个。为了更好地理解为什么IoTFuzzer遗漏了我们发现的一些错误,我们检查了changeCameraUsernamePassword(如图4所示)。该函数调用函数cam.changeUsername和cam.changePassword分别生成更改用户名和密码的请求(这些函数的第一个参数代表当前摄像机的用户名)。此外,变量cam是应用程序用来存储详细相机信息(例如,相机型号)的内部结构,其内容不受从应用程序UI接收的数据的直接影响。另一方面,newUsr和newPwd都包含通过应用程序UI传递的用户数据。由于IoTFuzzer只对包含用户数据的函数参数进行模糊测试(调用函数时),所以它对第二个和第三个函数参数进行模糊测试,但不对第一个进行模糊测试。不幸的是,正如我们在IV-G节中详细解释的,如果伴随应用程序生成的请求包含长度大于某个缓冲区大小的用户名,则摄像机包含可被利用的错误。但是,通过模糊测试changeCameraUsernamePassword的最后两个参数,IoTFuzzer只会更改cam.changeUsername和cam.changePassword的第二个参数——分别是newUsr和newPwd——而不会更改它们的第一个参数(cam.user),这将导致一个额外的错误。这个案例突出了IoTFuzzer方法的局限性,因为它表明假设发送到设备的所有数据都直接来自应用程序的UI是无效的。另一方面,我们的自底向上方法从sendMessage函数(参见第三节)引导其分析,该函数独立于输入源,因此更具一般性。此外,changeCameraUsernamePassword只允许您修改特定相机型号的凭据(第2行,cam.checkCameraModel)。这意味着IoTFuzzer无法有效模糊其他相机型号。通过识别控制流中更深层次的模糊触发器,DIANE绕过了这一检查,并且独立于设备版本而有效。对于设备ID 7和8,IoTFuzzer导致应用程序立即崩溃,因为有太多的挂钩函数。我们将分析范围缩小到只包含与设备交互的代码的包,但应用程序无论如何都会崩溃。因此,我们不能在这些设备上运行IoTFuzzer。
图4 IoTFuzzer为Insteon摄像机(设备ID 2)找到模糊函数图5 IoTFuzzer为Foscam摄像机支持应用程序(设备ID 4和5)找到模糊函数。对于装置ID 9,IOT引信确定三个功能模糊。然而,我们发现这些功能都是误报,因为它们是用来记录智能手机上的用户数据的。对于ID为1、ID为4和ID为5的设备(在表III中标记),IoTFuzzer无法识别任何要混淆的函数。原因是为了找到一个fuzz函数,IoTFuzzer必须首先找到应用程序的UI元素和Android的socket发送函数之间的数据流。但在这些设备中,“发送”功能是用原生代码实现的(即这些设备不依赖于Android的发送功能)。因为IoTFuzzer无法识别本机代码中的发送函数,所以无法识别最终会产生网络流量的UI事件,所以不会产生任何有效的模糊输入。DIANE通过使用动态分析克服了这一限制,并发现了产生网络流量的边界函数,如第III -A节所述..为了帮助IoTFuzzer并直接与我们的工具进行比较,我们硬编码了DIANE在IoTFuzzer中找到的发送功能,并重新分析了这些设备。对于设备ID 4和5,IoTfuzzer为Fuzz确定一个候选函数,应用程序使用它来更改设备的凭证,类似于设备ID 2。如图5所示,这个函数实现了一个检查(通过confirm_ credentials ),并要求用户提供凭证才能继续。因此,模糊不会对相机产生任何有意义的输入,因为检查会连续失败。相反,DIANE被认为是模糊触发函数changeUserAndPwd,它不受任何检查的影响(因为它在检查凭证信息后是模糊的),并在模糊时有效地向摄像机发送命令。这些案例突出了IoTFuzzer方法的另一个局限性,因为它们表明模糊应用程序控制流中处理用户提供的数据的第一个函数是无效的。对于设备ID 1,IoTFuzzer识别一个名为setUser的函数,该函数将用户的登录信息发送到设备。在这种情况下,该功能受到检查的保护,该检查禁止用户的密码包含某些特殊字符(如“&”)。我们已经对该功能进行了24小时的模糊化处理,设备中没有记录到任何异常。同样在这个例子中,DIANE在任何客户端检查之后选择了应用控制流中更深层次的功能。这是成功发现(零日)bug所必需的。一般来说,DIANE只在两种情况下(设备ID 3和6)表现得和iFuzzer一样好,在所有其他情况下都优于iFuzzer,因为iFuzzer无法识别任何有意义的发送函数,或者因为它不产生任何导致崩溃的输入。评估强调在支持应用中谨慎选择正确模糊函数的重要性,appside的消毒检查会阻碍模糊活动的效果。伴随应用中应用侧消毒的频率加剧了这个问题。例如(如表II所示),在我们的数据集中,我们发现11个应用程序中至少有7个包含健全性检查。我们在IV-E节中进一步测量了这一方面。
局限性和未来工作虽然我们已经解决了实现物联网设备黑盒模糊化的主要挑战,但我们的整体方法和DIANE的实现仍然存在一些局限性。当应用端健全性检查在原生代码、数据转换函数或者直接在sendMessage函数中实现时,我们目前无法绕过这些检查。尽管我们承认这种检查可能存在于任何这些代码类中,但我们手动验证数据集中的任何应用程序不包含这些类别中的健全性检查。实际上,如前面的工作[16]所示,原生代码通常不用于实现主应用的逻辑,而是用在库助手功能中。请注意,与之前的作品不同,这并不意味着DIANE完全不能处理原生代码。事实上,即使sendMessage功能是在本地实现的,DIANE也可以识别它,并模糊其模糊触发器。但是,如果上面的任何一个代码都有健全性检查,那么模糊化的效果就很差。像任何基于动态分析的方法一样,DIANE的代码覆盖率是有限的,也就是说,它不能识别应用程序尚未执行的模糊触发器。为了缓解这种限制,我们手动模拟应用程序触发大部分可用功能,并在真实的智能手机上进行分析。DIANE当前的实现不能混淆嵌套的Java对象。我们计划在今后的工作中解决这个问题。可以增强DIANE自动发现语义漏洞(比如智能锁开门而不是锁门)。目前,该功能是半自动的,因为它需要分析师检查并与看门狗设备交互。
结论本文研究模糊设备在物联网中的有效性。一方面,随机且模糊地发送到设备的网络数据包需要知道设备接受的数据格式,这在设备使用自定义固件时很少能得到。另一方面,由于应用程序端代码的限制,通过使用支持移动应用程序的UI来生成语法正确的消息的方法是无效的。相反,我们提出了一种介于网络级模糊性和用户界面模糊性之间的新方法。我们的方法旨在识别模糊触发器,它是物联网支持应用程序中的代码部分,在输入验证之后和任何数据转换函数之前执行,并最大化模糊结果。我们在一个名为DIANE的工具中实现了我们的方法,并在11个不同品牌的真实网络设备上对其进行了评估。DIANE的性能优于目前最先进的方法,能成功检测出现有模糊程序无法触发的关键错误(9 0day)。
评论前必须登录!
注册