固件简介
固件简介
前言
该文章用于总结部分网络的固件知识,不具有原创性,只是转载和总结。
固件下载
虽然通过官网下载固件的方法比较便捷,但是有些厂商并不会提供固件的下载链接,这就需要我们通过其他途径来获取固件。使用从硬件设备提取固件的方法会比较通用(前提是需要有实体机设备),因为固件一般都会存储在 PCB 的某个位置里。将设备拆开之后,找到相应的 flash rom 或者 Nor flash,使用专门的工具(烧写器、编程器)进行固件的提取。
先认识一下flash文件系统和固件类型
flash文件系统
与普通计算机系统不同的是,嵌入式系统往往需要使用低成本的存储器,诸如EEPROM
(带电可擦可编程只读存储器)或Nor/Nand Flash
等。Nand flash
存储器经常可以与NOR Flash
存储器互换使用。大多数情况下闪存只是用来存储少量的代码,这时NOR
闪存更适合一些,而NAND
则是高数据存储密度的理想解决方案。
这里列举一些最常见的Flash文件系统,具体如下:
Squashfs
SquashFS
是一套基于Linux内核使用的压缩只读文件系统,文件最大支持2^64字节。他是基于GPL协议的开源软件。初始的版本使用gzip压缩
,2.6.34版本Linux内核增加了支持LZMA和LZO压缩
,并且在2.6.3内核版本上增加支持XZ压缩
。OpenWrt以及DD-Wrt的固件
使用的就是这种文件系统,多见于4~16MB的Nor型Flash
中。
JFFS/JFFS2
全名是Journalling Flash File System
,是RedHat公司开发的闪存文件系统,最早是为NOR Flash设计的,自2.6版本以后开始支持NAND Flash,极适合用于嵌入式系统,多见于32MB以下的Nor型Flash固件中。它支持三种压缩算法:zlib、rubin以及rtime
。
YAFFS/YAFFS2
全称为Yet Another Flash File System
,是由Aleph One公司发展出来的NAND flash嵌入式文件系统。与JFFS不同的
是,YAFFS最初是专门针对Nand型Flash所设计的,对于大容量的Flash读写更有优势,而JFFS在小容量的FLASH中更具优势,两者各有侧重。这种文件系统多见于128MB以上的Nand型Flash
固件中。
固件提取
一般是通过串口UART
或者编程器去提取固件,由于没有对应的设备和工具,这里不再复现,简单贴一下大哥的博客
UART提取:https://www.cnblogs.com/pwnfeifei/p/16926238.html
编程器提取: https://www.cnblogs.com/pwnfeifei/p/16928361.html
固件类型
固件就是程序+文件系统的组合,由文件系统将多个程序组合成一个更大、更复杂的二进制文件。当然这里的大小指的是一个相对的概念。很多时候,固件的大小往往只有几MB,而在Windows或Linux上的可执行文件动辄就是几百MB,当然两者是不能比的,相比而言,固件是麻雀虽小,五脏俱全。
裸机程序
它是组成最简单的固件,也是最容易分析的固件,IDA可以正确识别并分析这种类型的固件。这类的设备可以看作是 “单片机设备”,设备固件中是比较简单的控制、循环逻辑,利用中断、例程来处理外部世界的各种事件,如常见的智能门锁内部固件
固件解包
binwak
是一款优秀的固件分析、固件解包工具。可以用来解析绝大多数没有加密的固件,进行解包从而获取到固件的文件系统。
针对不同的flash文件系统也有不同的工具来解包,比如
Firmware Mod Kit广泛应用于
Squashfs
类型的固件编辑,支持多款路由器,OpenWrt
和DD-Wrt
的所有固件,以及TP-Link、ASUS、D-Link
的大部分路由型号的固件。mtd-utils 由于
jffs/jffs2和yaffs/yaffs2
是基于MTD
的文件系统,因此可以使用Linux下的mtd-utils
中的内核工具来获得对这两种文件系统的支持
binwalk
binwalk通过识别文件头 智能扫描目标文件所有可识别的文件类型
“-e” 按照预定义的配置文件中的提取方法提取文件
“-M” 用于根据magic签名扫描结果进行递归提取
“-d” 用于限制递归提取深度,默认为8
“-A “ 使用普通可执行操作码签名扫描目标文件
提取文件
1 | binwalk -Me DIR818LW_FW205b03.bin |
[](https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20221022230518.png)
提取出的文件如下
[](https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20221022230518.png)
可以加上-t -vv参数查看详细的提取过程。通过输出信息,可以得知该固件系统没有加密压缩,好了之后就可以看到squashfs-root这个文件夹了。得到的squashfs-root就是固件系统
[](https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20221022230518.png)
firmware-mod-kit
firmware-mod-kit 工具包可用于提取固件中的文件系统,然后对其进行修改,并重新打包成固件。我们可以使用它对固件做定制化的修改,但是也有可能被恶意地用于在固件中添加后门等,所以在下载固件时应到官方网站下载,并检查固件是否被修改过。
该工具包支持以下固件:
DD-WRT v23 tested - versions v23 SP1 and later are compatible (soon older versions too).
DD-WRT v24 tested
OpenWrt White Russian tested
OpenWrt Kamikaze untested (should work) - not really necessary, based on OpenWrt has its Image Builder.
FreeWrt untested - should work ok
HyperWrt untested
Ewrt untested
Sveasoft Alchemy untested
Sveasoft Talisman untested
Linksys / other vendor not supported by scripts yet - haven’t added cramfs handling
ASUS WL-330G untested - should work ok
ASUS WL-520G untested - should work ok
ASUS WL-530G supported
ASUS WL-550G untested - should work ok
Trendnet TEW-632BRP tested
DLink DIR-615 untested
many others* untested
安装
可在 google code 下载 Firmware Mod Kit v0.99 安装包,然后解压安装,安装前需要先安装相应的依赖库。
1 | sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic |
使用
firmware-mod-kit 中包含以下几个工具脚本:
extract-firmware.sh:解包固件
build-firmware.sh:重新打包固件
check_for_upgrade.sh:检查更新
unsquashfs_all.sh:解包提取出来的 squashfs 文件
- 解包固件
使用以下命令解包固件,firmware.bin 为需解包的固件,working_directory 为解包结果存储位置。
1 | $ ./extract_firmware.sh firmware.bin working_directory/ |
- 重新打包固件
修改完解包后的文件系统后,使用 build_firmware.sh 重新打包固件,新生成的固件将存在 output_directory 目录下。
1 | $ ./build_firmware.sh output_directory/ working_directory/ |
固件对比
1 | git clone https://github.com/bmaia/binwall |
固件模拟
因为例如 MIPS、ARM 指令集是无法直接在 X86 的指令集机器上直接运行的,所以就需要使用一个模拟环境,可以用 qemu或者Firmadyne来模拟
qemu
qemu有系统模式和用户模式。对于只想模拟单个程序的话使用用户模拟即可;对于整个设备(摄像头、路由器等)的环境来说,使用系统模式比较方便
用户模式
以DIR-822为例子
[](https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20221022230518.png)
查看squashfs-root/bin/busybox
为mips32 静态链接程序,busybox
就是类似于linux下的/bin/sh
[](https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20221022230518.png)
所以用qemu-mips-static
来模拟,启动单个文件
1 | cp /usr/bin/qemu-mips-static . |
[](https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20221022230518.png)
可以看到运行成功了