路由器文件系统
路由器固件
路由器的固件不是硬件,而是软件,因为在路由器中,它通常是被固化在只读存储器中的,所以称为固件。通常我们所说的更新路由器是指更新路由器的固件,路由器的固件中包含操作系统的内核及文件系统。
文件系统
文件系统是操作系统的重要组成部分,是操作运行的基础。不同的路由器使用的文件系统格式不尽相同。根文件系统会被打包成当前路由器所使用的文件系统格式,然后组装到固件中。路由器希望文件系统越小越好,所以这些文件系统中各种压缩格式随处可见。
Squashfs是一个只读格式的文件系统,具有超高压缩率,其压缩率最高可达34%。当系统启动后,会将文件系统保存在一个压缩过的文件系统文件中,这个文件可以使用换回的形式挂载并对其中的文件进行访问,当进程需要某些文件时,仅将对应部分的压缩文件解压缩。
Squashfs文件系统常用的压缩格式有GZIP、LZMA、LZO、XZ(LZMA2)。路由器的根文件系统通常会按照Squashfs文件系统常用压缩格式中的一种进行打包,形成一个完整的Squashfs文件系统,然后与路由器操作系统的内核一起形成更新固件。
手动提取文件系统
方法
拿到路由器固件后首先利用Linux自带的file命令查看文件类型,得到的结果仅供参考,如果没有发现符合任何文件类型的匹配,也不代表该固件就是完全没有接触过的文件格式,原因在于file命令是从给定文件的首字节开始的,会按照既定格式进行模式匹配。
如果没有妨碍西安符合要求的文件格式,就采用一下方法进行分析:
1、”stings|grep”检索文件系统magic签名头。
2、”hexdump|grep”检索magic签名偏移。
3、”dd|file”确定magic签名偏移处的文件类型。
magic签名头
文件系统magic签名头是指一个文件系统中包含的一串可识别字符,有了这串字符,表明该文件可能包含某个文件系统。当然如果要确定是否包含某个文件系统还需要其他条件证明,就是第2、3两步。如Windows应用程序就是以字符串”MZ”开头,但不代表所有的以”MZ”开头的都是.exe文件。
常见的文件系统头部特征如下:
cramfs文件头部特征字符为”0x28cd3d45”
squashfs文件系统头部特征较多,有sqsh、hsqs、qshs、shsq、hsqt、tqsh、sqlz
实例
从D-Link官网下载固件DIR-645 1.04 B11,地址为ftp://ftp2.dlink.com/PRODUCTS/DIR-645/REVA/DIR-645_FIRMWARE_1.04.B11.ZIP,提取后拿到其中的.bin文件。
检索文件系统的magic签名
先用file查看,可以看到无法分析出文件类型。
接下来查看magic头,先看看是不是cramfs,因为不知道文件是大端还是小端所以两个都要试下。结果发现都不是。
再来查squashfs,文件头部一个个试。查到一个hsqs的签名头,但还不能确定是不是一定就是包含了squashfs文件系统。
查看文件十六进制里面是否有hsqs,可以看到确实有,在文件0x160090的位置
用dd命令复制从0x160090开始的100字节数据。之所以要复制100字节的数据,是因为squashfs文件系统的头部校验不会超过100字节。1441936是0x160090的10进制。
接着用file查看文件格式,可以看到现在已经能发现文件就是Squashfs文件格式的了。并且还知道了文件的大小。
我们已经知道了fireware.bin在偏移0x00160090处包含Squashfs文件系统,其大小为6164554字节,用dd命令复制这块数据块。
已经拿到了文件系统,接下来就是还原文件系统的根文件系统了。可以用
file -m filesystems kernel.squash命令来查看更深层次的文件信息。这里我在尝试的时候出现了问题,和作者一样的命令但我的就无法显示出结果。
这是我的
这是作者的
可以看到是lzma压缩,接着可以用firmware-mod-kit解压缩。
安装firmware-mod-kit,具体可以看这个https://blog.csdn.net/qq1084283172/article/details/68061957。作者的安装代码我失败了。
需要安装的依赖库文件
$ sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
git clone https://github.com/mirror/firmware-mod-kit.git
进入源码目录
cd firmware-mod-kit/src
执行configure文件生成Makefile文件然后make编译生成可执行文件
./configure && make
安装完之后解压缩./unsquashfs_all.sh kernel.squash
解压完之后可以看到当前文件目录下有一个root文件,点开之后就是文件系统根文件
自动提取文件系统
Binwalk智能固件扫描
Binwalk和libmagic
Binwalk并不是简单使用file命令识别文件类型,原因在于file命令占用了太多的磁盘来读写I/O,效率太低,而且file命令识别文件类型是从文件的第一个字节开始,且只能把磁盘上的一个文件识别成一种文件格式,所以会占用很多磁盘空间来保存文件。此外,如果使用file命令,就需要逐字节把路由器固件文件分割成多个文件,文件的I/O也必然会极大影响扫描效率。
libmagic动态库为文件扫描提供了更好的方法。可以直接扫描文件的内存镜像。libmagic库识别文件系统和文件类型依然依赖magic签名文件。
在Binwalk中,主要使用来自libmagic库的4个函数,分别是magic_open、magic_close、magic_buffer、magic_load,在binwalk/src/fike-5.18/src/magic.h中可以找到这几个函数。
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算法流程
binwalk的提取与分析
固件扫描
binwalk firmware.bin//固件扫描。可以看到这里直接分析出了文件的信息,包括我们前面手动分析的LZMA压缩以及Squashfs文件头。
提取文件
binwalk -e firmware.bin//提取文件。选项“-e”和“–extract”用于按照预定义的配置文件中的提取办法从固件探测到文件及系统。
同时当前文件目录下出现一个_firmware.bin.extracted文件,进入之后可以看到里面的root就是文件系统根文件。
binwalk -Me firmware.bin//选项“-M”和“–matryoshka”用于根据magic签名扫描结果进行递归提取,仅对“-e”和“–dd”选项有效
binwalk -Me -d 5 firmware.bin//选项”-d”和“–depth=
显示完整结果
binwalk -I firmware.bin//选项“-I”和“–invalid”会显示所有结果,有大量无用信息。
指令系统分析
binwalk -A 70 | more//选项“-A”和“–opcodes”用于扫描制定文件中通用CPU架构的可执行代码。70文件夹是前面提取到的文件里面的另一个文件。 |
参考链接
《揭秘家用路由器0day漏洞挖掘技术》