我的位置 态势感知  >  安全态势

原创 | 利用010 Editor进行固件格式分析

来源:关键基础设施安全应急响应中心 时间:2020-02-27 阅读次数:

绿盟科技工业物联网安全实验室 李东宏

针对未知物联网设备的安全评估,获取固件并通过拆解获取相关的运行程序文件是必经之路。一般可以通过官方网站、售后服务、调试接口、管理接口以及编程器读取的方式获得固件。固件的格式随着厂商和型号的不同而有所差异,针对未混淆格式一般使用binwalk、FMT等自动化工具可以进行分析,但往往拿到的固件是无法通过这些自动化工具直接进行拆解的,需要对固件格式进行人工手动分析。本文将会使用010 Editor二进制编辑工具以某厂商的手机固件为例进行人工分析,并编写拆解程序。

010 Editor简介

010 Editor是一款非常强大的文本/十六进制编辑器,除了文本/十六进制编辑外,还包括文件解析、计算器、文件比较等功能,但它真正的强大之处还在于文件的解析功能,可以使用010 Editor官方网站提供的解析脚本(Binary Template)对avi、bmp、png、exe等简单格式的文件进行解析,当然也可以根据需求来自己编写文件解析脚本。

分析目标

本次以S680固件为例进行分析,直接通过file命令查看文件格式,发现无法识别:

$file S680_SS_S_2_030_0055_120710.qsb
S680_SS_S_2_030_0055_120710.qsb:data

使用binwalk直接解包,发现解出的文件目录结构存在很大的问题。

这种文件目录结构由于没有明确的含义,谁看了都会晕头转向,不知所云。

文件格式
固件主要分为三大部分
固件信息头

固件信息头包含256个字节,其结构如下:

typedef struct {    char magic[8];//文件标识    unsigned int checksum;//文件32位校验和    unsigned int len;//文件长度    char buildinfo[32];//创建信息    char descript[32];//描述信息    unsigned int createTime;//创建时间    unsigned int filecount;//包含的文件数    char pad[168];//填充

S680的rom 文件信息头分析如下:

此部分影响后面的分解因素为包含的文件个数,同时要求这个数值必须小于128。

固件中各个文件的信息部分

此部分每个文件的信息也是占用256个字节,其结构如下:

typedef struct {    char filename[64];//文件名    char partionName[32];//写入到的分区名    unsigned int checksum;//文件校验和    unsigned int createTime;//文件创建时间    unsigned int fileStartAddr;//文件数据开始位置    unsigned int filelen;//文件数据长度    unsigned int isdata;//文件是否为数据类型    unsigned int flash;//文件是否可以被FLASH    unsigned int blocks;//文件占用的块数    unsigned int id;//文件ID    char pad[128];}FILEINFO;

以第一个文件为例,分析结果如下:

此部分影响后面分解文件的因素为文件的起始地址,文件的长度,文件的块数。

文件数据部分

文件数据部分则为原始的二进制数据合并而来的。

010 Editor v4.0.2 Binary Template

针对固件的格式分析完后,编写固件格式解析脚本如下:

//--------------------------------------//--- 010 Editor v4.0.2 Binary Template////File: QSB File Parser//--------------------------------------LittleEndian();typedef struct {  char magic[8]<comment="magic of file">;  unsigned int checksum<comment="check of file">;  unsigned int len<comment="the length of file">;  char buildinfo[32]<comment="the build info of file">;  char descript[32]<comment="the decription of file">;  unsigned int createTime<comment="the time of file create">;  unsigned int filecount<comment="the file cout of file include">;  char pad[168]<comment="pad bytes">;}HEADER;typedef struct {  char filename[64]<comment="the name of file">;  char partionName[32]<comment="the name of partition while the file will flash to">;  unsigned int checksum<comment="the checksum of this file">;  unsigned int createTime<comment="the create time of this file">;  unsigned int fileStartAddr<comment="the start address in rom file">;  unsigned int filelen<comment="the length of this file">;  unsigned int isdata<comment="Mark the data type">;  unsigned int flash<comment="Make flash action">;  unsigned int blocks<comment="Blocks of this file">;  unsigned int id<comment="ID">;  char pad[128];}FILEINFO<optimize=true>;typedef struct{  local int len = datalen;  BYTE data[len];}Entry;//********define files *****************HEADER header;FILEINFO fileinfo[0x7F];local int i = 0;local int datalen = 0;for(i=0; i < header.filecount;i++){  datalen=fileinfo[i].filelen;  FSeek(fileinfo[i].fileStartAddr);  Entry file;}
ROM解包

通过对ROM固件格式分析,利用C语言编写代码,编译解包工具为rom_depack.exe,在命令行运行解包命令进行固件拆解。

D:\rom>rom_depack.exe S680_SS_S_2_030_0055_120710.qsb        ****** Depack Tools of Qsb Format Rom ******[*] builder@QA-Build-Gorilla-024[*] S680_ SS_S_2_030_0055_120710[*] Extract file MBR0.bin[*] Extract file qcsblhd_cfgdata.mbn[*] Extract file qcsbl.mbn[*] Extract file fat.bin[*] Extract file EBR0.bin[*] Extract file oemsblhd.mbn[*] Extract file oemsbl.mbn[*] Extract file emmc_appsboothd.mbn[*] Extract file emmc_appsboot.mbn[*] Extract file boot.img[*] Extract file persist.img.ext4[*] Extract file system.img stage 1[*] Extract file system.img stage 2[*] Extract file system.img stage 3[*] Extract file system.img stage 4[*] Extract file system.img stage 5[*] Extract file preload.img stage 1[*] Extract file preload.img stage 2[*] Extract file preload.img stage 3[*] Extract file userdata.img stage 1[*] Extract file userdata.img stage 2[*] Extract file userdata.img stage 3[*] Extract file userdata.img stage 4[*] Extract file userdata.img stage 5[*] Extract file userdata.img stage 6[*] Extract file userdata.img stage 7[*] Extract file userdata.img stage 8[*] Extract file userdata.img stage 9[*] Extract file userdata.img stage 10[*] Extract file userdata.img stage 11[*] Extract file userdata.img stage 12[*] Extract file cache.img stage 1[*] Extract file recovery.img[*] Extract file udisk.bin[*] Success file to direct out

固件经过拆解后的目录结构如下:

其中文件系统位于system.img中,利用Binwalk或者360zip等工具再次进行自动化解包即可获得文件系统。

总结

针对未知格式分析,先寻找一下相关的字符串特征,观察字符串前后四个以内的字节与其的关系,根据距离规律进行分割定位,将非可视区域以四字节为单位进行分组标记,逐步缩小分组长度,验证每个字段的含义,通过Binary Template进行逐步标定,直到分析结束后即可通过编写代码构建解包工具,当然有部分固件中存在压缩数据,则需要根据压缩数据开始的4到8个字节匹配压缩格式魔数,利用相应的解压缩算法进行数据解压缩。

 

 

原文来源:关键基础设施安全应急响应中心

8条评论