1. 固件镜像信息收集与识别
任务目标
给定一个路由器固件镜像文件,通过binwalk提取文件系统,识别目标架构、内核版本及关键组件(如Web服务、telnetd、dropbear等),为后续漏洞分析建立基础信息档案。
环境与依赖
- 操作系统:Ubuntu 22.04 LTS(或任意Linux发行版)
- 工具:
binwalk、file、strings、readelf(或objdump) - 安装命令:
sudo apt install binwalk file binutils
固件获取与准备
本案例使用公开的D-Link DIR-859路由器固件作为分析对象(固件版本1.03,可从D-Link官方支持页面下载)。下载后得到文件DIR859Ax_FW103b02.bin,存放于工作目录~/firmware_analysis/下。
关键完整代码(Shell脚本)
以下脚本完成固件信息收集、文件系统提取与关键组件识别的完整流程:
#!/bin/bash
# firmware_info_gather.sh - 固件镜像信息收集与识别
# 用法: ./firmware_info_gather.sh <固件文件路径>
set -e
FIRMWARE="$1"
OUTDIR="firmware_extracted"
BASENAME=$(basename "$FIRMWARE")
if [ -z "$FIRMWARE" ]; then
echo "用法: $0 <固件文件路径>"
exit 1
fi
echo "[*] 固件文件基本信息"
file "$FIRMWARE"
echo -e "\n[*] 固件头部/结构扫描"
binwalk "$FIRMWARE" | head -30
echo -e "\n[*] 提取文件系统"
rm -rf "$OUTDIR"
mkdir -p "$OUTDIR"
binwalk -e -M -C "$OUTDIR" "$FIRMWARE" > /dev/null 2>&1
# 定位squashfs根目录
ROOTFS=$(find "$OUTDIR" -type d -name "squashfs-root" | head -1)
if [ -z "$ROOTFS" ]; then
ROOTFS=$(find "$OUTDIR" -type d -name "*root*" | head -1)
fi
if [ -z "$ROOTFS" ]; then
echo "[!] 未找到文件系统根目录,尝试手动定位"
ls -la "$OUTDIR"
exit 1
fi
echo "[*] 文件系统根目录: $ROOTFS"
echo -e "\n[*] 架构识别"
# 从busybox或任意ELF文件识别架构
BUSYBOX=$(find "$ROOTFS" -name "busybox" -type f | head -1)
if [ -n "$BUSYBOX" ]; then
file "$BUSYBOX"
readelf -h "$BUSYBOX" 2>/dev/null | grep -E "Class|Machine|Entry"
else
# 尝试从任意ELF文件识别
ELF_FILE=$(find "$ROOTFS" -type f -exec file {} \; | grep "ELF" | head -1 | cut -d: -f1)
if [ -n "$ELF_FILE" ]; then
file "$ELF_FILE"
readelf -h "$ELF_FILE" 2>/dev/null | grep -E "Class|Machine|Entry"
fi
fi
echo -e "\n[*] 内核版本识别"
# 从内核字符串或版本文件中提取
KERNEL_STR=$(strings "$FIRMWARE" | grep -E "^Linux version [0-9]" | head -1)
if [ -n "$KERNEL_STR" ]; then
echo "$KERNEL_STR"
else
# 尝试从文件系统中的内核模块或proc/config中获取
KVER_FILE=$(find "$ROOTFS" -path "*/proc/version" -o -name "config-*" 2>/dev/null | head -1)
if [ -n "$KVER_FILE" ]; then
cat "$KVER_FILE" | head -5
else
# 从文件系统中的字符串提取
strings "$ROOTFS/bin/*" 2>/dev/null | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | sort -u | head -5
fi
fi
echo -e "\n[*] 关键组件识别"
echo "--- 网络服务 ---"
ls "$ROOTFS/etc/init.d/" 2>/dev/null | head -20
find "$ROOTFS" -name "*httpd*" -o -name "*lighttpd*" -o -name "*nginx*" 2>/dev/null | head -5
find "$ROOTFS" -name "telnetd" -o -name "dropbear" -o -name "sshd" 2>/dev/null | head -5
echo -e "\n--- Web目录 ---"
ls "$ROOTFS/www" 2>/dev/null | head -20 || echo "无/www目录"
find "$ROOTFS" -type d -name "*web*" 2>/dev/null | head -5
echo -e "\n--- 关键二进制 ---"
find "$ROOTFS" -name "busybox" -o -name "nvram" -o -name "iptables" 2>/dev/null | head -10
echo -e "\n[*] 信息收集完成"
echo "文件系统位置: $ROOTFS"
echo "可执行文件总数: $(find "$ROOTFS" -type f -executable | wc -l)"
运行方式
cd ~/firmware_analysis
chmod +x firmware_info_gather.sh
./firmware_info_gather.sh DIR859Ax_FW103b02.bin
验证方法与判定标准
脚本执行后,按以下标准验证结果是否完整:
- 文件系统提取成功:输出中存在
squashfs-root目录,且该目录下包含/bin、/etc、/usr等标准Linux目录结构; - 架构识别明确:readelf输出显示
Class: ELF32或ELF64,Machine: MIPS或ARM(DIR-859为MIPS架构,预期显示MIPS R3000或类似); - 内核版本获取:输出包含形如
Linux version 2.6.36或3.10.x的版本字符串; - 关键组件可见:输出中列出至少一个Web服务器(如
httpd)、远程管理服务(telnetd或dropbear)以及busybox的位置。
若以上四项均满足,则说明固件信息收集与识别成功,可进入后续漏洞分析阶段。
常见问题
- binwalk提取失败:尝试
binwalk --dd='.*'强制提取,或使用jefferson(针对JFFS2)等专用工具; - 架构识别为空:若文件系统中无busybox,可手动查找任意ELF文件执行
readelf -h; - 内核版本无法从镜像直接获取:可解压内核镜像(通常为
vmlinuz或kernel分区)后使用strings配合grep搜索版本字符串。