CN111428233A - 一种嵌入式设备固件的安全性分析方法 - Google Patents

一种嵌入式设备固件的安全性分析方法 Download PDF

Info

Publication number
CN111428233A
CN111428233A CN202010193286.5A CN202010193286A CN111428233A CN 111428233 A CN111428233 A CN 111428233A CN 202010193286 A CN202010193286 A CN 202010193286A CN 111428233 A CN111428233 A CN 111428233A
Authority
CN
China
Prior art keywords
executing
service daemon
firmware
register
basic block
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
CN202010193286.5A
Other languages
English (en)
Other versions
CN111428233B (zh
Inventor
吴华茂
周亚金
李金库
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Xidian University
Original Assignee
Xidian University
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Xidian University filed Critical Xidian University
Priority to CN202010193286.5A priority Critical patent/CN111428233B/zh
Publication of CN111428233A publication Critical patent/CN111428233A/zh
Application granted granted Critical
Publication of CN111428233B publication Critical patent/CN111428233B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/57Certifying or maintaining trusted computer platforms, e.g. secure boots or power-downs, version controls, system software checks, secure updates or assessing vulnerabilities
    • G06F21/577Assessing vulnerabilities and evaluating computer system security
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/52Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/57Certifying or maintaining trusted computer platforms, e.g. secure boots or power-downs, version controls, system software checks, secure updates or assessing vulnerabilities
    • G06F21/575Secure boot

Landscapes

  • Engineering & Computer Science (AREA)
  • Computer Security & Cryptography (AREA)
  • Computer Hardware Design (AREA)
  • General Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Computing Systems (AREA)
  • Debugging And Monitoring (AREA)

Abstract

本发明公开了一种嵌入式设备固件的安全性分析方法,步骤1:对嵌入式设备固件的文件系统进行静态分析,寻找用于启动服务守护程序使用的参数和配置文件,并将嵌入式设备固件的文件系统打包为虚拟机磁盘镜像;步骤2:利用寻找的参数和配置文件启动服务守护程序,并录制服务守护程序的执行轨迹;若能启动,执行步骤5;否则,执行步骤3;步骤3:根据录制的服务守护程序的执行轨迹,寻找服务守护程序不能启动的原因;步骤4:根据寻找的服务守护程序不能启动的原因,对服务守护程序进行修复,修复后执行步骤2;步骤5:测试已启动的网络服务。本发明支持更多类型的嵌入式设备固件,并获取固件程序运行过程中的各项操作语义信息进行安全性分析。

Description

一种嵌入式设备固件的安全性分析方法
技术领域
本发明属于软件的安全防护技术领域,具体涉及一种嵌入式设备固件的安全性分析方法。
背景技术
随着互联网和电子技术的发展,各种类型的“物联网”嵌入式设备变得越来越普及,遍布到人们的生活中。然而,受限于设备厂商的更新策略与用户的使用习惯,这些设备的安全性经常得不到重视,它们很多时候都在运行过时的或有漏洞的固件程序。这些设备在其工作网络环境中大都发挥着重要作用,例如作为局域网的接入设备和网关出口等,有时候甚至可能掌握一些用户的重要或隐私信息。这些设备的安全防线一旦被攻破,可能会带来严重的后果。
很长一段时间以来,嵌入式设备安全性的传统研究方案是获取目标设备的真实硬件,并直接对其进行分析。使用这种方法需要真实的设备,因此很难覆盖到大量设备。另外,由于嵌入式设备软硬件架构的特殊性,在设备上通常无法运行传统桌面计算机平台上的分析工具,因此有时候很难获得程序运行过程中的详细信息。为此,Costin等人提出并实施了大规模收集嵌入式设备固件,通过静态分析的方式寻找漏洞的方案[Costin et al.,Usenix Security Symposium 2014]。该方案解决了传统方案设备覆盖范围小的问题,然而由于此种方案使用了静态分析的技术,因此只能识别出一部分类型的漏洞。为克服静态分析方法的局限性,Chen等人提出了一种基于全系统模拟的安全分析方案[Chen et al.,NDSS 2016],该方案首先解压出固件的文件系统,通过一个初始化过程识别出设备的网络配置,并利用一个通用的Linux内核加载固件的文件系统,让固件原系统中的系统初始化脚本完成设备初始化的工作。在此之后,使用各种漏洞检测工具对模拟器中启动的网络服务进行分析。这种方法虽然解决了无法进行动态分析的问题,但实验表明该方案的兼容性不佳,对于很多厂商的固件它都无法识别出正确的网络配置或完成设备的初始化。
发明内容
针对现有技术中的技术问题,本发明提供了一种嵌入式设备固件的安全性分析方法,以便在有限的性能损耗下,支持更多类型的嵌入式设备固件,并获取固件程序运行过程中的各项操作语义信息进行安全性分析。
为了解决上述技术问题,本发明通过以下技术方案予以实现:
一种嵌入式设备固件的安全性分析方法,其特征在于,包括以下步骤:
步骤1:对嵌入式设备固件的文件系统进行静态分析,寻找用于启动服务守护程序使用的参数和配置文件,并将嵌入式设备固件的文件系统打包为虚拟机磁盘镜像;
步骤2:利用步骤1中寻找的参数和配置文件启动服务守护程序,并录制服务守护程序的执行轨迹;
若服务守护程序能启动,执行步骤5;否则,执行步骤3;
步骤3:根据步骤2中录制的服务守护程序的执行轨迹,寻找服务守护程序不能启动的原因;
步骤4:根据步骤3中寻找的服务守护程序不能启动的原因,对服务守护程序进行修复,修复后执行步骤2;
步骤5:测试已启动的网络服务。
进一步地,所述步骤1具体包括以下步骤:
步骤1.1:解压嵌入式设备固件中的文件系统;
步骤1.2:验证解压后的文件系统的完整性,若文件系统完整,执行步骤1.3,否则结束;
步骤1.3:在文件系统中寻找用于提供需要分析的网络服务的服务守护程序的二进制文件,若能找到,执行步骤1.4,否则结束;
步骤1.4:根据二进制文件的路径寻找用于启动服务守护程序使用的参数和配置文件;
步骤1.5:将嵌入式设备固件的文件系统打包为虚拟机磁盘镜像。
进一步地,所述步骤2具体包括以下步骤:
步骤2.1:读取模拟环境的启动参数,对启动参数进行变量初始化;
步骤2.2:根据步骤2.1中初始化后的启动参数,对模拟环境进行初始化,启动端口扫描工具,让其检测被分析的网络服务所使用的端口是否开放,并设置超时一定时间后退出;
步骤2.3:在初始化后的模拟环境中,利用步骤1中的参数和配置文件启动服务守护程序;
步骤2.4:基本块被执行前,执行在步骤4中对服务守护程序进行修复时需要的信息获取操作和控制流修改操作,并记录当前的寄存器状态;
步骤2.5:执行基本块;
步骤2.6:基本块被执行后,执行在步骤4中对服务守护程序进行修复时需要的信息获取操作和控制流修改操作,并记录当前的寄存器状态;
步骤2.7:若步骤2.2中的端口扫描工具扫描到端口开放,执行步骤(5);若端口扫描工具超时退出,执行步骤(3);否则,执行步骤2.4。
进一步地,所述步骤2.1具体包括以下步骤:
步骤2.1a:初始化程序运行过程中需要录制的基本块的首条指令的地址范围addr_range;
步骤2.1b:初始化程序运行过程中需要进行的寄存器改写操作序列op_queue,op_queue中的每一个元素op使用以下三个属性标记操作执行的条件:pc代表操作执行时PC寄存器的值;lr代表操作执行时lr寄存器的值;do_before标记该操作发生的时机是否在基本块被执行前;
步骤2.1c:初始化程序运行过程中需要进行的信息获取操作序列in_queue,in_queue中每一个元素in使用以下三个属性标记操作执行的条件:pc代表操作执行时PC寄存器的值;lr代表操作执行时lr寄存器的值;do_before标记该操作发生的时机是否在基本块被执行前;
步骤2.1d:初始化用于设置是否录制该基本块的全局变量do_record为false;
步骤2.1e:创建运行轨迹记录文件exec_trace。
进一步地,所述步骤2.2具体包括以下步骤:
步骤2.2a:启动模拟器,让其加载用于模拟环境初始化的initramfs和嵌入式设备固件的文件系统;
步骤2.2b:initramfs完成网络环境初始化,并chroot到嵌入式设备固件的文件系统中;
步骤2.2c:启动端口扫描工具,让其检测被分析的网络服务所使用的端口是否开放,并设置超时一定时间后退出。
进一步地,所述步骤2.4具体包括以下步骤:
步骤2.4a:对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作;
步骤2.4b:对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作;
步骤2.4c:检查PC寄存器的值是否在addr_range范围内,若是,执行步骤2.4d;否则,执行步骤2.6;
步骤2.4d:记录当前寄存器状态bb_stat和将要被执行的基本块大小bb_size到运行轨迹记录文件exec_trace中;
步骤2.4e:设置do_record为true。
进一步地,所述步骤2.6具体包括以下步骤:
步骤2.6a:对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作;
步骤2.6b:对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作;
步骤2.6c:若do_record值为true,执行步骤2.6d,否则执行步骤2.8;
步骤2.6d:记录当前寄存器状态ab_stat到exec_trace中;
步骤2.6e:设置do_record值为false。
进一步地,所述步骤3具体包括以下步骤:
步骤3.1:加载服务守护程序及其依赖的共享库到内存模型map中;
步骤3.2:对exec_trace进行预处理,得到基本块执行记录序列bb_list;
步骤3.3:分析bb_list,获得服务守护程序的API调用记录api_trace;
步骤3.4:确认服务守护程序最后的运行状态,具体如下:
步骤3.4a:扫描bb_list,若服务守护程序经过了正常退出必经的例程__libc_csu_fini或__uClibc_fini,执行步骤3.6;
步骤3.4b:检查api_trace,查看最后是否存在未返回的外部API函数调用,若存在,执行步骤3.4d;
步骤3.4c:分析bb_list最后是否陷入循环,若是,执行步骤3.6;
步骤3.4d:检查最后一个未返回的外部API函数func,若该库函数为常见库函数,执行步骤3.7,否则,执行步骤3.5;
步骤3.5:把提供func函数的共享库文件在内存中加载的地址范围加入到addr_range中,执行步骤2.1;
步骤3.6:寻找服务守护程序出错的原因,具体如下:
步骤3.6a:将bb_list中的每一个block的基本块内容转换成中间语言;
步骤3.6b:从bb_list最后一个未被扫描到的block开始,往前寻找一个包含条件跳转的基本块s;
步骤3.6c:初始化数组tainted_regs和tainted_mems,分别用于存放已被标记的寄存器和内存地址;
步骤3.6d:以s为起点,往前寻找最后一个包含条件跳转的未被分析的基本块,对其进行反向污点分析;
步骤3.6e:检查该基本块被执行前r0寄存器的标记状态,若未被标记,执行步骤3.6d;否则,执行步骤3.6f;
步骤3.6f:对api_trace,检查该基本块的起始地址是否为一个函数调用的返回点,如果是,执行步骤3.6g;否则,执行步骤3.6d;
步骤3.6g:检查该函数返回值是否代表错误,若是,执行步骤3.7;否则,执行步骤3.6h;
步骤3.6h:清除所有用于传递函数调用参数的寄存器的污点状态;
步骤3.6i:执行步骤3.6d;
步骤3.7:尝试获取该函数调用的参数内容。
进一步地,所述步骤4具体包括以下步骤:
步骤4.1:检查导致服务守护程序出错的函数调用的函数来源,若该函数来自常见的共享链接库,执行步骤4.2;否则,执行步骤4.3;
步骤4.2:具体如下:
步骤4.2a:检查该函数调用的参数内容是否都获取成功,若成功,执行步骤4.2d;
步骤4.2b:生成用于获取该函数参数具体内容的信息获取指令in,加入到in_queue中;
步骤4.2c:执行步骤2;
步骤4.2d:针对该函数的函数名和重要参数,生成修复建议;
步骤4.2e:将修复建议应用到模拟环境中;
步骤4.2f:执行步骤2;
步骤4.3:具体如下:
步骤4.3a:计算出一个可让服务守护程序在条件跳转处走向另一条分支的函数返回值;
步骤4.3b:生成用于修改该函数返回值的寄存器修改指令op,加入到op_queue中;
步骤4.3c:执行步骤2。
进一步地,所述步骤5中,使用漏洞扫描工具或攻击代码测试已启动的网络服务。
与现有技术相比,本发明至少具有以下效果:
1)与现有的全系统模拟方案相比,本发明方案使用预设的网络配置,且每次只对单个服务的安全性进行分析,避免了网络配置识别失败或者由于系统初始化失败而导致的服务无法访问问题。
2)相对于传统方案利用程序在终端的输出或监控系统调用等粗粒度信息修复无法正常工作程序的方法,本方案通过利用程序运行过程中记录的运行轨迹,能更好的解释程序在运行过程中的语义行为,大大方便了程序的修复。
3)相对于现有的其它方案,本发明在录制程序的运行轨迹时,采用了选择录制的方式,大大减少了录制量,并且包含了更多的有用信息,例如程序基本块被执行前后的寄存器状态等,提高了后续操作的效能。
为使本发明的上述目的、特征和优点能更明显易懂,下文特举较佳实施例,并配合所附附图,作详细说明如下。
附图说明
为了更清楚地说明本发明具体实施方式中的技术方案,下面将对具体实施方式描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图是本发明的一些实施方式,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1是本发明的总流程图;
图2是寻找程序出错原因的子流程图;
图3是在程序基本块内部进行反向污点分析的子流程图;
图4是为程序出错原因选择修复方案的子流程图;
图5是本发明动态安全性分析实验的性能测试对比图。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合附图对本发明的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
本发明一种嵌入式设备固件的安全性分析方法,包括以下步骤:
步骤1:对嵌入式设备固件的文件系统进行静态分析,寻找用于启动服务守护程序(Service Daemon)使用的参数和配置文件,并将嵌入式设备固件的文件系统打包为虚拟机磁盘镜像;具体包括以下步骤:
步骤1.1:解压嵌入式设备固件中的文件系统;
步骤1.2:验证解压后的文件系统的完整性,若文件系统完整,执行步骤1.3,否则结束;
步骤1.3:在文件系统中寻找用于提供需要分析的网络服务的服务守护程序的二进制文件,若能找到,执行步骤1.4,否则结束;
步骤1.4:根据二进制文件的路径寻找用于启动服务守护程序使用的参数和配置文件;
步骤1.5:将嵌入式设备固件的文件系统打包为虚拟机磁盘镜像。
步骤2:利用步骤1中寻找的参数和配置文件启动服务守护程序,并录制服务守护程序的执行轨迹;若服务守护程序能启动,执行步骤5;否则,执行步骤3;具体包括以下步骤:
步骤2.1:读取模拟环境的启动参数,对启动参数进行变量初始化;具体包括以下步骤:
步骤2.1a:初始化程序运行过程中需要录制的基本块的首条指令的地址范围addr_range;
步骤2.1b:初始化程序运行过程中需要进行的寄存器改写操作序列op_queue,op_queue中的每一个元素op使用以下三个属性标记操作执行的条件:pc代表操作执行时PC寄存器的值;lr代表操作执行时lr寄存器的值;do_before标记该操作发生的时机是否在基本块被执行前;
步骤2.1c:初始化程序运行过程中需要进行的信息获取操作序列in_queue,in_queue中每一个元素in使用以下三个属性标记操作执行的条件:pc代表操作执行时PC寄存器的值;lr代表操作执行时lr寄存器的值;do_before标记该操作发生的时机是否在基本块被执行前;
步骤2.1d:初始化用于设置是否录制该基本块的全局变量do_record为false;
步骤2.1e:创建运行轨迹记录文件exec_trace。
步骤2.2:根据步骤2.1中初始化后的启动参数,对模拟环境进行初始化,启动端口扫描工具,让其检测被分析的网络服务所使用的端口是否开放,并设置超时一定时间后退出;具体包括以下步骤:
步骤2.2a:启动模拟器,让其加载用于模拟环境初始化的initramfs和嵌入式设备固件的文件系统;
步骤2.2b:initramfs完成网络环境初始化,并chroot到嵌入式设备固件的文件系统中;
步骤2.2c:启动端口扫描工具,让其检测被分析的网络服务所使用的端口是否开放,并设置超时一定时间后退出。
步骤2.3:在初始化后的模拟环境中,利用步骤1中的参数和配置文件启动服务守护程序;
步骤2.4:基本块被执行前,执行在步骤4中对服务守护程序进行修复时需要的信息获取操作和控制流修改操作,并记录当前的寄存器状态;具体包括以下步骤:
步骤2.4a:对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作;
步骤2.4b:对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作;
步骤2.4c:检查PC寄存器的值是否在addr_range范围内,若是,执行步骤2.4d;否则,执行步骤2.6;
步骤2.4d:记录当前寄存器状态bb_stat和将要被执行的基本块大小bb_size到运行轨迹记录文件exec_trace中;
步骤2.4e:设置do_record为true。
步骤2.5:执行基本块;
步骤2.6:基本块被执行后,执行在步骤4中对服务守护程序进行修复时需要的信息获取操作和控制流修改操作,并记录当前的寄存器状态;具体包括以下步骤:
步骤2.6a:对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作;
步骤2.6b:对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作;
步骤2.6c:若do_record值为true,执行步骤2.6d,否则执行步骤2.8;
步骤2.6d:记录当前寄存器状态ab_stat到exec_trace中;
步骤2.6e:设置do_record值为false。
步骤2.7:若步骤2.2中的端口扫描工具扫描到端口开放,执行步骤(5);若端口扫描工具超时退出,执行步骤(3);否则,执行步骤2.4。
步骤3:根据步骤2中录制的服务守护程序的执行轨迹,寻找服务守护程序不能启动的原因;具体包括以下步骤:
步骤3.1:加载服务守护程序及其依赖的共享库到内存模型map中;
步骤3.2:对exec_trace进行预处理,得到基本块执行记录序列bb_list;
步骤3.3:分析bb_list,获得服务守护程序的API调用记录api_trace;
步骤3.4:确认服务守护程序最后的运行状态,具体如下:
步骤3.4a:扫描bb_list,若服务守护程序经过了正常退出必经的例程__libc_csu_fini或__uClibc_fini,执行步骤3.6;
步骤3.4b:检查api_trace,查看最后是否存在未返回的外部API函数调用,若存在,执行步骤3.4d;
步骤3.4c:分析bb_list最后是否陷入循环,若是,执行步骤3.6;
步骤3.4d:检查最后一个未返回的外部API函数func,若该库函数为常见库函数,执行步骤3.7,否则,执行步骤3.5;
步骤3.5:把提供func函数的共享库文件在内存中加载的地址范围加入到addr_range中,执行步骤2.1;
步骤3.6:寻找服务守护程序出错的原因,具体如下:
步骤3.6a:将bb_list中的每一个block的基本块内容转换成中间语言;
步骤3.6b:从bb_list最后一个未被扫描到的block开始,往前寻找一个包含条件跳转的基本块s;
步骤3.6c:初始化数组tainted_regs和tainted_mems,分别用于存放已被标记的寄存器和内存地址;
步骤3.6d:以s为起点,往前寻找最后一个包含条件跳转的未被分析的基本块,对其进行反向污点分析;
步骤3.6e:检查该基本块被执行前r0寄存器的标记状态,若未被标记,执行步骤3.6d;否则,执行步骤3.6f;
步骤3.6f:对api_trace,检查该基本块的起始地址是否为一个函数调用的返回点,如果是,执行步骤3.6g;否则,执行步骤3.6d;
步骤3.6g:检查该函数返回值是否代表错误,若是,执行步骤3.7;否则,执行步骤3.6h;
步骤3.6h:清除所有用于传递函数调用参数的寄存器的污点状态;
步骤3.6i:执行步骤3.6d;
步骤3.7:尝试获取该函数调用的参数内容。
步骤4:根据步骤3中寻找的服务守护程序不能启动的原因,对服务守护程序进行修复,修复后执行步骤2;具体包括以下步骤:
步骤4.1:检查导致服务守护程序出错的函数调用的函数来源,若该函数来自常见的共享链接库,执行步骤4.2;否则,执行步骤4.3;
步骤4.2:具体如下:
步骤4.2a:检查该函数调用的参数内容是否都获取成功,若成功,执行步骤4.2d;
步骤4.2b:生成用于获取该函数参数具体内容的信息获取指令in,加入到in_queue中;
步骤4.2c:执行步骤2;
步骤4.2d:针对该函数的函数名和重要参数,生成修复建议;
步骤4.2e:将修复建议应用到模拟环境中;
步骤4.2f:执行步骤2;
步骤4.3:具体如下:
步骤4.3a:计算出一个可让服务守护程序在条件跳转处走向另一条分支的函数返回值;
步骤4.3b:生成用于修改该函数返回值的寄存器修改指令op,加入到op_queue中;
步骤4.3c:执行步骤2。
步骤5:使用漏洞扫描工具或攻击代码测试已启动的网络服务。
下面更进一步的对本发明进行说明解释。
参照图1,本发明包括两个组成部分,分别是:基于系统态模拟的动态分析,以及用于修复无法正常工作程序的轨迹分析。其中,固件中受分析的服务在动态分析部分中被尝试运行,若运行成功则进行安全分析,否则通过轨迹分析部分找出程序出错的原因和生成修复方案。
一、基于系统态模拟的动态分析部分
步骤1,固件文件系统的静态分析。
为对嵌入式设备的固件进行安全分析,本发明采取的方案是使用全系统模拟器模拟出一个与被研究设备采用同样处理器架构的虚拟机,并在其中运行固件中用于提供服务的服务守护程序。在服务守护程序启动后,虚拟机可被视作与宿主机处于同一局域网环境中的另一台机器,宿主机使用各种漏洞检测工具对启动的服务进行检测,就像研究真实设备一样。为满足这一需求,本发明首先需要对固件镜像中的文件系统进行提取,并在其中找到服务启动程序和原设备启动该服务使用的启动参数和依赖的配置文件等,具体包括以下步骤:
(1a)从固件镜像中解压嵌入式设备固件中的文件系统。
(1b)验证固件文件系统的完整性。固件厂商可能使用各种打包方式或加密方式生成固件的镜像,文件系统可能不能被正确解压。此外,镜像可能只是设备的增量升级包,其中不包含完整的文件系统,因此本发明需要检查解压出的文件系统的完整性正确性。具体地,本发明首先检查固件文件系统根目录下是否存在大量的文本文件或二进制文件,这是文件系统解压错误的征兆。然后,本发明检查固件中是否包含有效的C运行时库二进制文件。此举动是基于这样一种观察:设备厂商通常使用同一套交叉编译工具链编译一个同一个设备的固件,而固件文件系统中的C运行时库文件则来源于交叉编译工具链。因此,对于同一设备的不同固件版本,其包含的C运行时库文件版本通常不会改变,该文件的存在意味着固件镜像不是一个增量更新包。此外,存在这样一个有效的二进制文件,也意味着解压工具使用的算法能正确解压固件中的二进制文件。若文件系统完整,执行步骤(1c),否则退出。
(1c)在文件系统中寻找用于提供需要分析的网络服务的服务守护程序的二进制文件。若不能找到,则退出。
(1d)寻找用于启动服务守护程序使用的启动指令和配置文件等。具体而言,本发明采用的方法是进行对固件文件系统进行静态分析。首先,在文件系统中寻找包含服务守护程序可执行文件或文件名为子串的字符串的文件,此种字符串可能就是启动指令。然后,使用正则表达式检查该字符串中是否存在其他类似文件名或者是文件路径的子串,并检查相应的文件或者路径是否存在。若不存在,则尝试生成该文件。若文件无法被生成或无法找到有效的启动指令,则结束;
(1e)把固件文件系统打包为虚拟机磁盘镜像。文件系统需要被传入模拟器中,本发明采用的方案是新建一个虚拟机磁盘镜像,并把文件系统打包放入其中,在模拟过程中挂载为虚拟机的一个磁盘。
步骤2,启动服务守护程序,并录制其执行轨迹。
在此步骤,本发明尝试启动用于提供服务的服务守护程序,并录制其运行轨迹,以在其不能正常运行的情况下提供修复的依据。此外,在修复步骤中可能会生成一些需要在此步骤中使用的额外指令,以改变程序的控制流或在程序运行过程中获取一些信息,这些指令将在本步骤中被传导至模拟器。具体而言,包括以下步骤:
(2a)读取模拟环境启动参数,进行变量初始化。一些变量用于控制在程序运行过程中会对模拟环境进行信息获取或者操纵的行为。若在进行到此步骤时程序已不是第一次被执行,本发明将在此步骤执行修复步骤中生成的指令,这些指令会影响变量的初始值。
(2a1)初始化运行过程中需要录制的基本块的首条指令的地址范围addr_range,为减少录制量和提高模拟速度,本发明采用了一种选择录制机制,只录制程序二进制文件的执行部分和指定共享链接库的执行部分。在关闭ASLR的情况下,程序二进制文件本身会被加载到内存的前部,而其依赖的共享链接库会被加载到用户内存空间的较后部分,因此可通过内存地址范围区分开来,且在每一次执行时,同样的动态链接库总会被加载到相同的内存地址范围中。在首次录制,只录制程序二进制文件的执行部分,addr_range为0x8000到0x1000000。若应用了录制动态链接库的指令,指令中包含的动态链接库地址范围将被加入到addr_range。;
(2a2)初始化运行过程中需要进行的寄存器改写操作序列op_queue。本发明可通过在指定点修改寄存器中的值来改变程序的控制流,达到修复程序运行的目的。若步骤(2a)是第一次被执行,op_queue为空。修复步骤中生成的指令指示了寄存器修改操作op的执行时机和修复方式,这些op会被加入到op_queue中。
(2a3)初始化运行过程中需要进行的信息获取操作序列in_queue。本发明可支持在指定点读取虚拟机内部任意地址或寄存器的信息。若步骤(2a)是第一次被执行,in_queue为空。修复步骤中生成的指令指示了寄存器信息获取操作in的执行时机和具体操作,这些in会被加入到in_queue中。
(2a4)初始化用于指示当前是否应该执行录制的布尔变量do_record,该变量初始值为false。
(2b)创建运行轨迹记录文件exec_trace。
(2c)对模拟环境进行初始化。
(2c1)启动模拟器,让其加载用于环境初始化的initramfs和固件文件系统。
(2c2)initramfs完成网络环境初始化,并chroot到固件文件系统中。
(2c3)启动端口扫描工具,让其检测被分析的网络服务所使用的端口是否开放,并设置超时5分钟后退出。
(2d)使用在步骤(1d)获取到的启动参数启动服务守护程序。
(2e)判断当前模拟环境中当前正在执行的程序是否为目标服务守护程序,如果是则执行步骤(2f)。
(2f)在基本块被执行前,检查当前虚拟机的PC和LR寄存器,并执行相应的任务。
(2f1)对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作。
(2f2)对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作。
(2f3)若当前PC寄存器的值在addr_range范围内,跳转到步骤(2f4),否则跳转到步骤(2g)。
(2f4)记录当前的寄存器状态bb_stat和将要被执行的基本块大小bb_size到运行轨迹记录文件exec_trace中。此处使用了ARM的寄存器表示,其中PC寄存器为Programcounter,用于指示下一条被执行的指令的地址,LR寄存器用于指示当前函数调用执行完毕后将跳转到的返回地址。本发明使用PC和LR寄存器来定位程序执行到的点。
(2f5)设置do_record为true。
(2g)等待基本块被模拟器执行完毕。
(2h)在基本块被执行后,检查当前虚拟机的PC和LR寄存器,并执行相应的任务。
(2h1)对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作。
(2h2)对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作。
(2h3)若当前do_record为true,跳转到步骤(2h4),否则跳转到步骤(2i)。
(2h4)记录当前的寄存器状态ab_stat到运行轨迹记录文件exec_trace中。
(2h5)设置do_record为false。
(2i)检查端口扫描工具的状态,若端口扫描工具扫描到端口开放,跳转到步骤3;若端口扫描工具仍在运行但未检测到端口开放,跳转到步骤(2e);若端口扫描工具已出错退出,把exec_trace传递给本发明的轨迹分析部分进行下一步分析。
上述步骤(2e)-(2i)为录制程序运行轨迹和判断程序是否正常运行的操作。本发明采用了超时机制,若在超时之内程序无法提供服务或已经退出,则判定程序在运行过程中遇到了问题。
步骤3,使用漏洞扫描工具或攻击代码测试已启动的网络服务。
二、用于修复无法正常工作程序的轨迹分析
如图1所示,若程序无法正常提供网络服务,将根据其执行轨迹寻找其出错的原因并进行修复。根据程序最后的运行情况,本发明使用不同的方式寻找程序的出错点,并对修复点进行修复。该部分的具体实现如下:
步骤A,程序加载和运行轨迹记录的预处理。
(A1)加载服务守护程序及其依赖的共享库到内存模型map中。为获取程序运行过程中的语义行为,需对其运行轨迹记录中经过的地址进行解析,获得程序的函数调用记录。通过还原程序在运行时的内存布局,即可解析每个地址对应的函数。此外,在记录执行轨迹时为了减少执行轨迹的大小,并未记录下基本块的内容。通过基本块执行前的PC寄存器值与基本块的大小,即可从map中获取基本块的内容。
(A2)对程序执行轨迹exec_trace进行预处理,得到基本块执行记录序列bb_list。bb_list内的每一个元素bb为一个基本块的执行记录,包括基本块的代码、基本块执行前后的寄存器状态等。
(A3)分析bb_list,获得程序的API调用记录api_trace。本发明通过将基本块的代码转换成中间语言表达来获知程序执行流程中的函数调用操作。具体而言,本发明从bb_list的第一个bb开始,对其进行线性扫描。以平台架构为ARM、中间语言为VEX IR为例,若IR最后的jumpkind属性为Ijk_Call,意味着程序在此处执行了函数调用操作,该基本块执行后的PC地址为函数跳转的目标,LR地址为函数调用的返回地址。根据ARM的调用规范,函数调用返回后使用r0和r1寄存器存放函数的返回值。因此,当扫描到一个基本块被执行前的PC地址为前一个函数调用的返回地址时,意味着函数已在此处返回,而r0即是函数的返回值。在此扫描过程中,若一个基本块与函数调用相关,该函数调用相关的信息将被加入到对应的bb中,相应的函数相关操作(调用或返回)、函数名、函数的返回值及bb的序号等将被记录于api_trace中。
函数名的获取通过检查PC地址是否在内存布局的.plt段来实现。若PC地址p在.plt段,查询程序符号表中该PLT项对应的符号。若不能获取到符号,标记该函数名为unknown_p。
不仅程序本身会调用外部库函数,外部库函数在运行过程中,也可能会调用程序本身的API。这常见于外部库作为程序本身的插件的情况。由于步骤2在录制程序运行轨迹时是通过地址段来区分程序本身的部分以及外部库的部分的,因此这些被调用的程序内部的函数也会被记录下来。由于这些函数的调用和执行都应当被看做是未被录制的外部库函数执行的一部分,因此这些部分应该被去掉。通过检查运行轨迹记录中的不连续点,可得知程序在何时进入未被录制的部分,这一点可通过检查两个基本块之间的寄存器状态实现。若两个基本块之间的录制是连续的,前一个基本块执行后的寄存器状态应与后一个基本块执行前的寄存器状态相同。因此,若在扫描过程中遇到一个基本块在执行结束时执行了函数调用,且记录在此处中断了,则在遇到该函数调用的返回地址前中间的所有基本块都会被去掉。
步骤B,寻找程序出错的原因。首先,确认程序最后的运行状态。根据api_trace的内容,本方法将情况分为4种:程序正常退出、程序陷入循环、程序被终结及未知。具体而言,使用(B4.1)-(B4.4)来确认。在确认程序的退出情况后,选择适当的方案来寻找程序出错的原因,具体步骤为(B5)-(B7)。
(B4.1)扫描bb_list,若程序经过了程序正常退出必经的例程__libc_csu_fini或__uClibc_fini,跳转到步骤(C2)。对于动态链接的程序,这些例程例程在程序退出时会被调用,用于进行清理工作。本方法将这些例程被调用作为程序正常退出的标志。
(B4.2)检查api_trace,查看最后是否存在未返回的外部API函数调用,若存在,跳转至步骤(B4.4)。
(B4.3)分析bb_list最后是否陷入循环,若是,跳转到步骤(C2)。本方法使用的判断程序陷入循环的标准为:程序没有退出,且重复运行一些代码块序列。在所有循环中,至少有一个基本块,其执行前后的寄存器状态与其他循环中相同块的状态相同。这可作为循环不会主动结束的标志。
(B4.4)检查api_trace最后一个未返回的函数func,若func为常见的外部库函数,跳转到步骤(C3)。否则,跳转到步骤(C1)。通常而言,常用库(C标准库、OpenSSL等)提供的API并不会为厂商的程序特别定制。若未观察func的返回,意味着在执行func的过程中发生了错误,func就是程序出错的原因。若func来自私有库,此时无法判断程序的运行情况。需要分别处理。
步骤C,寻找程序出错的原因。
(C1)将把提供func函数的共享库文件在内存中加载的地址范围加入到addr_range中,跳转至步骤(2a)。对于程序结束于未知函数的情况,本方法采用的方案是添加录制提供该函数的共享链接库的执行轨迹,获取更详细的信息。
(C2)通过程序分析寻找程序出错的原因,其基本流程如图2所示。本发明实现的算法基于这样的一个观察:当程序的运行出现错误时,通常采用两种方法来应对:退出或者重试。前者通常用于无法挽救的错误发生的情况,在这种情况下,程序通常会选择这样的一条执行路径:输出一些帮助分析错误的信息,执行一些清理工作,然后程序退出。对于一个服务守护程序来说,如果程序的运行没有出现问题,这样的一条路径通常是不会被执行的。如果程序的运行遇到了有可能挽回的错误,通常最常用的解决方法是重试。比如说,程序没有在一个超时之内获取到其需要的资源,等等。如果这个错误无法通过简单的重试来解决,而程序有没有设置重试次数的阈值,程序的执行最后就会陷入循环。这两种错误处理方式有一个共同点:它们都通过一个条件判断来决定程序的走向。该条件判断通常是比较变量是否与预定范围匹配。对于一个以用户态程序形式存在的服务守护程序而言,其通常只能通过系统调用或外部库提供的API与外部环境进行交互,因此,对于那些由于环境问题而无法运行的服务守护程序,程序就有可能因为某个用于与外界交互的函数调用返回值不在预期范围之内而出错退出。因此,假如对程序的执行轨迹进行回溯,很有可能可以找到一个条件跳转,该条件跳转走向的分支由某个函数调用的返回值直接或间接决定。这个函数调用若是一个返回失败的外部API,那么很有可能就是程序出错的原因。具体而言,该步骤包含步骤(C2.1)-(C2.8)。
(C2.1)将bb_list中每一个bb的基本块内容转换成中间语言。
(C2.2)从bb_list最后一个未被扫描到的block开始,往前寻找一个包含条件跳转的基本块。
(C2.3)初始化数组tainted_regs和tainted_mems,分别用于存档当前已被污点标记的寄存器和内存地址。
(C2.4)开始反向污点分析。在基本块内部进行污点分析的算法如图3所示。该污点分析算法从语句序列的最后一句开始往前逐句进行分析。在一条语句内部,如果被污点标记的临时变量的值是由某个寄存器或者内存地址或者是另一个临时变量的值计算得来的,则污点会被传播到这些元素中。相反,如果一个被污点标记的临时变量的值纯粹是由一个常量计算得来,则该临时变量的污点标记将被抹去。对于寄存器和内存地址,算法也用相似的方式来处理。此算法的设计基于这样的一个假设:既然同一个程序在不同环境中运行的结果不同,那么决定程序走向的条件不会来自于硬编码于二进制文件中的数据,而是来自于程序在实际运行过程中获得或者计算得到的值。污点分析的污点传播源为用于决定条件跳转走向的临时变量。若基本块不包含条件跳转,则把分析前已标记的寄存器和内存地址作为污点传播源。在污点分析过程中,若遇到其他包含条件的基本块,则把污点也传播到用于决定该跳转目标的临时变量。
(C2.5)检查当前r0寄存器的标记状态,若r0被标记,跳转至(C2.6),否则跳转至(C2.4)。
(C2.6)比对api_trace,检查该基本块的起始地址是否一个函数调用的返回点,如果是,跳转至步骤(C2.7),否则跳转至步骤(C2.4)。根据ARM的调用规范,r0和r1寄存器用于存放函数调用的返回值。因此,若此处是函数的返回点,r0又是被标记的,这意味着后面的一个条件跳转与该函数的返回值相关。
(C2.7)检查函数的返回值是否代表失败。若是,跳转至(C3),否则,跳转至(C2.8)。本发明对于维护了一些常用库函数及系统调用的返回值范围,通过检查返回值是否在错误范围内,即可得知程序是否出错。对于未被维护的API,则检查该函数的返回值是否为负数或0,然后交由用户判断。
(C2.8)清除所有用于传递函数调用参数的寄存器的污点状态。对于ARM架构来说,是r0-r3寄存器。
(C3)尝试获取该函数调用的参数内容。以ARM架构为例,r0-r3寄存器及堆栈用于传递函数调用的参数,其存放的内容为立即数或指针。若该函数名是已知的常见API,可直接根据其参数类型获取值。若该函数名是未知的,则通过启发式的方式获取:若数值在0x7efffe000-0x8000之间,判断其为立即数,否则判断其为指针。若该值被识别为一个指针,且指针范围在内存布局中位于.data,.rodata或.bss段,尝试获取这些值。
步骤D,对问题进行修复。本发明的修复方案如图4所示。简单来说,对于来自常见共享库的API调用,使用对症下药的解决方法,对于未知的API调用,使用修改控制流的方法,对于信息获取不全的情况,则去获取必要的信息。
(D1)检查可能导致程序出错的函数调用的函数来源,若该函数来自常见的共享链接库(C标准库、OpenSSL等),跳转到步骤(D2);否则跳转到步骤(D3);
(D2)对于常见库函数的修复方案
(D2.1)检查该函数调用的参数内容是否都获取成功,若成功,跳转至步骤(D2.4)。
(D2.2)生成用于获取该函数参数具体内容的信息获取指令in,加入到in_queue中。以ARM架构设备为例,其r0-r3寄存器用于传导函数调用参数值。若函数调用的第一个参数未获取成功,则指令内容为当模拟器PC和LR寄存器值与函数调用发生时的PC和LR相同时,获取r0寄存器的内容。
(D2.3)跳转至步骤(2)。
(D2.4)针对该函数的函数名和重要参数,提出修复建议。如:open()函数失败通常与其第一个参数有关(文件名),检查该文件是否存在,或文件存放的路径是否有效。
(D2.5)将修复建议应用到模拟环境中。
(D2.6)跳转至步骤(2)。
(D3)对于其他函数的解决方案
(D3.1)计算出一个可让程序在条件跳转处走向另一条分支的函数返回值。可使用约束求解的方式来计算此值。
(D3.2)生成用于修改该函数返回值的寄存器修改指令op,加入到op_queue中。以ARM架构为例,r0寄存器用于传递函数的返回值。要想改变函数func的返回值,则指令内容为当模拟器PC和LR寄存器值与函数返回点指向的块被执行前的PC和LR寄存器状态一致时,改变其r0寄存器的值为(D3.1)获得的约束求解值。
(D3.3)跳转至步骤(2)。
本发明的有效性可以通过以下实验进一步说明:
1)实验条件
使用PANDA和angr实现本发明。PANDA是一个基于QEMU的全系统动态分析引擎,用于对软件的快速逆向工程。angr是美国圣巴巴拉大学ShellPhish团队研发的一款二进制分析框架,可以实现动静态符号执行、控制流平坦化、自动化生成ROP链,应用于漏洞挖掘与软件破解,同时也是CTF比赛中逆向分析的常用工具之一。其中,实现一个PANDA插件用于实现程序分析和轨迹录制部分,angr用于实现对运行轨迹进行分析的部分。固件的解压使用FIRMADYNE项目提供的固件解压脚本。在轨迹分析的实现部分,使用VEX IR作为分析程序运行轨迹的中间语言并基于VEX IR实现反向污点分析算法,对72个常用的C运行时库函数以及POSIX函数的参数和返回值范围进行了建模。漏洞检测部分使用带有Vulscan插件的Nmap扫描工具,并加载来自mitre的特征数据库。
硬件平台选用Dell公司的Optiplex 7060 PC机,它的CPU是i7 8700,内存为32GB。实验的固件解压、执行和运行轨迹录制部分于一个Ububtu 14.04LTS docker容器中进行,轨迹分析脚本使用python实现,运行于Pypy 7.2.0(python 3.6.9)。
2)实验内容
实验包括两部分:检测框架的有效性和测试动态分析的性能损失。
为检测框架的有效性,建立一个包含223个固件镜像的测试集,尝试使用本发明的实现启动其中的Web服务守护程序,并使用漏洞扫描工具进行扫描。这些固件镜像用于ARM架构的嵌入式设备,来自7个不同厂商并尽可能提高了设备型号多样性。镜像已通过检查,包含至少一个Web服务守护程序。
为测试动态分析的性能损失,选取10个未经修复不能正常运行的Web服务守护程序,测试其在QEMU和启动了轨迹录制的PANDA环境中从启动到退出使用的时间。计时在模拟器内部进行,编写一个shell脚本在程序运行前获取起始时间,启动程序,然后在程序结束时计算当前时间与起始时间的时间差并输出。
3)结果分析
在固件文件系统检查阶段,实验实现去掉了15个文件系统解压失败的镜像。剩余的208个镜像中,有165个(79.3%)成功通过实验实现给出的修复方案启动了Web服务或是无需修复即启动了web服务。根据分析脚本给出的建议和找到的程序出错点,修复了85个Web服务守护程序的运行。其中,有4个程序通过修改模拟环境的IP配置修复,81个程序在修复过程中使用了修复文件路径的方法,51个程序在修复过程中使用了修改函数返回值的方法进行修复。在这165个固件中,通过Nmap扫描找到70个包含可能受漏洞的固件镜像。此实验证明本发明提出的方案兼容性良好,且能帮助验证已知漏洞。
在性能测试阶段,如图5所示,轨迹录制操作造成了平均7.4倍,最高11.5倍的拖慢。然而,运行耗费最长的一个也只耗费了12.998秒,在可接受范围内。需指出的是实验实现在每次生成新的轨迹记录时,都会立即对轨迹记录文件进行写入。若采用适当的缓存写入措施,可有较高的性能提升空间。
最后应说明的是:以上所述实施例,仅为本发明的具体实施方式,用以说明本发明的技术方案,而非对其限制,本发明的保护范围并不局限于此,尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,其依然可以对前述实施例所记载的技术方案进行修改或可轻易想到变化,或者对其中部分技术特征进行等同替换;而这些修改、变化或者替换,并不使相应技术方案的本质脱离本发明实施例技术方案的精神和范围,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应所述以权利要求的保护范围为准。

Claims (10)

1.一种嵌入式设备固件的安全性分析方法,其特征在于,包括以下步骤:
步骤1:对嵌入式设备固件的文件系统进行静态分析,寻找用于启动服务守护程序使用的参数和配置文件,并将嵌入式设备固件的文件系统打包为虚拟机磁盘镜像;
步骤2:利用步骤1中寻找的参数和配置文件启动服务守护程序,并录制服务守护程序的执行轨迹;
若服务守护程序能启动,执行步骤5;否则,执行步骤3;
步骤3:根据步骤2中录制的服务守护程序的执行轨迹,寻找服务守护程序不能启动的原因;
步骤4:根据步骤3中寻找的服务守护程序不能启动的原因,对服务守护程序进行修复,修复后执行步骤2;
步骤5:测试已启动的网络服务。
2.根据权利要求1所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤1具体包括以下步骤:
步骤1.1:解压嵌入式设备固件中的文件系统;
步骤1.2:验证解压后的文件系统的完整性,若文件系统完整,执行步骤1.3,否则结束;
步骤1.3:在文件系统中寻找用于提供需要分析的网络服务的服务守护程序的二进制文件,若能找到,执行步骤1.4,否则结束;
步骤1.4:根据二进制文件的路径寻找用于启动服务守护程序使用的参数和配置文件;
步骤1.5:将嵌入式设备固件的文件系统打包为虚拟机磁盘镜像。
3.根据权利要求2所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤2具体包括以下步骤:
步骤2.1:读取模拟环境的启动参数,对启动参数进行变量初始化;
步骤2.2:根据步骤2.1中初始化后的启动参数,对模拟环境进行初始化,启动端口扫描工具,让其检测被分析的网络服务所使用的端口是否开放,并设置超时一定时间后退出;
步骤2.3:在初始化后的模拟环境中,利用步骤1中的参数和配置文件启动服务守护程序;
步骤2.4:基本块被执行前,执行在步骤4中对服务守护程序进行修复时需要的信息获取操作和控制流修改操作,并记录当前的寄存器状态;
步骤2.5:执行基本块;
步骤2.6:基本块被执行后,执行在步骤4中对服务守护程序进行修复时需要的信息获取操作和控制流修改操作,并记录当前的寄存器状态;
步骤2.7:若步骤2.2中的端口扫描工具扫描到端口开放,执行步骤(5);若端口扫描工具超时退出,执行步骤(3);否则,执行步骤2.4。
4.根据权利要求3所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤2.1具体包括以下步骤:
步骤2.1a:初始化程序运行过程中需要录制的基本块的首条指令的地址范围addr_range;
步骤2.1b:初始化程序运行过程中需要进行的寄存器改写操作序列op_queue,op_queue中的每一个元素op使用以下三个属性标记操作执行的条件:pc代表操作执行时PC寄存器的值;lr代表操作执行时lr寄存器的值;do_before标记该操作发生的时机是否在基本块被执行前;
步骤2.1c:初始化程序运行过程中需要进行的信息获取操作序列in_queue,in_queue中每一个元素in使用以下三个属性标记操作执行的条件:pc代表操作执行时PC寄存器的值;lr代表操作执行时lr寄存器的值;do_before标记该操作发生的时机是否在基本块被执行前;
步骤2.1d:初始化用于设置是否录制该基本块的全局变量do_record为false;
步骤2.1e:创建运行轨迹记录文件exec_trace。
5.根据权利要求4所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤2.2具体包括以下步骤:
步骤2.2a:启动模拟器,让其加载用于模拟环境初始化的initramfs和嵌入式设备固件的文件系统;
步骤2.2b:initramfs完成网络环境初始化,并chroot到嵌入式设备固件的文件系统中;
步骤2.2c:启动端口扫描工具,让其检测被分析的网络服务所使用的端口是否开放,并设置超时一定时间后退出。
6.根据权利要求5所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤2.4具体包括以下步骤:
步骤2.4a:对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作;
步骤2.4b:对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作;
步骤2.4c:检查PC寄存器的值是否在addr_range范围内,若是,执行步骤2.4d;否则,执行步骤2.6;
步骤2.4d:记录当前寄存器状态bb_stat和将要被执行的基本块大小bb_size到运行轨迹记录文件exec_trace中;
步骤2.4e:设置do_record为true。
7.根据权利要求6所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤2.6具体包括以下步骤:
步骤2.6a:对op_queue中每一个与当前运行状态匹配的元素op,执行op内指示的寄存器改写操作;
步骤2.6b:对in_queue中每一个与当前运行状态匹配的元素in,执行in内指示的信息获取操作;
步骤2.6c:若do_record值为true,执行步骤2.6d,否则执行步骤2.8;
步骤2.6d:记录当前寄存器状态ab_stat到exec_trace中;
步骤2.6e:设置do_record值为false。
8.根据权利要求7所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤3具体包括以下步骤:
步骤3.1:加载服务守护程序及其依赖的共享库到内存模型map中;
步骤3.2:对exec_trace进行预处理,得到基本块执行记录序列bb_list;
步骤3.3:分析bb_list,获得服务守护程序的API调用记录api_trace;
步骤3.4:确认服务守护程序最后的运行状态,具体如下:
步骤3.4a:扫描bb_list,若服务守护程序经过了正常退出必经的例程__libc_csu_fini或__uClibc_fini,执行步骤3.6;
步骤3.4b:检查api_trace,查看最后是否存在未返回的外部API函数调用,若存在,执行步骤3.4d;
步骤3.4c:分析bb_list最后是否陷入循环,若是,执行步骤3.6;
步骤3.4d:检查最后一个未返回的外部API函数func,若该库函数为常见库函数,执行步骤3.7,否则,执行步骤3.5;
步骤3.5:把提供func函数的共享库文件在内存中加载的地址范围加入到addr_range中,执行步骤2.1;
步骤3.6:寻找服务守护程序出错的原因,具体如下:
步骤3.6a:将bb_list中的每一个block的基本块内容转换成中间语言;
步骤3.6b:从bb_list最后一个未被扫描到的block开始,往前寻找一个包含条件跳转的基本块s;
步骤3.6c:初始化数组tainted_regs和tainted_mems,分别用于存放已被标记的寄存器和内存地址;
步骤3.6d:以s为起点,往前寻找最后一个包含条件跳转的未被分析的基本块,对其进行反向污点分析;
步骤3.6e:检查该基本块被执行前r0寄存器的标记状态,若未被标记,执行步骤3.6d;否则,执行步骤3.6f;
步骤3.6f:对api_trace,检查该基本块的起始地址是否为一个函数调用的返回点,如果是,执行步骤3.6g;否则,执行步骤3.6d;
步骤3.6g:检查该函数返回值是否代表错误,若是,执行步骤3.7;否则,执行步骤3.6h;
步骤3.6h:清除所有用于传递函数调用参数的寄存器的污点状态;
步骤3.6i:执行步骤3.6d;
步骤3.7:尝试获取该函数调用的参数内容。
9.根据权利要求8所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤4具体包括以下步骤:
步骤4.1:检查导致服务守护程序出错的函数调用的函数来源,若该函数来自常见的共享链接库,执行步骤4.2;否则,执行步骤4.3;
步骤4.2:具体如下:
步骤4.2a:检查该函数调用的参数内容是否都获取成功,若成功,执行步骤4.2d;
步骤4.2b:生成用于获取该函数参数具体内容的信息获取指令in,加入到in_queue中;
步骤4.2c:执行步骤2;
步骤4.2d:针对该函数的函数名和重要参数,生成修复建议;
步骤4.2e:将修复建议应用到模拟环境中;
步骤4.2f:执行步骤2;
步骤4.3:具体如下:
步骤4.3a:计算出一个可让服务守护程序在条件跳转处走向另一条分支的函数返回值;
步骤4.3b:生成用于修改该函数返回值的寄存器修改指令op,加入到op_queue中;
步骤4.3c:执行步骤2。
10.根据权利要求1所述的一种嵌入式设备固件的安全性分析方法,其特征在于,所述步骤5中,使用漏洞扫描工具或攻击代码测试已启动的网络服务。
CN202010193286.5A 2020-03-18 2020-03-18 一种嵌入式设备固件的安全性分析方法 Active CN111428233B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202010193286.5A CN111428233B (zh) 2020-03-18 2020-03-18 一种嵌入式设备固件的安全性分析方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202010193286.5A CN111428233B (zh) 2020-03-18 2020-03-18 一种嵌入式设备固件的安全性分析方法

Publications (2)

Publication Number Publication Date
CN111428233A true CN111428233A (zh) 2020-07-17
CN111428233B CN111428233B (zh) 2022-11-04

Family

ID=71549635

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202010193286.5A Active CN111428233B (zh) 2020-03-18 2020-03-18 一种嵌入式设备固件的安全性分析方法

Country Status (1)

Country Link
CN (1) CN111428233B (zh)

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111881455A (zh) * 2020-07-27 2020-11-03 绿盟科技集团股份有限公司 一种固件安全分析的方法及装置
CN113110891A (zh) * 2021-04-21 2021-07-13 深圳忆联信息系统有限公司 固态硬盘的固件加载方法、装置、计算机设备及存储介质
CN117077151A (zh) * 2023-10-16 2023-11-17 北京华云安信息技术有限公司 漏洞挖掘方法、装置、设备以及存储介质

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20130339929A1 (en) * 2012-06-14 2013-12-19 Microsoft Corporation Program repair
CN106909829A (zh) * 2015-12-22 2017-06-30 中电科技(北京)有限公司 适用于龙芯台式计算机的软件安全保护系统及其保护方法
CN107506259A (zh) * 2017-06-26 2017-12-22 努比亚技术有限公司 系统修复方法、终端及管理方法、服务器及存储介质
CN109002721A (zh) * 2018-07-12 2018-12-14 南方电网科学研究院有限责任公司 一种信息安全漏洞的挖掘分析方法

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20130339929A1 (en) * 2012-06-14 2013-12-19 Microsoft Corporation Program repair
CN106909829A (zh) * 2015-12-22 2017-06-30 中电科技(北京)有限公司 适用于龙芯台式计算机的软件安全保护系统及其保护方法
CN107506259A (zh) * 2017-06-26 2017-12-22 努比亚技术有限公司 系统修复方法、终端及管理方法、服务器及存储介质
CN109002721A (zh) * 2018-07-12 2018-12-14 南方电网科学研究院有限责任公司 一种信息安全漏洞的挖掘分析方法

Non-Patent Citations (3)

* Cited by examiner, † Cited by third party
Title
YI LI ETC.: "Research of Industrial Control System Device Firmware Vulnerability Mining Technology Based on Taint Analysis", 《IEEE》 *
卢洪涛: "基于嵌入式系统的装备故障检测平台软件设计", 《硕士电子期刊》 *
韩心慧等: "二进制程序中的use-after-free漏洞检测技术", 《清华大学学报(自然科学版)》 *

Cited By (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111881455A (zh) * 2020-07-27 2020-11-03 绿盟科技集团股份有限公司 一种固件安全分析的方法及装置
CN111881455B (zh) * 2020-07-27 2023-12-01 绿盟科技集团股份有限公司 一种固件安全分析的方法及装置
CN113110891A (zh) * 2021-04-21 2021-07-13 深圳忆联信息系统有限公司 固态硬盘的固件加载方法、装置、计算机设备及存储介质
CN113110891B (zh) * 2021-04-21 2022-03-29 深圳忆联信息系统有限公司 固态硬盘的固件加载方法、装置、计算机设备及存储介质
CN117077151A (zh) * 2023-10-16 2023-11-17 北京华云安信息技术有限公司 漏洞挖掘方法、装置、设备以及存储介质
CN117077151B (zh) * 2023-10-16 2024-01-26 北京华云安信息技术有限公司 漏洞挖掘方法、装置、设备以及存储介质

Also Published As

Publication number Publication date
CN111428233B (zh) 2022-11-04

Similar Documents

Publication Publication Date Title
Manès et al. The art, science, and engineering of fuzzing: A survey
US6820256B2 (en) System and method for whole-system program analysis
CN111428233B (zh) 一种嵌入式设备固件的安全性分析方法
US8621279B1 (en) System and method for generating emulation-based scenarios for Error Handling
US20060253739A1 (en) Method and apparatus for performing unit testing of software modules with use of directed automated random testing
JP2006185211A (ja) プログラム解析装置、テスト実行装置、その解析方法及びプログラム
CN110245467B (zh) 基于Dex2C与LLVM的Android应用程序保护方法
US10083029B2 (en) Detect application defects by correlating contracts in application dependencies
JP6142705B2 (ja) オブジェクト指向言語のための記号テストドライバの反復生成
CN111694746A (zh) 面向编译型语言AS3的Flash缺陷模糊测评工具
US20220197777A1 (en) System and methods for live debugging of transformed binaries
US11461472B2 (en) Automatic correctness and performance measurement of binary transformation systems
US20060026584A1 (en) Explicit linking of dynamic link libraries
CN115017516A (zh) 一种基于符号执行的模糊测试方法
Quach et al. Bloat factors and binary specialization
CN112419057A (zh) 智能合约的日志生成及保存方法、装置、设备和存储介质
Ognawala et al. Compositional fuzzing aided by targeted symbolic execution
CN115062309A (zh) 一种新型电力系统下基于设备固件仿真的漏洞挖掘方法及存储介质
Peng et al. {GLeeFuzz}: Fuzzing {WebGL} Through Error Message Guided Mutation
US8997048B1 (en) Method and apparatus for profiling a virtual machine
US11720474B2 (en) System and methods for post mortem debugging of transformed binaries
CN113438273B (zh) 一种物联网设备中应用程序的用户级仿真方法及装置
Belle Lakshminarayan Fuzzing: A Comparison of Fuzzing Tools
JP2022150518A (ja) テスト処理プログラム、テスト処理方法および情報処理装置
JP6586143B2 (ja) ファイルの実行をエミュレートするシステム及び方法

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant