文章目录

前言

什么是OTA?

OTA(Over-the-Air)是一种通过无线通信网络(如Wi-Fi、蜂窝网络)远程下载和安装设备固件或软件更新的方式。这种方式广泛应用于智能手机、物联网设备、汽车电子等领域。
小米发烧友估计对此并不陌生,线刷、卡刷、各种系统的刷机包,最近的澎湃OS不知道各位米友试着刷了没有。当然还有路由器、汽车,甚至台灯等各种智能家居,都是通过OTA的方式进行升级更新。
这里笔者通过两个固件解压包分析案例,来学习固件安全相关内容。

升级包(固件)的类型和架构

二进制映像(.bin):最常见的固件格式,包含了设备运行所需的所有代码和数据,通常用于路由器、摄像头、物联网设备等。
压缩包(.zip, .tar, .gz, .xz):将多个文件打包并压缩成一个文件。
映像文件(.img):包含整个文件系统映像,通常用于嵌入式设备和操作系统镜像(Linux、Android)。
Intel HEX文件(.hex):一种文本格式的固件文件,常用于微控制器和嵌入式系统。
Motorola S-record文件(.srec, .s19):类似于Intel HEX格式的文本固件文件。
ELF文件(.elf):一种可执行和可链接格式,包含可执行代码和数据段,常用于嵌入式系统开发。
如下所示,服务商会提供多种格式固件,方便客户进行分析
【产品那些事】固件安全-关于OTA升级包分析_车联网

案例

tp-link路由器升级包

 固件下载链接
解压后目录结构如下,当前我们关注的还是bin文件
【产品那些事】固件安全-关于OTA升级包分析_车联网_02

怎么解包分析?

这里以.bin格式的固件为例,因为没有明显的文件边界和结构,所以分析起来难度也相对要高些,这里我们使用binwalk来提取和解析内容

binwalk安装及使用
sudo apt-get install binwalk 	// ubuntu
brew install binwalk			// macos
  • 1.
  • 2.
# 识别包含的文件和数据结构
binwalk firmware.bin
  • 1.
  • 2.

【产品那些事】固件安全-关于OTA升级包分析_IOT安全_03

# 递归提取内容
binwalk -Me firmware.bin
  • 1.
  • 2.

【产品那些事】固件安全-关于OTA升级包分析_IOT安全_04
将二进制里面的ubi格式文件提取出来之后

什么是ubi格式文件?
UBI(Unsorted Block Image)是一种用于 NAND 闪存的文件系统,它提供了对闪存的磨损均衡和坏块管理。UBI 文件系统常见于嵌入式设备中,尤其是在需要可靠性和耐用性的场景。
为什么这里是ubi格式呢?
可以理解为bin是一种通用的二进制格式,在固件打包过程中,不同的文件系统和数据格式被统一打包成 .bin 文件,以简化传输和更新过程。
固件文件可以包含多种文件系统格式,如 UBI、EXT4、FAT32 等。这些文件系统格式用于存储操作系统、应用程序、驱动程序和配置文件等。

解压后的ubi文件
【产品那些事】固件安全-关于OTA升级包分析_IOT安全_05

ubi_reader安装及使用

ubi_reader 是一个用于处理 UBI 文件系统的工具集。它包括几个命令行工具,用于读取和提取 UBI 和 UBIFS 映像文件。

#  Ubuntu/Debian 
sudo apt-get update
sudo apt-get install python3 python3-pip mtd-utils
# Centos
sudo yum install python3 python3-pip mtd-utils
# pip安装
pip3 install ubi_reader
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
# 查看 UBI 映像文件的信息
ubireader_display_info 12D4.ubi
  • 1.
  • 2.

【产品那些事】固件安全-关于OTA升级包分析_IOT安全_06

# 提取 UBI 映像文件中的所有内容
ubireader_extract_images 12D4.ubi
  • 1.
  • 2.

【产品那些事】固件安全-关于OTA升级包分析_IOT安全_07
当然还有其他命令 这里就不一一演示了

# 列出 UBI 映像文件中的文件
ubireader_list_files 12D4.ubi
# 提取特定的文件或块
ubireader_extract_files 12D4.ubi
  • 1.
  • 2.
  • 3.
  • 4.
unsquashfs安装及使用

unsquashfs 是一个用于解压和提取 SquashFS 文件系统映像的工具。SquashFS 是一种高压缩的只读文件系统格式,常用于嵌入式设备和 Linux 发行版中。

# ubuntu
sudo apt-get update
sudo apt-get install squashfs-tools
# centos
sudo yum install squashfs-tools
# macos
brew install squashfs
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

【产品那些事】固件安全-关于OTA升级包分析_IOT安全_08

使用unsquashfs工具将ubifs文件进行一一解包

固件开发人员在构建固件时,可能使用了多个文件系统和压缩格式混合的方法

unsquashfs -d output img-2022911448_vol-ubi_rootfs.ubifs
  • 1.

【产品那些事】固件安全-关于OTA升级包分析_安全产品_09
可以看到固件源码基本上可以获取到了……
【产品那些事】固件安全-关于OTA升级包分析_车联网_10

某车企OTA升级包

经过一系列解压处理后,得到了payload.bin文件(类似Android刷机包)
这里先是使用binwalk进行解压,结果陷入了死循环
【产品那些事】固件安全-关于OTA升级包分析_固件_11
最后解压出来的xz包竟高达半个T!显示是解压方式错误,遂放弃

通用Android OTA解包

【产品那些事】固件安全-关于OTA升级包分析_车联网_12
解包后的 OTA 文件生成了许多 .img 文件,这些文件对应不同的设备分区,每个分区都有其特定的功能
【产品那些事】固件安全-关于OTA升级包分析_IOT安全_13

相关分区
分类分区名称描述
引导和启动boot.img包含内核和初始文件系统(ramdisk),用于引导 Android 系统。
dtbo.img包含设备树覆盖文件,用于硬件抽象。
vendor_boot.img包含启动供应商相关的驱动程序和配置文件。用于初始化供应商设备驱动。
xbl.img包含可扩展引导加载程序的固件。
xbl_config.img包含引导加载程序配置数据。
abl.img包含 Android 引导加载程序,用于加载和启动操作系统。
硬件驱动和固件aop.img包含用于管理低功耗模式和传感器的固件。
bluetooth.img包含蓝牙驱动和固件。
cpucp.img包含 CPU 控制处理器的固件。
devcfg.img包含设备配置数据和驱动。
dsp.img包含数字信号处理器(DSP)的固件,用于音频处理等任务。
featenabler.img包含特性启用配置文件,用于启用或禁用特定功能。
hyp.img包含虚拟机监控程序(Hypervisor)的固件,用于虚拟化支持。
imagefv.img包含 UEFI 固件卷,用于引导和硬件初始化。
modem.img包含调制解调器固件,用于蜂窝网络通信。
qupfw.img包含 Qualcomm 固件,用于处理无线电信号。
shrm.img包含共享内存驱动。
tz.img包含 ARM TrustZone 的固件,用于安全处理和加密操作。
uefisecapp.img包含用于 UEFI 安全启动的应用程序。
系统和应用system.img包含 Android 操作系统的主要部分,包括系统应用、库文件、框架等。
system_ext.img存放系统扩展部分,主要用于特定功能或服务的扩展。从 Android 10 开始引入,用于增强系统模块化。
product.img包含特定产品功能和应用。用于不同设备型号或市场版本的定制。
vendor.img包含与硬件相关的驱动程序和库文件,由设备制造商提供。与硬件抽象层(HAL)和供应商接口(VINTF)相关。
odm.img包含设备制造商(ODM)提供的特定硬件驱动和配置文件。用于特定硬件的支持。
multiimgoem.img包含多个 OEM 特定的映像和配置。
安全和验证keymaster.img包含密钥管理器固件,用于加密和解密操作。
vbmeta.img包含用于 Android Verified Boot 的元数据。
vbmeta_system.img包含用于 Android Verified Boot 的系统元数据。
第二层解包

第二层相对来说较为容易,在 Windows 或 Linux 系统上,可以使用 7-Zip 工具解压 .img 文件,写一个批量解压的脚本

#!/bin/bash

# 创建输出目录
output_dir="./output"
mkdir -p "$output_dir"

# 遍历当前目录下的所有 .img 文件
for img_file in *.img; do
  # 获取文件名(不包括扩展名)
  file_name=$(basename "$img_file" .img)
  
  # 创建解压后的输出目录
  extracted_dir="$output_dir/${file_name}_extracted"
  mkdir -p "$extracted_dir"
  
  # 使用 7z 解压 img 文件到相应的输出目录
  7z x "$img_file" -o"$extracted_dir"
  
  # 检查解压结果
  if [ $? -eq 0 ]; then
    echo "Successfully extracted $img_file to $extracted_dir"
  else
    echo "Failed to extract $img_file"
  fi
done
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

【产品那些事】固件安全-关于OTA升级包分析_IOT安全_14
这里需要注意的是,.img文件可能是由不同文件格式转换成的(ext4、ubi、elf),所以具体的解压步骤还要视情况而定……