利用QEMU模拟树莓派环境实现IoT固件动态分析与调试

张开发
2026/4/20 19:57:42 15 分钟阅读

分享文章

利用QEMU模拟树莓派环境实现IoT固件动态分析与调试
1. 为什么需要QEMU模拟树莓派环境搞IoT安全研究的朋友们应该都深有体会真机调试简直就是一场噩梦。去年我分析某款智能摄像头固件时光是买设备就花了2000多结果刷固件时不小心变砖了那个心疼啊。后来发现用QEMU模拟树莓派环境不仅省钱省事还能实现真机难以做到的动态分析。QEMU这个开源模拟器最厉害的地方在于它能完整模拟ARM架构的CPU、内存、外设等硬件环境。我实测下来树莓派3B的模拟完整度能达到90%以上包括GPIO、USB这些关键外设都能正常工作。对于固件分析来说最大的优势是可以随时暂停、快照和内存dump这在真机上根本做不到。2. 环境搭建全流程详解2.1 镜像获取与处理官方镜像raspios-bullseye-armhf-lite.img大概只有400MB左右比桌面版小巧很多。我习惯用wget直接下载wget https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-lite.img.xz unxz 2023-05-03-raspios-bullseye-armhf-lite.img.xz挂载镜像提取内核文件有个坑要注意新版镜像用了ext4文件系统老教程里用的kpartx可能报错。我现在的标准操作流程是sudo losetup -Pf --show 2023-05-03-raspios-bullseye-armhf-lite.img # 假设输出/dev/loop0 sudo mount /dev/loop0p1 /mnt cp /mnt/kernel8.img /mnt/*.dtb . sudo umount /mnt sudo losetup -d /dev/loop02.2 QEMU启动参数详解这个启动命令我优化过十几次现在这个版本最稳定qemu-system-aarch64 \ -M raspi3b \ -kernel kernel8.img \ -dtb bcm2710-rpi-3-b-plus.dtb \ -drive file2023-05-03-raspios-bullseye-armhf-lite.img,formatraw \ -append consolettyAMA0 root/dev/mmcblk0p2 rw \ -m 1G -smp 4 \ -serial stdio \ -net nic -net user,hostfwdtcp::5022-:22重点说下网络配置hostfwdtcp::5022-:22这个参数特别实用它把宿主机的5022端口映射到虚拟机的22端口。这样启动后可以直接ssh连接ssh -p 5022 pilocalhost3. 固件动态分析实战技巧3.1 内存监控与行为分析我最常用的组合是qemugdbstrace。比如要监控某个IoT服务的系统调用# 在QEMU中启动服务时加上strace strace -f -o /tmp/service.log ./iot_service # 同时在宿主机用gdb附加进程 gdb-multiarch -ex target remote :1234 -ex continue最近发现个更好用的工具——qemu内置的tcg插件。在启动命令加上-plugin ./contrib/plugins/libhotblocks.so能实时统计代码块执行频率对逆向分析帮助很大。3.2 漏洞挖掘实战案例去年分析某路由器固件时发现它的UPnP服务存在栈溢出漏洞。用QEMU环境复现的步骤很典型用binwalk解包固件binwalk -Me firmware.bin找到目标程序后先静态分析file squashfs-root/usr/bin/upnpd checksec --filesquashfs-root/usr/bin/upnpd在QEMU中运行并触发漏洞sudo chroot squashfs-root /usr/bin/upnpd # 另开终端发送恶意数据包 python3 exploit.py用gdb观察崩溃点gdb-multiarch -ex set architecture arm \ -ex target remote :1234 \ -ex b *0x123456 \ -ex continue4. 高级调试技巧与性能优化4.1 GDB调试增强方案原生的gdb用起来太痛苦我强烈推荐搭配gef插件wget -q -O ~/.gdbinit-gef.py https://github.com/hugsy/gef/raw/master/gef.py echo source ~/.gdbinit-gef.py ~/.gdbinit调试时几个常用命令heap bins查看堆内存状态telescope $sp 20查看栈空间pattern create 200生成测试数据4.2 性能优化方案QEMU跑ARM程序确实慢我总结了几条提速技巧启用KVM加速需要CPU支持-enable-kvm -cpu host使用TCG缓存-tb-size 256 -icount 6关闭图形界面-nographic -serial mon:stdio实测下来优化后执行速度能提升3-5倍。对于大型固件建议分配更多内存-m 4G -smp 85. 常见问题解决方案5.1 网络连接问题遇到ping不通的情况先检查QEMU的网卡配置-netdev user,idnet0,net192.168.100.0/24 -device virtio-net-device,netdevnet0如果还是不行可能是固件自带的网络配置冲突。解决方法是在启动时覆盖网络配置-append ip192.168.100.2::192.168.100.1:255.255.255.05.2 外设模拟问题模拟GPIO设备需要特别处理-device gpio-key,gpiosgpio0:0然后在系统中加载对应的内核模块modprobe gpio-keys遇到USB设备识别问题可以尝试强制指定设备类型-device usb-host,vendorid0x1234,productid0x56786. 实战经验分享去年用这套方法成功挖到三个CVE。最典型的一个案例是某智能门锁固件它的蓝牙协议栈存在认证绕过漏洞。在QEMU环境中我通过内存断点定位到关键校验函数b *0x12345678 if $r00xdeadbeef commands print *(char**)($r14) continue end另一个实用技巧是用QEMU的trace功能记录系统调用-trace events./events.txt这个events文件里定义了要监控的系统调用分析起来比strace更高效。

更多文章