第二章:固件获取与初步分析

好,咱们正式开始动手了。这一章,我带你走一遍固件分析的第一个环节——把固件搞到手,然后拆开看看里面到底装了啥。

说实话,固件分析最怕什么?最怕你连固件都拿不到,或者拿到了却不知道怎么下手。我早期做逆向的时候,就吃过这个亏。有一次客户扔给我一个设备,说“你分析一下”,结果我花了三天才把固件从板子上读出来……嗯,那都是血泪史。

今天咱们就聊聊,怎么从思科官网或者设备里把固件弄出来,然后用 Binwalk 这把“瑞士军刀”把它拆开,最后看看固件里头到底藏着什么。

2.1 固件获取:两条路,总有一条走得通

获取固件,说白了就两条路:官网下载设备提取。我个人习惯,能下载的绝不硬拆,省时省力。

2.1.1 从思科官网下载

思科官网的固件下载其实挺友好的。你只要有一个合法的服务合同,登录 Cisco.com,找到你的设备型号,就能看到对应的固件版本列表。

  • 搜索路径:Support > Download Software > 输入设备型号
  • 常见格式:.bin、.tar、.pkg、.iso
  • 注意:有些固件需要特定的授权,别想着白嫖,合规第一
我的小技巧:下载时尽量选最新的稳定版本。老版本可能有已知漏洞,但新版本加密手段也可能升级。我一般会下载两个版本——一个老的,一个新的,对比着看。

2.1.2 从设备中提取

如果官网没有,或者你想分析设备当前运行的固件,那就得从设备里“抠”出来。这条路稍微麻烦点,但也不是没办法。

  • 通过串口/SSH:如果设备能进系统,用 cat /dev/mtdblock0 > /tmp/firmware.bin 之类的命令,把 Flash 分区读出来
  • 通过 JTAG/SWD:如果设备变砖了,或者有硬件保护,那就得上编程器或者 JTAG 调试器。我常用的有 FT2232H 和 J-Link
  • 拆芯片读:最后的手段——把 Flash 芯片吹下来,放到编程器上读。这招我一般不用,太伤板子
注意:从设备提取固件,一定要确认你有合法权限。别乱拆别人的设备,小心吃官司。

2.2 Binwalk 解包:固件分析的“第一刀”

固件拿到手了,接下来就是拆包。Binwalk 是我最常用的工具,没有之一。它就像一个文件格式探测器,能自动识别固件里嵌了哪些东西。

2.2.1 安装 Binwalk

安装很简单,我建议用 Python 版本,跨平台支持好。

# 安装依赖
sudo apt-get install build-essential autoconf automake libtool
sudo apt-get install python3-pip

# 安装 Binwalk
pip3 install binwalk

# 验证安装
binwalk --help

嗯,这里要注意。如果你用的是 macOS,记得先装 Xcode Command Line Tools。Windows 用户嘛……我建议直接上 WSL 或者虚拟机,省得折腾。

2.2.2 扫描固件结构

拿到固件后,第一件事就是扫描。看看里面到底有什么。

binwalk firmware.bin

输出大概长这样:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             u-boot legacy image, Linux Kernel Image
1024          0x400           Squashfs filesystem, little endian, version 4.0
4096          0x1000          LZMA compressed data
65536         0x10000         JFFS2 filesystem, little endian

看到没?Binwalk 直接告诉我们:偏移 0 处是 U-Boot偏移 1024 处是 Squashfs 文件系统。这就是固件的骨架。

2.2.3 提取文件系统

扫描完了,就该提取了。我最常用的命令是:

binwalk -e firmware.bin

这个 -e 参数会自动提取所有可识别的文件。提取完后,你会看到一个 _firmware.bin.extracted 文件夹,里面就是拆出来的东西。

核心知识点:Binwalk 的 -e 参数默认会递归提取。也就是说,如果文件系统里还有压缩包,它也会帮你解开。但有时候递归太深会导致文件混乱,我一般会先用 -D 参数指定只提取特定类型。

2.3 固件结构初步识别:看懂固件的“骨架”

固件拆开了,接下来就是识别它的结构。一个典型的嵌入式 Linux 固件,通常包含三大部分:Bootloader内核文件系统

2.3.1 Bootloader(引导加载程序)

思科设备最常用的 Bootloader 是 U-Boot。它负责初始化硬件、加载内核。你可以在固件开头找到它,通常以 u-bootU-Boot 字符串开头。

  • 特征:开头有 U-Boot 的魔数(0x27051956)
  • 作用:引导内核、提供命令行、支持网络启动
  • 分析价值:可以找到启动参数、内存布局、甚至后门

2.3.2 内核(Kernel)

内核通常是压缩过的,常见格式有 zImageuImage。Binwalk 能识别出内核的起始位置。

  • 特征:以 \x1f\x8b\x08(gzip)或 \xfd\x37\x7a\x58(xz)开头
  • 分析价值:可以提取内核模块、查看驱动、甚至找到隐藏的调试接口

2.3.3 文件系统(Filesystem)

思科最常用的是 SquashfsJFFS2。Squashfs 是只读的,适合固件;JFFS2 是可读写的,适合运行时数据。

  • Squashfs:压缩率高,只读,适合存放系统文件
  • JFFS2:可读写,适合存放配置、日志
  • 分析价值:文件系统里藏着所有可执行文件、配置文件、Web 页面

2.4 实战:用一张图看懂固件结构

说了这么多,不如画张图。下面是我用 SVG 画的一个典型思科固件结构图。你一看就明白了。

思科固件典型结构 Bootloader (U-Boot) 偏移 0x0 - 0x400 | 初始化硬件、加载内核 Linux Kernel (zImage/uImage) 偏移 0x400 - 0x10000 | 压缩的内核镜像 文件系统 (Squashfs / JFFS2) 偏移 0x10000 - 结尾 | 存放所有系统文件、配置、Web页面 启动流程:Bootloader → 内核 → 文件系统 注:实际偏移因设备型号而异,需用 Binwalk 扫描确认

你看,结构其实很简单。Bootloader 在最前面,负责“点火”;内核紧随其后,负责“发动引擎”;文件系统最后,负责“装货”。

2.5 避坑指南:我踩过的那些坑

最后,分享几个我实际项目中踩过的坑。你遇到了,能少走弯路。

  • 坑一:固件加密——我曾经拿到一个固件,Binwalk 扫描出来全是乱码。后来才发现,固件被 AES 加密了。你得先找到解密密钥,或者从设备内存中 dump 出解密后的数据。
  • 坑二:固件分片——有些思科设备会把固件分成多个部分,比如 Bootloader 单独一个分区,内核和文件系统在另一个分区。Binwalk 扫描单个文件可能看不到全貌。这时候,你得把整个 Flash dump 出来,或者用 binwalk -M 递归扫描。
  • 坑三:文件系统损坏——有一次我提取 Squashfs 时,Binwalk 报错说“unsupported compression”。后来发现是固件用了自定义的压缩算法。没办法,只能手动分析压缩头,写脚本解压。
我的建议:拿到固件后,先别急着提取。先用 binwalk 扫描,再用 hexdump -C 看看开头几个字节。很多时候,固件的“身份信息”就藏在开头那 64 字节里。

好了,这一章就到这里。固件获取和解包,是后续所有分析的基础。你只要把这一步走稳了,后面的内核分析、漏洞挖掘,才能顺风顺水。


公众号:蓝海资料掘金营,微信deep3321