KARONTE: Detecting Insecure Multi-binary Interactions in Embedded Firmware

原文:

karonte.pdf

翻译:

摘要—低功耗、单一用途的嵌入式设备(如路由器和物联网设备)已经变得无处不在。虽然它们自动化和简化了用户生活的许多方面,但最近的大规模攻击表明,它们的数量对互联网基础设施构成了严重威胁。不幸的是,这些系统的软件依赖于硬件,并且通常在独特的、最小的环境中执行,具有非标准的配置,使得安全分析特别具有挑战性。许多现有的设备通过使用多个二进制文件实现其功能。这种多二进制服务的实现使得目前的静态和动态分析技术要么无效,要么无能为力,因为它们无法识别和充分模拟各种可执行文件之间的通信。在本文中,我们提出了K ARONTE,这是一种静态分析方法,能够通过建模和跟踪多二进制的互动来分析嵌入式设备软件。我们的方法在二进制文件之间传播污点信息,以检测不安全的互动和识别漏洞。我们首先对来自不同供应商的53个软件样本进行了评估,表明我们的原型工具可以成功地跟踪和约束多二进制的互动。这导致了46个零日漏洞的发现。然后,我们在899个不同的样本上进行了大规模的实验,表明K ARONTE在不同规模和复杂度的软件样本上有良好的扩展性。

I. I NTRODUCTION

小型互联的嵌入式设备的激增正在推动我们世界的连接性,它们正在取代传统的门锁、灯泡和许多其他以前不显眼的物体。不幸的是,在这些物联网(IoT)设备上运行的软件(或fimware)很容易受到攻击[3], [9], [32],这导致了物联网专用网络犯罪的地下发展[21]。例如,在2016年,Mirai僵尸网络破坏了数以百万计的设备(如路由器和摄像头),并利用它们进行拒绝服务攻击,破坏互联网的核心服务并关闭网站[27],[30],[50]。

作为回应,研究人员已经提出了自动识别固件分布中的漏洞的技术,一般是通过将其解包为可分析的组件[11],然后对其进行单独分析[5],[42],[40]。然而,尽管在漏洞发现技术方面取得了这些进展,最先进的方法是不充分的,而且漏洞仍然存在。

当前技术不完善的一个关键原因是,嵌入式设备本身是由相互连接的组件组成的。这些组件是不同的二进制可执行文件,或者是一个大型嵌入式操作系统的不同模块。

它们相互作用以完成各种任务。例如,嵌入式设备经常暴露出由网络服务器和各种后端应用程序组成的基于网络的界面[6], [44]。在这种结构中,任何给定的功能往往依赖于多个程序的执行[12]:例如,接受HTTP请求的网络服务器,由网络服务器召唤的本地二进制文件(例如,使用套接字),以及由本地二进制文件执行的外部命令来完成请求。

每个相互作用的软件组件(网络服务器、后端应用程序和其他辅助程序)可以对正在共享的数据做出不同的假设,而不一致的地方可以表现为安全漏洞。精确地检测一个软件样本的不同组件之间的这些不安全的多进制相互作用是具有挑战性的。在不考虑内部数据流的情况下,孤立地考虑每个组件的程序分析方法会产生次优的结果,因为它们(i)忽略了组件在二进制通信过程中施加的有意义的约束,(ii)不能有效地区分攻击者控制的和非攻击者控制的输入源,以及(iii)可能只发现超级错误。

考虑一个接受用户证书的网络服务器,将其长度限制为16个字符,然后将其传递给一个处理程序二进制(例如,通过环境变量),后者将其复制到两个16字节长的缓冲区。如果后一个二进制文件是专门用来处理由网络服务器接收(和审查)的用户证书,它可以放弃实现长度检查。在这个例子中,孤立地分析处理程序的二进制文件可能会导致识别在实践中不可能触发的错误,而且安全分析可能会产生大量的误报,因为它必须假设所有输入二进制文件的来源都可能产生不受约束的、攻击者控制的数据。这些误报将需要由人类分析员来检查,这意味着时间成本。由于分析师检查、修补和测试一个软件样本所需的时间是不可忽视的,因此,在实践中,不会造成安全威胁的二进制文件之间的受控互动应被取消优先级。另一方面,只考虑面向网络的二进制文件(即那些直接接受用户请求的二进制文件)的分析不能识别firmware中更深层次和更复杂的错误。

因此,有效的固件分析必须考虑到多个二进制文件,并对它们共享的数据进行推理。

不幸的是,大多数现有的程序分析工作一次只关注一个程序或模块[55], [37], [45]。虽然有些工作试图模拟嵌入式设备,从而同时分析所有的组件,但目前的方法要么对固件样本施加严格的假设[11],要么只取得有限的成功率(即从13%[12]到21%[5])。其他方法[6],[48],[54]试图直接分析实际设备,但由于他们采用了纯粹的动态技术(如模糊),他们可能无法有效地发现更深层次和更复杂的错误[34]。

在本文中,我们提出了K ARONTE,这是一种新型的静态分析方法,它可以跟踪firmware样本二进制文件的数据流,从而精确地发现安全漏洞。K ARONTE基于这样一种直觉,即二进制程序使用一套有限的进程间通信(IPC)范式进行通信,它利用这些范式的共性来检测用户输入被引入firmware样本的地方,并识别不同组件之间的互动。识别出的交互作用随后被用来跟踪组件之间的数据流,并进行跨二进制污点分析。最后,传播的污点和约束被用来检测用户控制的输入的不安全使用,这可能导致漏洞。

我们实现了KARONTE,并使用两个数据集对其进行了评估:53个当前版本的软件样本和899个从相关工作中收集的样本[5]。我们利用前一个数据集来深入研究我们方法的每个阶段,并评估其发现漏洞的有效性。在我们的实验中,我们表明我们的方法成功地识别了不同固件组件的数据流,正确地传播了污点信息。这使我们能够发现潜在的易受攻击的数据流,从而发现了46个零日软件漏洞,并重新发现了另外5个n日漏洞,证明了我们的方法在不同设计的复杂固件上的有效性(即,单片式嵌入式操作系统和嵌入式Linux发行版)。毫无疑问,健全的单一二进制静态分析技术也可以发现这些漏洞,但它会产生大量的假阳性,使分析在现实世界中站不住脚。在我们对K ARONTE的多二进制分析方法和在单二进制模式下运行的相同分析(即禁用二进制间数据流跟踪)的比较中,产生的警报数量从每个样本平均2个增加到平均722个。K ARONTE提供了两个数量级的警报,并因此降低了假阳性率。如我们的评估所示,我们估计验证由单一二进制分析产生的所有警报可能需要一个安全分析员大约四个月的工作。另一方面,对我们的原型所产生的警报的验证大约需要10个小时的累积时间。

最后,我们利用第二个更大的数据集来研究我们的工具的性能,显示其在不同规模和复杂度的软件样本上有良好的扩展能力。

综上所述,我们做出了以下贡献。
我们介绍了静态分析技术的新组合,以进行多进制污点分析。为了做到这一点

为此,我们设计了一种新的技术来精确地应用和传播多个二进制的污点信息。

  • 我们提出了K ARONTE,这是一种新的静态分析方法,用于识别二进制之间不安全的互动。K ARONTE从根本上减少了误报的数量,使现实世界的软件分析变得实用。
  • 我们在53个真实世界的软件样本上实现并评估了我们的K ARONTE原型,表明我们的工具可以成功地在多个二进制文件中传播污点信息,从而发现了46个未知的(零日)漏洞,并产生很少的误报。然后,我们利用一个更大的899个软件样本的数据集来评估我们工具的性能。
  • 我们的工具所获得的结果由另一所大学的独立研究人员进行了彻底的验证。

本着开放科学的精神,我们发布了我们的原型和docker镜像的实施,以复制我们的工作环境1。

II. 背景资料

本节提供背景信息,以了解我们的方法的目标和内在的挑战。

A. 物联网攻击者模型

物联网设备通过网络交换数据。这些数据可以直接来自用户(例如,通过网络界面),或间接来自可信的远程服务(例如,云后端)。许多设备,特别是路由器、智能电表和大量的低功率设备,如智能灯泡和锁,都使用前一种模式。此外,最近的攻击表明,这些设备可以被聪明的远程攻击者利用,即使他们的通信被限制在一个封闭的本地网络[23]。在这项工作中,我们考虑的是基于网络的攻击者,他们通过本地网络或互联网与设备直接通信。然而,如第十节所示,K ARONTE可以很容易地扩展到其他场景。

B. 固件的复杂性

现代物联网设备的固件很复杂,由多个组件组成。这些组件可以采取不同的二进制文件的形式,打包在嵌入式Linux发行版中,或不同的模块,编译成一个大型的、单一的二进制嵌入式操作系统(”blob firmware”)。到目前为止,前一种类型的固件是最普遍的:一个大规模的实验分析了数以万计的固件样本,并发现其中86%是基于Linux的[11]。与其他基于Linux的系统类似,基于Linux的软件包括大量相互依赖的二进制文件。

嵌入式设备上的固件的不同二进制文件(或组件)共享数据以执行设备的任务。在我们的攻击者模型下,这种互动是至关重要的,因为我们关注的是那些可以由来自设备 “外部”(即通过网络)的攻击者输入触发的错误,但可能会影响那些直接面对网络的二进制文件。任何只关注这些面向网络的二进制文件的分析都会错过其他组件中包含的bug[6]。另一方面,关注所有孤立的二进制文件的分析会产生不可接受的大量错误警报。

我们在下面这个基于真实世界的软件样本的服务例子中证明了这一点。这个服务由一个面向网络的Web服务器(清单1)组成,它执行一个CGI处理程序(清单2)。当网络服务器收到一个用户请求时,它调用函数serve_request。然后,在解析了请求(parse_URI)之后,网络服务器执行处理程序,通过QUERY_STRING环境变量传递数据。处理程序的二进制文件检索数据并将其传递给 process_request。这个函数包含一个错误:如果用户请求中的字段op的值超过128字节,会发生缓冲区溢出。这种溢出是由攻击者控制的,代表了一个重大的漏洞。

虽然这种特殊的溢出会被只关注处理程序二进制的分析所发现,但任何单一的二进制分析都会在这个程序中发现两个漏洞。第二个是由LOG_PATH环境变量引起的log_dir缓冲区的溢出。尽管这是一个合法的错误,但它被归类为漏洞取决于LOG_PATH中数据的来源。如果攻击者不能控制这些数据,那么这个错误就不是一个漏洞,真正的漏洞应该被优先考虑。理想情况下,每个警报都会被检查,每个漏洞都会被修复。不幸的是,这个目标在实践中是不可行的。虽然这个简单的例子有两个警报,揭示了一个漏洞,但我们的评估显示,对现实世界中的单个二进制软件进行静态分析,每个设备可以产生成千上万的警报,需要分析人员花几个月的时间来处理。

为了使静态分析在二进制文件上变得可行,一种能过滤掉不能被攻击者触发的漏洞的方法是至关重要的。K ARONTE就是这样一种方法。它通过使用静态分析将产生(或设置)数据的函数与其他二进制文件中消耗(或获取)数据的函数连接起来,从而识别出跨二进制文件的数据依赖关系,比如本例中的二进制文件。
image.png
在本文中,我们把上述例子中显示的程序互动称为多二进制互动。同样地,我们把涉及跨多个二进制的数据流的漏洞称为多进制漏洞。最后,我们把产生数据的二进制(例如清单1中的Web服务器)称为setter二进制,而把消费数据的二进制(例如清单2中的handler二进制)称为getter二进制。

C. 物联网固件中的IPC 自动确定用户输入是如何被引入并通过嵌入式设备传播的,这是一个开放的问题[36]、[51]、[55],而且容易出现令人沮丧的误报率[22]。然而,我们观察到,在实践中,进程通过一组有限的通信范式进行通信,即所谓的进程间通信(或IPC)范式。

IPC的一个实例是通过一个独特的密钥(我们称之为数据密钥)来识别的,参与通信的每个进程都知道这个密钥。由于这一信息必须在所有参与的程序执行之前就能得到,所以它通常是硬编码在二进制文件本身。例如,两个通过文件交换数据的二进制程序在传输数据之前必须知道文件名(即数据键)。

与常见的IPC范式相关的数据密钥可用于静态跟踪攻击者控制的信息在二进制文件之间的流动情况。下面,我们将介绍firmware 2中最常见的IPC模式。

文件。进程可以使用文件共享数据。一个进程在一个给定的文件上写入数据,另一个进程则读取和消费这些数据。数据键是文件本身的名称。共享内存。进程可以共享内存区域。

共享内存可以由文件系统上的一个文件支持,也可以是匿名的(如果两个进程是父子关系)。在前一种情况下,数据键由支持的文件名表示,而在后一种情况下,则由共享内存页的虚拟地址表示。进程可以通过环境变量共享数据。在这种情况下,数据键是环境变量的名称(例如,QUERY_STRING)。套接字。进程可以使用套接字与驻扎在同一主机(带文件路径的Unix域套接字)或不同主机(网络套接字)上的进程共享数据。套接字的端点(例如,IP地址和端口,或Unix域套接字的文件路径)代表数据键。命令行参数。一个进程可以催生另一个进程,并通过命令行参数传递数据。数据键是被调用程序的名称。
我们将共享数据表示为一个元组(data key, data)。