物联网设备模糊:DIANE:识别应用程序中的模糊触发器,为物联网设备生成受限制的输入

  本文记录阅读DIANE论文的内容总结和一些阅读过程中不理解地方的补充,我是搬运工。

简介

发表会议 IEEE S&P 2021
作者 Nilo Redini∗, Andrea Continella†, Dipanjan Das∗, Giulio De Pasquale∗, Noah Spahn∗, Aravind Machiry‡,Antonio Bianchi‡, Christopher Kruegel∗, and Giovanni Vigna∗
作者单位 ∗UC Santa Barbara †University of Twente ‡Purdue University

摘要

  Abstract: Internet of Things (IoT) devices have rooted themselves in the everyday life of billions of people.Thus, researchers have applied automated bug finding techniques to improve their overall security.However, due to the difficulties in extracting and emulating custom firmware, black-box fuzzing is often the only viable analysis option.Unfortunately, this solution mostly produces invalid inputs, which are quickly discarded by the targeted IoT device and do not penetrate its code.Another proposed approach is to leverage the companion app (i.e., the mobile app typically used to control an IoT device) to generate well-structured fuzzing inputs.Unfortunately, the existing solutions produce fuzzing inputs that are constrained by app-side validation code, thus significantly limiting the range of discovered vulnerabilities.
In this paper, we propose a novel approach that overcomes these limitations.Our key observation is that there exist functions inside the companion app that can be used to generate optimal (i.e., valid yet under-constrained) fuzzing inputs.Such functions, which we call fuzzing triggers, are executed before any data-transforming functions (e.g., network serialization), but after the input validation code.Consequently, they generate inputs that are not constrained by app-side sanitization code, and, at the same time, are not discarded by the analyzed IoT device due to their invalid format.We design and develop DIANE, a tool that combines static and dynamic analysis to find fuzzing triggers in Android companion apps, and then uses them to fuzz IoT devices automatically.We use DIANE to analyze 11 popular IoT devices, and identify 11 bugs, 9 of which are zero days.Our results also show that without using fuzzing triggers, it is not possible to generate bug-triggering inputs for many devices.
  摘要:物联网 (IoT) 设备已扎根于数十亿人的日常生活中。因此,研究人员已应用自动错误查找技术来提高其整体安全性。然而,由于难以提取和模拟自定义固件,黑盒模糊测试通常是唯一可行的分析选项。不幸的是,该解决方案大多会产生无效输入,这些输入会被目标物联网设备迅速丢弃并且不会渗透其代码。另一种建议的方法是利用配套应用程序(即通常用于控制物联网设备的移动应用程序)来生成结构良好的模糊测试输入。不幸的是,现有的解决方案产生的模糊输入受到应用端验证代码的限制,从而大大限制了已发现漏洞的范围。
  在本文中,我们提出了一种克服这些限制的新方法。我们的主要观察结果是配套应用程序中存在可用于生成最佳(即有效但约束不足)模糊输入的函数。此类函数,我们称为模糊触发器在任何数据转换函数(例如,网络序列化)之前执行,但在输入验证代码之后执行。因此,它们生成的输入不受应用程序端清理代码的约束,同时也不会由于格式无效而被分析的 IoT 设备丢弃。我们设计和开发了 DIANE,这是一种结合静态和动态分析的工具,用于在 Android 配套应用中查找模糊测试触发器,然后使用它们自动对 IoT 设备进行模糊测试。我们使用 DIANE 分析了 11 个流行的物联网设备,并确定了 11 个错误,其中 9 个是零日漏洞。我们的结果还表明,如果不使用模糊触发器,就不可能为许多设备生成触发错误的输入。

导言

  大多数物联网设备都有配套应用程序(即,用于与设备交互的移动应用程序),其中包含为相应设备生成有效输入的必要机制。基于这一观察,Chen等人提出了一种工具IoTFuzzer(本文中很多部分与IOTFUZZER进行了对比,建议先去看一下这篇),该工具通过利用IoT设备的配套应用程序来模糊IoT设备。IoFuzzer分析配套应用程序并检索将应用程序的用户界面(UI)连接到网络相关方法或数据编码方法的所有路径。然后,IoTFuzzer将处理这些路径上的用户输入的第一个函数的参数模糊化,从而为IoT设备生成有效的模糊化输入。
  虽然这种方法比通过网络直接发送到物联网设备的数据随机模糊化产生更好的结果,但在实践中,它在由UI获取变量后,在应用程序执行任何输入验证或数据处理之前,立即对变量进行变异。因此,当应用程序对提供的输入进行净化时,IoTFuzzer的有效性受到很大影响。我们的实验(第IV-E节)表明,51%的IoT应用程序执行应用程序端输入验证。事实上,最近的研究表明,移动应用程序经常执行输入验证来触发不同的行为[86]。由于这些原因,IoTFuzzer的方法无法产生约束不足(即,不受应用程序端消毒的影响)但结构良好(即,被IoT设备接受)的模糊输入,这可以到达更深的代码位置,发现更多漏洞。
  我们的做法。在本文中,我们提出并实现了一种利用配套应用程序为分析设备生成输入的方法。为了克服IoTFuzzer的局限性,我们精确地确定(并模糊)配套应用程序中的最佳代码位置,从而为IoT设备生成有效但受限制的输入。
  我们的方法将应用程序的执行视为将用户引入的数据(例如,通过应用程序的 UI)转换为网络数据的一系列函数。我们的直觉是,这个序列中的第一个函数通常将用户输入转换为内部数据结构,生成受应用端验证约束的数据。相比之下,此序列中的最后一个函数对用户数据进行了充分编码,并在网络上对其进行了序列化。
  我们的方法的新颖之处在于通过调用IoT配套应用程序中的特定功能来模糊IoT设备。我们称这些函数为模糊触发器。调用时,模糊触发器生成的输入不受应用程序端验证的约束,同时结构良好,因此不会立即被模糊物联网设备丢弃。
  我们的方法使用了静态和动态分析的新组合,并执行两个主要步骤:i)模糊触发器识别和ii)模糊化。为此,首先,我们自动检索应用程序中向物联网设备发送数据的功能。然后,对于这些函数中的每一个,我们构建一个过程间向后切片,我们动态地分析它以最终识别模糊触发器。最后,我们使用动态工具使用不同的参数重复调用这些模糊触发器。这会生成网络数据流,模糊物联网设备的功能,最终发现漏洞。
  我们在一个名为DIANE的工具中实现了我们的方法,并针对11个不同类型和不同制造商的流行物联网设备进行了测试。DIANE正确识别了模糊触发器,并成功识别了11个bug,其中9个是以前未知的漏洞。此外,我们将DIANE与IoTFuzzer进行了比较,结果表明,模糊触发器的识别对于生成受约束的、导致崩溃的输入至关重要。
总之,我们作出以下贡献:
  •我们提出了一种识别模糊触发器的方法,模糊触发器是应用程序控制流中位于应用程序端验证逻辑和数据编码功能之间的功能。执行时,识别的模糊触发器产生有效但受约束的输入,从而实现物联网设备的有效模糊。
  •我们利用我们的方法实施DIANE,一种用于物联网设备的自动黑匣子模糊器。
  •我们针对11种流行的真实物联网设备评估我们的工具。在我们的实验中,我们表明,通过识别模糊触发器并使用它们为分析的设备生成输入,我们可以有效地发现漏洞。具体而言,我们在5个不同的设备中发现了11个漏洞,其中9个以前未知。
  •我们表明,对于大多数物联网设备和配套应用程序,识别和利用模糊触发器对于生成错误触发输入至关重要。

动机

  为了激发我们的方法并举例说明它解决的挑战,请考虑图 1 中的代码片段。该应用程序利用方法 PTZ(第 2 行)将位置命令(即空间坐标)发送到物联网摄像机。为此,PTZ 调用本机函数 SendMsg(第 7 行),该函数准备要发送的数据(第 15 行),并将其存储到共享缓冲区中(第 16 行)。同时,另一个线程从同一个缓冲区读取数据(第 20 行),并向设备发送命令(第 21 行)。请注意,物联网摄像头需要密码来验证命令,应用程序对密码字符串(第 5 行和第 6 行)执行完整性检查。此示例显示了从配套应用程序生成 IoT 输入时必须面临的两个关键挑战:
  首先,应用程序使用结构化数据与物联网设备通信,这些数据以已知协议(如HTTP)或供应商定义的自定义协议编码。不符合预期格式的消息会被设备立即丢弃,因此不会在其代码中触发深层错误。在本例中,应用程序使用函数prepare_msg(第15行)创建结构正确的消息。
其次,尽管生成正确结构的输入至关重要,但有效的方法必须避免生成受应用程序端验证代码约束的输入。在本例中,函数PTZ(第2行)禁止密码包含字符&和'。然而,这些字符的存在可能对生成碰撞触发模糊输入至关重要。
在这里插入图片描述
  IoTFuzzer作者的见解是利用配套应用程序以设备可以处理的格式生成模糊输入。这意味着在应用程序“打包”并将其发送到设备之前,需要对输入值进行变异。虽然这是真的,但我们的关键洞察是,变异确实必须在应用程序打包输入之前发生,也必须在应用程序执行任何输入验证之后发生。请注意,在表达式app-side-validation中,我们指的是应用程序对发送到物联网设备的数据施加的所有类型的约束。这些约束可能由典型的清理检查(例如,限制字符串的长度)或在生成的请求中硬编码的参数(例如,JSON对象中硬编码的属性)施加。
  我们的工作填补了这一空白:我们确定了产生不受应用程序逻辑施加的约束影响的输入的战略执行点。为了实现这一目标,我们分析了IoT设备配套应用程序,重点是确定有效的模糊触发:当用作模糊化入口点时,这些功能可以最大限度地增加设备固件上执行的唯一代码量,从而可能触发与安全相关的bug。举例来说,将应用程序执行为从UI接收数据并通过网络发送数据的函数序列。一方面,如果fuzzed函数过于接近UI,则fuzzing是无效的,因为应用程序端验证可能会在稍后的执行中出现。另一方面,选择一个太靠近数据被放到网络上的点的函数可能是无效的。事实上,在执行早期应用的某些特定于协议的数据转换将被跳过,从而导致IoT设备丢弃生成的输入。在图1中,函数sendMsg表示一个模糊触发器。
  我们的方法依靠动态和静态分析的组合自动识别这些模糊触发器,而不需要任何关于所分析物联网设备所使用的固件或网络协议的先验知识。此外,之前的工作[25]依赖于特定的输入源(例如,应用程序UI中的文本框)来引导其分析,并且不会改变从未指定源生成的数据(例如,通过计时器触发的配套应用程序进行固件更新)。我们的自下而上方法(在第三节中解释)没有对输入源进行任何假设,因此更为通用。
  我们在本节中讨论的示例是在Wansview应用程序中实现的代码的简化版本。我们还注意到,应用程序端验证在现实世界的应用程序中非常普遍,我们描述的挑战不仅适用于本例。

方法

  我们的方法没有对应用程序的用户界面如何影响发送到受控物联网设备的数据做出任何假设,并且避免了对生成的数据进行应用程序端净化。我们的分析不是从考虑UI处理功能开始的,相反,我们使用了“自下而上”的方法。具体来说,我们从识别可能产生网络流量的低级功能开始,然后逐步在应用程序调用图中“向上”移动(即,从低级网络功能到高级UI处理功能)。这种方法允许我们识别产生有效但受约束的输入的函数,跳过数据处理函数执行的所有清理检查。然后,我们使用这些函数(我们称之为模糊触发器)有效地模糊所分析的物联网设备,同时监控其异常行为,这些异常行为指示何时触发错误。
在这里插入图片描述
图2。使用静态分析,DIANE 首先确定候选的 sendMessage 函数。然后,它运行配套应用程序,重放记录的用户交互,以验证候选的 sendMessage 函数。接下来,DIANE 使用混合分析来识别数据转换功能,从而识别模糊触发器。最后,DIANE 通过监控设备响应对经过验证的触发器进行模糊测试并识别崩溃。

模糊触发器识别

  直观地说,模糊触发器是在应用程序的控制流中位于应用程序端验证逻辑和通过网络发送数据之前发生的任何数据转换(例如,消息序列化)功能之间的函数。准确地说,给定从输入源(例如,从UI接收的数据)到通过网络发送数据的函数的执行跟踪,模糊触发器定义为支配所有数据转换函数和后支配所有输入验证函数的函数(我们参考调用图理论的支配概念,其中如果从入口节点到 n 的每条路径都必须经过 d,则节点 d 支配节点 n。此外,如果从 n 到出口节点的每条路径都经过 p,则我们说节点 p 后支配 n)。我们认为跟踪中的第一个数据转换函数是有效的模糊触发,因为它支配着每个其他数据转换函数(包括它本身)。
  我们的自底向上模糊触发识别算法由四个步骤组成:i)发送消息候选识别,ii)发送消息验证,iii)数据转换函数识别,以及iv)Top-Chain 函数收集。算法1列出了我们方法的伪代码。
步骤1:sendmessage候选函数识别
  我们首先在配套应用程序中确定实现向物联网设备发送消息所需逻辑的功能。我们称这些函数为sendMessage函数。以自动化和可扩展的方式识别这些功能是困难的。配套应用程序可能依赖于直接调用系统调用的特殊本机函数来实现sendMessage函数。此外,我们发现这些函数可能在单独的线程中执行,这使得任何分析(静态或动态)都难以精确跟踪应用程序UI和sendMessage函数之间的数据流。然而,我们的关键洞察是,配套应用程序必须包含“边界”功能,位于应用程序核心功能和外部组件(即Android框架或本机库)之间,当执行时,最终触发发送至物联网设备的消息。在本文的其余部分,我们将这些边界函数视为我们的 sendMessage 函数。
  在我们的方法中,我们首先通过静态分析配套应用程序来识别候选sendMessage函数。我们的目标是找到可能实现与所分析物联网设备的网络交互的所有边界方法(算法1中的函数getBorderMethods)。具体来说,我们收集了所有执行(至少)对本机函数的调用或对Android框架中实现网络I/O功能的方法的调用的方法(更多详细信息,请参见附录a)。

附录a:为了在配套应用中找到初始的 sendMessage 候选集,我们分析了它的内部表示。特别是,我们选择所有那些包含对本机方法(具有本机属性)的调用(Soot 中间表示调用指令)或对 Android 框架中已知实现网络 I/O 操作的方法的调用(例如,java.lang. net.、javax.net. 或 android.net.*)。通过应用这些规则,我们获得了一个函数列表,这些函数在调用时可能会向 IoT 设备发送网络消息。

在这里插入图片描述
步骤2:发送消息验证
  我们动态执行应用程序并利用API挂钩来验证候选sendMessage函数。为了确定边界函数是否为有效的sendMessage函数,理论上,我们可以i)多次动态执行该函数并检查每次是否生成网络流量,ii)阻止应用程序执行该函数并检查是否仍生成网络流量。不幸的是,我们发现阻止一个函数执行,以及强迫应用程序多次执行同一个函数,通常会导致应用程序本身崩溃。为了解决这些问题,我们采用了一种基于时间戳和机器学习的不同方法。
  首先,我们动态地钩住所有候选函数并运行应用程序。当我们观察网络活动时,我们登记最后执行的候选sendMessage函数。特别是,每次执行候选sendMessage函数时,我们都会收集其执行和观察到的网络活动之间经过的时间。然后,我们利用K-均值算法对观察到的经过时间度量进行聚类。
  具体来说,我们将候选者分为两个集群(即 k = 2)。为此,我们将每个特征向量计算为每个候选的经过时间的均值、标准差和众数。基本原理是导致网络活动的函数具有较小的均值和标准差,因为它们受噪声的影响较小。最后,在 sendMessage 候选中,我们选择那些属于具有最小经过时间平均值的集群。在我们分析的后续步骤中,将只考虑该集群中的 sendMessage 函数。这种方法由算法1中的函数 dynamicFilter 表示。
步骤3:数据转换函数识别
  虽然sendMessage函数直观上是执行模糊化的好触发器,但应用程序可以在sendMessage函数之前执行的函数中应用数据转换。数据转换函数的典型示例由编码方法表示,该方法将整数列表作为输入,并将其序列化为字节序列。
  如前所述,模糊触发器是应用程序控制流中位于任何数据转换函数之前的函数。模糊化位于数据转换功能和sendMessage功能之间的功能可能会产生无效输入,这些输入被物联网设备丢弃。因此,为了找到模糊触发器,我们首先需要确定应用于所发送数据的数据转换函数。
  这项任务提出了不同的挑战。首先,正在发送的数据可能包含在类字段中,该字段由 sendMessage 函数引用。这个字段理论上可以设置在应用程序代码的任何地方,包括在其他线程中。此外,对于每个字段,我们需要考虑其父类,因为保存要发送的消息的变量可能会被不同的类继承。
在我们的方法中,我们考虑了这些问题。我们首先静态地确定保存由sendMessage函数发送的数据的可能变量,以及在应用程序中设置这些变量的代码位置(算法1中的函数getArgAndObjLocs)。为了实现这一点,我们创建了一个包含元组(v,cl)的集合Sv,其中v是sendMessage使用的变量(即sendMessage主体中引用的sendMessage参数或对象),cl是设置的代码位置。
  然后,我们识别数据转换函数。对于每个元组(v、cl)∈在Sv中,我们执行一个静态过程间反向切片(算法1中的第6行),从任意函数到任意UI对象检索值。然后,我们将计算出的程序切片划分为函数范围(第7行的getFunctionScopes)。给定一个程序片,函数作用域定义为片中属于同一函数的顺序指令的子序列。
  对于每个收集的函数范围,我们执行活度分析:我们考虑函数范围内引用的变量(即,局部变量和类字段),并且计算在范围的开始处生存的变量集和在范围的末尾(第8行)生存的变量集。例如,如果一个函数被切片遍历,则位于函数作用域开头的变量是的参数和在写入之前读取的类字段。位于的作用域末尾的变量是返回的变量和创建或修改的类字段。
  为了确定数据转换函数,我们利用了相关工作所探讨的观察结果,即这些函数增加了它们所消耗数据的熵。因此,我们将在切片中识别的函数挂钩,动态运行应用程序,并计算在运行时分配给包含在

L

i

f

Li_{f}

Lif

L

o

f

Lo_{f}

Lof中的每个变量v的数据的香农熵。(关于如何计算熵的更多详细信息,请参见附录C)。如果是一个基本变量(例如int)或一个已知类型(例如String、Integer、Float和Double),我们将转换它包含在字节表示中的数据,并计算这个字节列表的香农熵。相反,如果是类字段,则检索其类定义,并考虑其类型为原始或已知类型的每个字段变量。然后,我们计算这些变量中每一个的熵,并将它们添加到集合或集合中,具体取决于活动集合所属。
  最后,我们检查每个收集的函数范围,并计算中所有变量的最大熵与中所有变量的最小熵之间的商(第11行)。如果大于某一阈值(在我们的实验中设置为2,如先前的工作建议,我们认为函数是数据转换函数(第12行)。
补充熵相关知识:
在这里插入图片描述
步骤4:Top-Chain函数集合
  数据转换功能通常以精确的顺序执行,以充分准备要发送到物联网设备的数据。例如,一个配套应用程序可能会在base64中编码一些用户数据,然后将其封装在HTTP请求x中。
  我们将数据转换函数序列称为转换数据链,并使用术语“顶链函数top-chain”指代序列中的第一个函数。如果修改 f 变量的内容最终会影响 v 的值,我们就说顶链函数 f 会影响变量 v。
我们特别感兴趣的是影响sendMessage变量的顶链函数。事实上,如果我们控制这些顶级链的变量,我们就可以控制发送到被分析物联网设备的数据。特别是,这些数据既有效(即被物联网设备接受),又不受不必要的应用端输入验证的影响。因此,影响 sendMessage 变量的顶级链函数代表了刺激物联网设备功能的最佳模糊测试触发器。
  为了识别顶链函数,我们构建在上一步(第13行)检测到的每个数据转换函数的支配树(一个图,其中每个节点的子节点是它直接支配的那些节点),并选择那些不受任何其他数据转换函数支配的数据转换函数(第16行)。最后,我们认为fuzzing触发了收集的顶链函数。
  注意,如果没有数据转换函数支配SM消息函数,我们将SM视为模糊触发(第14, 15行和第16行)。例如,当配套应用程序不包含数据转换功能时,可能会发生这种情况。
  最后请注意,原则上,应用程序端清理代码可能存在于转换数据链中的函数中。我们将在第五节中对此进行讨论。
  作为一个简单的例子,考虑图3,它代表了我们在8月智能锁设备上发现的数据链之一。假设我们之前将sendToDevice标识为sendMessage函数,我们将{c}设置为可能包含要发送的数据的初始变量集,并确定设置c的代码位置。由于c是一个函数参数,我们检索sendMessage调用站点(第15行),并从调用站点向后引导程序切片,直到函数unlock(第1行)。这是通过向后跟踪变量e的数据流实现的:sendToDevice使用变量e,它是调用函数encrypt的结果。然后,我们继续从函数encrypt的末尾向后切片,直到其入口点,然后返回sendCommand函数。最后,我们到达了该函数的入口点,并考虑其调用者(即函数unlock)继续切片。
在这里插入图片描述
  按照上述函数作用域的定义,此向后切片包含以下函数作用域:i)sendCommand:第15行;ii)encrypt:6到9行;iii)sendCommand:第12行和第13行;iv)unlock:第3行;v)Command constructor(本例中未报告代码);和vi)unlock:第1行和第2行。为了简洁起见,在下面,我们只考虑相关的功能范围:ii)encrypt,iii)sendCommand,和vi)unlock。它们的活动变量集是: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};和unlock:

L

i

f

Li_{f}

Lif={},

L

o

f

Lo_{f}

Lof={cmd}。
  一旦我们确定了切片中的函数范围,我们运行应用程序并计算分配给每个活动变量的数据的熵。然后,我们计算每个函数作用域引入的熵量,并检查其值是否超过阈值。
  函数unlock不会引入任何熵,因为集合为空。在集合为空的情况下,我们不考虑函数作为候选数据转换函数,因为它不接受任何输入。
  对于函数encrypt,存储在b中的数据的熵为5.94,而在enc中返回的数据的熵为53.16。由于熵δ大于我们的阈值(

d

e

d_{e}

de=53.16/5.94>2),所以我们考虑加密作为数据变换函数。此外,函数sendCommand引入了较低的熵(

d

e

d_{e}

de=1.03),因此,它不被视为数据转换函数。最后,由于函数encrypt控制函数sendToDevice,因此encrypt是唯一的顶链函数,并用作唯一的模糊触发器。
UI刺激
  我们的方法多次执行同一个应用程序,在不同的运行中保持一致。因此,理想情况下,我们希望应用程序始终遵循相同的执行路径。为了实现这个目标,我们要求分析员运行应用程序一次,而DIANE记录生成的UI输入。然后,通过利用RERAN在后续运行中自动重放相同的输入。我们没有明确处理具有不确定性的其他来源,因为我们发现它们不会显著影响我们的方法。
  模糊化中间数据转换函数。原则上,转换数据链可能是任意长的。由于DIANE的目标是刺激物联网设备的核心功能,我们的方法忽略了中间数据转换功能(即,由顶链功能主导的数据转换功能),因为它们生成的消息可能会被物联网设备丢弃。然而,由于物联网设备在用于解码接收到的消息的过程中可能也包含bug,我们为DIANE提供了模糊所有中间数据转换功能的选项。类似地,DIANE提供了一个选项,可以直接模糊sendMessage函数,即使它由顶链函数控制。在第IV-C节中,我们根据经验证明,模糊sendMessage函数不会导致发现新的bug,但会减慢工具的执行速度。

fuzzing

  在我们的方法的第一阶段之后,我们获得了一组模糊触发器,它们是模糊器的输入。
  测试用例生成
  对于每个模糊触发器,我们通过改变已识别模糊触发器的参数来生成一组测试用例,最终修改sendMessage函数发送的数据。我们以循环方式一次模糊一个不同的模糊触发器。为了改变其参数值,我们使用以下策略:
  •字符串长度:我们更改字符串的长度,以触发缓冲区溢出和越界访问。我们生成不同长度的随机字符串。
  •数值:我们更改整型、双精度或浮点值的值,以导致整数溢出或越界访问。我们生成非常大的值、负值和零值。
  •空值:我们提供空值,试图导致误解、未初始化变量漏洞和空指针取消引用。
  •数组长度:我们通过删除或添加元素来修改数组的内容。
  重要的是,我们不仅要模糊基本变量(例如int、float),还要通过模糊对象的成员变量来模糊对象识别crash。正如最近的一项研究所示,识别物联网设备的基于网络的服务的所有崩溃,而不进行侵入性物理访问是一项挑战。同时,获得对物联网设备的侵入性物理访问需要大量的工程工作,因为供应商通常会阻止这种类型的访问。
  出于这些原因,在对设备进行模糊处理时,DIANE会自动分析其响应以识别崩溃。具体来说,DIANE首先执行应用程序的正常运行,并监控设备在正常活动期间的响应。然后,在模糊化过程中,DIANE再次监控应用程序和设备之间的网络流量,如果满足以下任一条件,则认为输入可能会导致崩溃
  •连接断开。如果设备突然结束正在进行的连接,我们认为它是设备出现了错误的指示。具体来说,对于TCP连接,我们查找应用程序发送FIN数据包但未收到响应(FIN+ACK),然后发送两个或更多SYN数据包序列的情况。
  •HTTPInternalServerError(500)。应用程序和设备通过HTTP进行通信,设备返回内部服务器错误(状态代码500)的实例被视为设备进入故障状态的信号。
  •网络流量大小不规则。如果应用程序和设备之间交换的数据量超过阈值,我们将保存当前导致崩溃的输入。我们的直觉是,当设备进入故障状态(例如,由于崩溃)时,它通常会暂时不可用于应用程序,从而大大减少了交换的数据量。在我们的实验中,我们经验性地验证了当交换的数据量小于50%(与常规运行相比)时,设备会发生异常情况。因此,我们设定阈值为50%。
  •心跳监测。在模糊给定设备的同时,我们不断对其进行ping并监控其响应时间。我们报告导致响应时间高于某个阈值的任何crash诱导输入。在我们的实验中,我们将时间设置为10秒,因为我们根据经验验证,在正常条件下,物联网设备的平均响应时间在1秒之内。
  最后,我们使用另一款Android智能手机,我们称之为看门狗设备,从中立的角度监控物联网设备的状态(即,我们不在此设备上检测配套应用程序)。我们在看门狗设备上运行配套应用程序,并自动重放先前记录的UI输入,以定期运行不同的物联网设备功能。然后,人类分析员可以观察看门狗设备执行的功能(例如,按下灯光开关UI按钮)是否对物联网设备产生预期效果(例如,打开灯光)。如果检测到不期望的效果,则意味着Diane能够使所分析的设备进入无效状态。

实验

  原文中作者使用DIANE对11种不同的物联网设备进行模糊处理,还与现有的网络级模糊器进行了比较。在这里只介绍与LOTFUZZER对比部分的实验。

DIANE vs LOTFUZZER

  为了将我们的方法与IoTFuzzer进行比较,我们联系了作者并获得了他们的工具。我们还试图购买用于评估IoTFuzzer的相同设备,但我们只能获得设备3和6,因为其余设备仅在中国可用。
  IoTFuzzer 需要手动干预以适应不同的设备和配套应用程序。特别是,我们必须 i) 将分析范围(即挂钩函数的数量)限制为 Android 应用程序中存在的 Java 包的子集——以保持分析易于处理并避免崩溃——以及 ii) 手动指定任何加密应用程序中存在的功能。在此手动配置步骤之后,我们能够为我们能够获得的设备(设备 3 和设备 6)复制原始论文中显示的结果。此外,IoTFuzzer 基于 TaintDroid,其最新版本最高支持 Android 4.3 (2012)。出于这个原因,我们无法分析设备 10 和设备 11,因为它们的配套应用程序需要更新的 Android SDK 版本
  我们的结果如表三所示。IoTFuzzer破坏了设备3和6(原始文件中使用的两个设备)以及设备2,但没有发现其他8个设备的任何缺陷。
对于设备2,IoTFuzzer确定了5个要进行模糊测试的函数。我们手动分析了这些函数,发现其中三个是误报,因为它们被用于在Android手机上保存用户信息。为了证实我们的发现,我们对这些函数进行了模糊化处理,并观察到它们都没有产生网络流量。
  然后,我们继续模糊剩下的两个函数,即HouseExtProperty和changeCameraUsernamePassword。在对HouseExtProperty函数进行一小时的模糊化处理时,我们发现生成的消息被定向到供应商的云,而不是实际设备,因此没有为物联网设备生成任何有意义的模糊化输入。
changeCameraUsernamePassword功能用于更改IoT设备上的凭据。我们对这个函数进行了24小时的模糊处理,IoTFuzzer重新发现了DIANE在这个设备上发现的7个bug中的2个。
  为了更好地理解 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,对于发现 IoT 设备中的错误是无效的。另一方面,我们的自下而上的方法从 sendMessage 函数中引导其分析(参见第 III 节),与输入源无关,因此更通用。
  此外,changeCameraUsernamePassword仅允许修改特定相机型号的凭据(第2行,cam.checkCameraModel)。这意味着IoTFuzzer无法有效地模糊其他相机模型。通过识别控制流中更深层次的模糊触发器,DIANE绕过了该检查,并且独立于设备版本有效。
  对于设备ID 7和8,IoTFuzzer导致应用程序立即崩溃,原因是挂接的函数数量太多。我们将分析范围缩小到只包含与设备交互的代码的包,但无论如何应用程序都会崩溃。因此,我们无法在这些设备上运行IoTFuzzer。
在这里插入图片描述

图4 IoTFuzzer为Insteon摄像头(设备ID 2)找到模糊功能
在这里插入图片描述
图5 IoTFuzzer为Foscam摄像头配套应用程序(设备ID 4和5)找到模糊功能
  对于设备ID 9,IoTFuzzer确定了3个要fuzz的函数。然而,我们发现这些函数是误报的,因为它们被用来在智能手机上记录用户数据。
  对于ID为1、4和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_凭证),要求用户提供凭证以便继续。因此,模糊化并没有给摄像机产生任何有意义的输入,因为检查会不断失败。相反,DIANE被识别为模糊触发函数changeUserAndPwd,它不受任何检查的影响(因为它在检查完下凭证信息之后才模糊),并在模糊时有效地向摄像机发送命令。这些案例突出了IoTFuzzer方法的另一个局限性,因为它们表明,模糊化应用程序控制流中处理用户提供数据的第一个函数是无效的。
  对于设备ID 1,IoTFuzzer识别了一个名为setUser的函数,该函数将用户的登录信息发送到设备。在这种情况下,此函数由一个禁止用户密码包含某些特殊字符(例如“&”)的检查来保护。我们对这个函数进行了24小时的模糊处理,没有在设备中记录到任何异常。同样在本例中,DIANE在进行任何客户端检查后,选择了应用程序控制流中更深的一个函数。这是成功发现(零天)bug所必需的。
  总体而言,DIANE仅在两种情况下(设备ID 3和6)的表现与IoFuzzer一样出色,并且在所有其他情况下都优于IoFuzzer,这是因为IoFuzzer无法识别任何有意义的发送功能,或者因为它没有产生任何导致崩溃的输入。
该评估强调了在配套应用程序中仔细选择正确的模糊功能的重要性,并且appside消毒检查会阻碍模糊活动的效果。伴随应用程序中存在应用程序端消毒的频率加剧了这一问题。例如(如表II所示),在我们的数据集中,我们发现11个应用程序中至少有7个包含健全性检查。我们在第IV-E节中进一步衡量了这一方面。

局限性和未来工作

  虽然我们解决了执行物联网设备黑盒模糊化的主要挑战,但我们的总体方法和DIANE的实施仍然存在一些局限性。
  当应用程序端健全性检查在本机代码、数据转换函数或直接在sendMessage函数中实现时,我们目前无法绕过这些检查。尽管我们承认此类检查可能存在于这些代码类中的任何一类中,但我们手动验证数据集中的任何应用程序都不包含这些类别中的健全性检查。事实上,正如前面的工作[16]所示,本机代码通常不用于实现主应用程序的逻辑,而是用于库助手函数中。请注意,与前面的工作不同,这并不意味着DIANE根本无法处理本机代码。事实上,即使sendMessage函数是本机实现的,DIANE也可以识别它并模糊其模糊触发器。但是,如果上述任何一类代码中都存在健全性检查,则模糊化的效果就较差。
  与任何基于动态分析的方法一样,DIANE的代码覆盖范围有限,即无法识别应用程序未执行的模糊触发器。为了缓解这一限制,我们手动刺激应用程序以触发大部分可用功能,并在真正的智能手机上进行分析。
DIANE的当前实现无法模糊嵌套Java对象。我们计划在今后的工作中解决这一问题。
  DIANE可以被增强以自动发现语义漏洞(例如,智能锁打开门而不是锁上门)。目前,该功能是半自动的,因为它需要分析员检查看门狗设备并与之交互。

结论

  在本文中,我们研究了物联网设备模糊器的有效性。一方面,随机模糊发送到设备的网络数据包需要了解设备接受的数据格式,而当设备使用自定义固件时,这种数据格式很少可用。另一方面,由于应用程序端代码施加的限制,利用配套移动应用程序的UI生成语法正确的消息的方法是无效的。
  相反,我们提出了一种介于网络级模糊和用户界面级模糊之间的新方法。我们的方法旨在识别模糊触发器,它是物联网配套应用程序中的代码部分,在输入验证之后和任何数据转换功能之前执行,并最大化模糊结果。我们在一个名为DIANE的工具中实现了我们的方法,并在11个不同品牌的真实物联网设备上对其进行了评估。DIANE的性能优于当前最先进的方法,它可以成功地检测到现有模糊程序无法触发的关键错误(9个0day)。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>