前言
物联网 (The Internet of Things,简称 IoT)是指将日常物理对象连接到互联网的过程——从灯泡等常见家用物品,到医疗设备等医疗资产,再到可穿戴设备、智能设备甚至智能城市,都可以连接到互联网。
来自 <https://www.redhat.com/zh/topics/internet-of-things/what-is-iot>
在1999年美国的MIT提出了IOT概念后,时至今日,IOT的产物已经无处不在,而这其中由最初的仅RFID数字标签的功能也逐渐延申到蓝牙、zigebee、wifi等智能硬件当中,据有效统计迄今为止IOT设备的数量已到达200亿之多。
IOT安全问题
而这200亿的设备当中又涉及到我们日常生活中的方方面面,小到灯泡、插座、手机、手表,大到贩卖机、智能汽车等设备。这么多的设备方便我们做各种各样的事情,但是在这同时,其中的智能IOT设备当真就是完美无缺、安全无误的吗?显然不是。
(智能锁存在安全漏洞…)
(网络摄像头制造商因安全问题而受到FTC的抨击)
因为这些智能设备在想帮助我们生活的同时必不可免的便会收集保存一些使用者的隐私信息数据,既然有了隐私信息、那么对于攻击者而言便有了一个初步的攻击目的。更严重的据报告在2016年中,仅一款叫做Mirai的僵尸网络,便成功入侵了数百万个Iot设备。
是什么让IOT如此危险?
在IOT设备中常见的架构中,如:ARM、MIPS、x86、PowerPC等,在相应的设备中管理一些外.围设备往往都需要单独开发或者改写一些代码进而实现。这就造成了不同设备间开发新代码时产生的一些安全漏洞。
针对固件的二进制漏洞分析
面对这些常见的漏洞,基本的分析方法可以分为动态分析和静态分析,但其中又各有利弊。
动态分析
- 仿真、Fuzz。
无法通用,要针对不同的设备进行单独的编写测试且不稳定。
且对硬件存在严重的依赖性(缺少硬件接口的支持)
相关工具与资料:
IoTFuzzer | http://web.cse.ohio-state.edu/~zhao.2708/assets/ndss18/NDSS18.pdf |
Firmadyne | |
Firm-AFL | https://www.usenix.org/conference/usenixsecurity19/presentation/zheng |
静态分析
- 误报严重,不够准确
分析方法单一
相关工具与资料:
FIE on Firmware | |
BootStomp | |
CRYPTOREX | https://www.usenix.org/conference/raid2019/presentation/zhang-li |
Companion apps analysis | https://www.usenix.org/conference/raid2020/presentation/tileria |
Multi-binary
其次在常见的IOT设备固件中86%的固件都是基于linux的文件操作系统,也就是类似于传统的linux其中存在大量的二进制文件,在其运行过程中不同的二进制程序、文件又会互相依赖,对此也称作multi-binary。
而在静态分析固件中,大部分的静态分析工具都是对单个二进制文件进行的,这时候如果分析multi-binary就明显的不够用了,因为在某函数协同处理的时候往往会延申到别的二进制文件中,因此这也是在静态分析中容易误报的根本原因。
而这样的一个multi-binary固件的构成通常为通过web服务进行请求,随后到相应的响应处理程序中以共享数据的方式执行任务,这种交互对于漏洞的检测至关重要。
因为当我们关注攻击者从设备的外部网络输入触发BUG时,很可能某个BUG接连影响到除了web server以外的二进制程序(在很多的只关注网络协议上的二进制文件分析工具都会遗漏其它二进制文件中所包含的问题),在以下的代码中也可以看到.
该服务由一个面向网络的 Web 服务器组成,该服务器执行 CGI 处理程序二进制文件。 当 Web 服务器收到用户请求时,它会调用函数 serve_request。 然后,在无约束的情况下解析请求 (parse_URI) 后,Web 服务器执行处理程序,通过 QUERY_STRING 环境变量传递数据。 处理程序二进制文件检索数据并将其传递给 process_request。 因此该函数存在的bug为:如果用户请求中op字段的值大于128字节,就会发生缓冲区溢出。
再或者是
在固件中,net-cgi控制着data变量的内容,在net-cgi中可能发现不了问题的所在,但是当数据传入到rc中时,就出现了execv执行的data数据。
但是上面的情况如果我们使用一些的针对单个二进制分析的工具进行分析时,则完全无法发现web server二进制程序的漏洞所在。那么这些不同的程序实际是是如何处理接受数据的呢?答案是可以通过进程间的通信(IPC)。每个依赖于共享链接数据的二进制文件必须知道此类数据的端点,而其数据密钥通常也保存在程序的硬编码中。
Karonte
如何精准的发现固件中的漏洞,需求点便可以延伸到跟踪用户的数据是如何在不同的二进制中传入和引用的。首先是对其二进制文件的交互进行建模,在进行下一步的分析,如通过多个二进制的污点分析来实现。而通过Karonte工具则可以跟踪多个二进制文件的数据流以查找漏洞,并有效的发现未知错误,从根本上减少误报的数量。
整体流程如下:
1.Firmware Pre-processing(固件的预先处理)
将固件使用binwalk工具解包
2.Border Binaries Discovery(边界二进制文件的发现)
将解包得到的二进制文件进行分析,找到边界二进制文件(Border Binaries)后并标记出边界二进制文件中与网络编程相关的关键字进行比较的语句地址。
注:边界二进制文件(Border Binaries)这里是指直接从外界接受用户输入的二进制文件,抽象为攻击者控制的数据的引入点。
识别方法:
这里作者假设的攻击时基于网络进而发起的,因此边界二进制文件就是那些接受和处理网络数据的二进制文件,并采用了以下五个特征来识别出设备固件中从网络陶杰在中读取数据并进行解析的二进制文件。
- # basic blocks(bb)
基本块的数量
- # momory comparisons (cmp)
内存比较
- # branches (br)
分支的数目
上面的三个是常见的固件分析工具对输入函数解析的三个特征,除此之外还有两个面向网络的二进制文件特征
- # network-related keywords (e.g.,"<soap")(net)
网络标志,对soap,http等网络编码字符串的引用或硬编码数目
- Data flow between a recv and a mem comparison (conn)
连接标志,是否从套接字中读取数据并与内存中的数据比较
之后根据数据模型,计算出某个二进制文件可能是网络边界二进制文件的概率。
在使用DBSCAN density-based clustering algorithm算法选出边界二进制文件的集合,并标记出其文件中与网络编程相关的关键字进行比较的语句位置。
3.Binary Dependency Graph(二进制依赖关系图)
根据前面得到的边界二进制文件集合,对处理被攻击者控制的数据二进制文件之间的通信进行分析,得到一个二进制依赖关系图(BDG)。
在该BDG中包含了在固件中各二进制文件之间传递的数据流信息,之后使用静态污点引擎,对污点数据与网络相关的关键字进行比较以及运行CPFs来分析检测二进制文件中共享的数据(CPFs)。
而CPF(通信格式查找器)模块则会对不同的进程间通信的格式进行推测,比如基于网络套接字的通信格式。其主要的功能为:数据关键字恢复、程序的流程确定(数据设置与获取间的过程)、二进制的放大扩展。
并且作者提供了通用的CPF以涵盖未知的进程间的通信数据(IPC)。例如下面这个示例,再两个binary中,我们通过针对数据传递的关键字确定了其为作为setter与getter的关系,对此传递的数据便可以以此为索引通过CPF进行查找。
4.Multi-Binary data-flow analysis(Multi-Binary 数据流分析)
根据上一步得到的BDG进行数据流分析,主要目的是得到来自网络传入的数据在传播过程中的约束集。
因此需要有向图 BDG 中的数据流细节。但通常情况下,列举 BDG 中所有二进制间的路径会导致路径爆炸的问题。因此作者的关键点是,更可能导致 bug 发生的路径是那些对用户提供的数据约束较少的路径,每次只将那些对用户输入数据约束最少的路径传播到其他二进制文件。
5.Insecure Interactions Detection(不安全的交互检测)
通过污点数据引擎发现不安全的可以被攻击者控制的数据流。
其中主要是作用于检测:
- 缓冲区溢出漏洞
对于缓冲区溢出漏洞,利用污点分析检测由攻击者控制的数据是否地到达了内存复制类函数,然后分析其目标缓存区的边界大小和污染信息的被约束后的大小,进而判断是否存在溢出等问题。
- 拒绝服务攻击等漏洞
对于被攻击者控制的循环,该模块会检测每个循环执行的次数是否不加约束地由用户控制。
其原理主要是根据在漏洞检测前扫描所有函数并对比较类(memcmp)、复制类函数 (memcpy)进行标记。
在污点数据由另外一个二进制程序接收的过程中,如果未受约束的数据是污点数据,那么就会触发警报。
- Taint Engine(污点分析引擎)
Karonte的污点引擎是基于BootStomp开发的,随后通过改进版的Angr进行相应的污点分析。
路径优先级策略 是指将会优先考虑传播污点的路径,并对抹去污点数据的路径取消优先权。
并返回非常量数据的基本区块和在分析其他的路径之前跟随到其函数return的地方。
污点数据在程序间的依赖关系,主要为缓解程序间过度依赖的问题,并智能解除污点策略,对此:
在n的污点标签与cmd的污点标签之间建立依赖关系。
如果n不受限制,那么CMD也不会被污染
那么 strcpy 函数就不会产生对应的误报情况
随后程序将会自动找到可以符合要求的代码函数,并创建污点标签的对应依赖。
Karonte的实际应用
作者团队对来自七家不同厂商的53个设备固件进行分析,通过Karonte发现了46个经过验证的0day漏洞,
且报警数从平均945个减少到了每个固件平均5个,警报错误率极低。
随后又在大规模的分析中,对21个不同厂商的899个固件进行测试,其中存在multi-binary交互的又348个,而Karonte生成的1003个报警中,作者手动检查了100个报警,其中44个为真实存在的并且30多个都是multi-binary的漏洞。
从BDG向量图中可以看到一个固件样本存在了16个二进制文件的BDG。
最后Karonte的项目地址