Binwalk是路由器固件分析的必备工具,该工具最大的优点就是可以自动完成指定文件的扫描,智能发掘潜藏在文件中所有可疑的文件类型及文件系统。
1、Binwalk和libmagic
Binwalk的扫描实现方法,就是把重复而复杂的手工分析方法通过程序实现。但是Binwalk并不是简单地使用file命令识别文件类型,原因在于file命令占用了太多的磁盘来读写I/O,效率太低,而且file命令识别文件类型是从文件的第一个字节开始,且只能把磁盘上的一个文件识别成一种文件格式,所以会占用很多磁盘空间来保存文件,此外,使用file命令,就需要逐字节把路由器文件分割成多个文件,文件的I/O也必然会极大影响扫描效率。
libmagic动态库为文件扫描提供了更好的解决方案。识别libmagic库函数,可以直接扫描文件的内存镜像,从而提高扫描效率。libmagic库识别文件系统和文件类型依然依赖magic签名文件。
在binwalk中,主要使用来自libmagic库的4个函数,分别为magic_open、magic_close、magic_buffer、magic_load。
magic_t magic_open(int flags); —–> 创建并返回一个magic_cookie指针。
void magic_close(magic_t cookie); —–> 关闭magic签名数据库并释放所有使用过的资源。
const char *magic_buffer(magic_t cookie, const void *buffer, size_t len); ——-> 读取buffer中指定长度的数据并与magic签名数据库进行对比,返回对比结果描述。
int magic_load(magic_t cookie, const char *filename); ———> 从filename指定文件加载magic签名数据库,binwalk把多个magic签名文件组合到一个临时文件中用于加载。
binwalk是使用python编写的,它通过python调用libmagic库中的导出函数并使用面向对象的方式进行封装,封装文件在binwalk/src/binwalk/core/magic.py中。Magic类包含两个成员函数:
Magic.buffer(data)函数,读取内存缓冲区数据,判断是否符合某一文件类型。
Magic.close()函数:关闭magic签名数据库,释放所有使用的资源。
2、Binwalk的提取与分析
2.1、固件扫描
命令:binwalk firmware.bin —–> 通过扫描能够智能地发现目标文件中包含的所有可识别的文件类型。
2.2、提取文件
命令:binwalk -e firmware.bin ——> 选项“-e”和“–extract”用于按照定义的配置文件中的提取方法从固件中提取探测到的文件系统。
命令:binwalk -Me firmware.bin —–> 选项“-M”和“–matryoshka”用于根据magic签名扫描结果进行递归提取,仅对”-e”和“–dd”选项有效。
命令:binwalk -Me -d 5 firmware.bin —-> 选项“-d”和“–depth=<int>”用于限制递归提取深度,默认深度为8,仅当“-M”选项存在时有效。
2.3、显示完整的扫描结果
命令:binwalk -I firmware.bin ——> 选项”-I”和“–invalid”用于显示扫描的所有结果(即使是扫描过程中被定义为“invalid“的项)。
当我们认为binwalk错把有效的文件当成无效文件时,可以通过该选项来检查。
2.4、指令系统分析
选项“A”和“–opcodes”用于扫描指定文件中通用CPU架构的可执行代码。
由于某些操作码签名比较短,所以比较容易造成误判。如果我们需要确定一个可执行文件的CPU架构,可以使用该命令。
命令:命令:binwalk -A 70|more
使用Binwalk扫描从firmware.bin中提取的文件的文件“70”中的可执行代码,在该文件中可以发现CPU的架构(大端或者小端也会给出)。