2. 固件字符串提取与分析

任务说明

本案例面向嵌入式固件安全分析场景:拿到一个未知的固件二进制文件后,第一步通常是提取其中的可打印字符串,快速定位版本号、文件系统路径、调试命令、协议关键字等敏感信息,为后续逆向定位关键函数提供线索。你将使用 strings 工具完成一次完整的固件字符串提取与分析。

环境准备

本案例需要一台 Linux 机器(或 WSL),并安装 binutils(提供 strings 命令)。大多数发行版默认已安装,若缺失可用以下命令安装:

sudo apt-get install binutils   # Debian/Ubuntu
sudo yum install binutils       # RHEL/CentOS

准备测试固件

为便于复现,我们先用一段 C 代码编译出一个模拟固件,其中故意包含版本号、路径、命令等特征字符串。将以下代码保存为 demo_fw.c:

#include <stdio.h>
#include <string.h>

const char version[] = "FW_VERSION: 2.1.7-rc3";
const char build_path[] = "/home/builder/firmware/src/main.c";
const char debug_cmd[] = "AT+DEBUG=1";
const char wifi_ssid[] = "IoT_Home_2.4G";

void process_cmd(char *buf) {
    if (strstr(buf, "AT+REBOOT")) {
        printf("System rebooting...\n");
    } else if (strstr(buf, "AT+UART_BAUD=115200")) {
        printf("UART baud set to 115200\n");
    }
}

int main() {
    char input[64];
    printf("Firmware demo, version: %s\n", version);
    printf("Build path: %s\n", build_path);
    printf("Default SSID: %s\n", wifi_ssid);
    while (1) {
        printf("cmd> ");
        fgets(input, sizeof(input), stdin);
        input[strcspn(input, "\n")] = 0;
        process_cmd(input);
    }
    return 0;
}

编译生成固件镜像(静态链接以模拟真实固件中字符串较多的情况):

gcc -static -o demo_fw demo_fw.c

字符串提取与过滤

使用 strings 提取所有可打印字符串,并过滤掉长度过短的噪声(默认最小长度为 4):

strings -n 4 demo_fw > strings_all.txt
wc -l strings_all.txt

查看与目标信息相关的字符串:

grep -i "version\|FW_\|AT+\|\.c\|\.h\|/home\|/usr\|/etc" strings_all.txt

预期输出(与代码逻辑严格一致):

FW_VERSION: 2.1.7-rc3
/home/builder/firmware/src/main.c
AT+DEBUG=1
AT+REBOOT
AT+UART_BAUD=115200
IoT_Home_2.4G

分析要点

对提取结果按类别进行人工分析:

  • 版本信息:FW_VERSION: 2.1.7-rc3 表明固件版本为 2.1.7 的候选版本,可用于漏洞库匹配。
  • 路径泄漏:/home/builder/firmware/src/main.c 暴露了开发者的构建目录结构,可用于推测源码组织方式。
  • 调试/AT命令:AT+DEBUG=1、AT+REBOOT 等表明设备支持串口 AT 指令,可尝试通过 UART 接口交互。
  • 默认配置:IoT_Home_2.4G 可能是默认 Wi-Fi SSID,可用于识别设备型号或搜索同类设备。

验证方法

运行以下命令确认提取结果与固件内容一致:

./demo_fw < /dev/null | strings | grep "FW_VERSION"

若输出 FW_VERSION: 2.1.7-rc3,则说明 strings 提取结果准确。判定标准:strings_all.txt 中能检索到上述 6 条关键字符串,且与源码中定义的常量完全匹配。

常见问题

  • 字符串被压缩或加密:若固件经过压缩(如 LZMA)或加密,strings 无法直接提取,需先进行解压或解密处理。
  • UTF-16 编码字符串:部分嵌入式系统使用宽字符,可用 strings -e l 指定 16 位 little-endian 编码提取。
  • 误报过滤:二进制中大量短字符串(如寄存器名)会干扰分析,建议先用 -n 8 或更长阈值过滤,再逐步降低。
固件字符串提取与分析流程 固件二进制 strings -n 4 strings_all.txt 版本信息 FW_VERSION: 2.1.7-rc3 → 漏洞匹配 路径泄漏 /home/builder/... → 源码结构推测 AT 命令 AT+DEBUG=1 → UART 接口交互 默认配置 IoT_Home_2.4G → 设备型号识别 验证:grep 检索关键字符串 + 运行固件比对输出 通过条件:6 条关键字符串全部匹配