模拟固件系统
上面已经提到了两种固件模拟的方式,他们都做不到全模拟,只能在有限的情况下使用.当一些固件对运行环境非常苛刻,必须要全模拟固件时使用上面介绍的方案就会比较麻烦.这里介绍另一款工具firmadyne
,这是一个开源的模拟程序,项目地址是:https://github.com/firmadyne/firmadyne . firmadyne基于qemu,binwalk等开源工具的整合工具,可以真正做到全模拟固件.
0x1 配置firmadyne
firmadyne 的安装过程比较复杂,一共分为三4大步骤 这里做一个详细的介绍:
- 安装 qemu
- 安装 firmadyne 的依赖 binwalk
- 安装 firmadyne
- 配置 firmadyne 数据库
- 首先使用如下命令安装qemu
apt-get install qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utils
qemu-system-arm
,qemu-system-mips
分别代表模拟arm/mips
的支持- 如果有其他分支的需求直接按照类似的方式安装即可,
- 典型的分支:
qemu-system-ppc/qemu-system-s390x/qemu-system-sparc
- 接着安装binwalk
首先安装binwalk的一些python库
pip install git+https://github.com/ahupp/python-magic
pip install git+https://github.com/sviehb/jefferson
特别针对python2,需要安装额外的加密库
apt-get install python-lzma
最后安装主程序
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo ./deps.sh
python ./setup.py install
- 安装 firmadyne
首先安装相关的依赖
apt-get install busybox-static fakeroot git dmsetup kpartx netcat-openbsd nmap python-psycopg2 python3-psycopg2 snmp uml-utilities util-linux vlan
接着下载源码即可
git clone --recursive https://github.com/firmadyne/firmadyne.git
cd ./firmadyne
./download.sh
- firmadyne 是由python写的程序,不需要其他依赖
- 配置数据库
- firmadyne 是整合了大量第三方工具的开源集合
- 各个工具/插件之间需要大量的数据交互
- firmadyne 使用 postgres 数据库作为 数据的缓存中心
./firmadyne/database/schema
就是数据库的初始文件
使用下面的指令来创建数据库
# 安装数据库
sudo apt-get install postgresql
# 创建用户,注意要设置密码为 firmadyne
sudo -u postgres createuser -P firmadyne
# 创建数据库
sudo -u postgres createdb -O firmadyne firmware
# 初始化数据库
sudo -u postgres psql -d firmware < ./firmadyne/database/schema
- 约定:数据库的账号密码均为
firmadyne
0x2 firmadyne 模拟
- firmadyne处于兼容性的考虑,将模拟过程分成了好几个模块,并且每个模块的处理结果都会保存在数据库中.
- firmware对固件的自动分析可能会出错,这时候需要在数据库中修改对应的模块处理结果.
- firmadyne有一个项目的概念,每一个固件为一个独立的项目,并且名称只能是数字
从逻辑上划分,firmadyne的模拟分为以下6个过程.
- 解压固件
- 分析固件架构
- 采集固件信息
- 创建模拟镜像
- 识别固件网络配置
- 运行固件
本案例中使用 netgear
的路由器固件作为演示demo,可以使用下面这个指令下载
cd firmadyne
wget -N --continue \
http://www.downloads.netgear.com/files/GDC/WNAP320/WNAP320%20Firmware%20Version%202.0.3.zip \
-O firmware.bin
- 首先使用如下命令解压固件
python3 ./sources/extractor/extractor.py -b Netgear -sql 127.0.0.1 -np -nk "firmware.bin" images
- 解析固件
firmware.bin
创建项目 - 解压后目录
./images/
下会多出一个tar.gz
文件,文件名就是这个固件的id -b Netgear
指定固件类型为Netgear
,可以忽略-sql
指定数据库位置-np
禁止多线程解压-nk
不处理内核
- 接着分析固件架构
./scripts/getArch.sh ./images/1.tar.gz
- 自动分析
项目1
的运行架构 - 自动将结果保存到数据库
- 然后采集固件信息
./scripts/tar2db.py -i 1 -f ./images/1.tar.gz
- 指定目标为
固件1
- 自动创建固件的运行数据库
- 将固件的相关信息保存到数据库,主要是模拟固件时使用
- 紧跟着创建固件对应的二进制镜像
./scripts/makeImage.sh 1 [arch]
- 创建项目
1
所需的镜像文件 [arch]
是可选参数,用于覆盖数据库中的arch
记录
- 最后分析固件的网络接口情况
./scripts/inferNetwork.sh 1
- 自动判断项目
1
的网络结构 - 模拟出对应的网络接口
- 一切完成之后就可以启动对固件的模拟
./scratch/1/run.sh
- 根据已经获得的硬件信息来启动模拟程序
- 前面几个步骤采集到的信息最终都会在这个脚本中体现
- 可以通过修改这个脚本来覆盖前面几步中错误的自动判断结果
0x3 网络详解
上面已经提到了firmadyne是自动判断固件的网络.实际情况中固件的网络运行环境各种各样,firmadyne很难做到完全兼容,这时候就需要使用者自己去修改相关的网络配置.firmadyne最终是调用qemu来实现对固件的模拟,而关键参数就存存在于项目的run.sh
文件中.
下面这段代码是run.sh
中用于配置网络的代码,接下对对关键代码进行解读
TAPDEV_0=tap${IID}_0
HOSTNETDEV_0=${TAPDEV_0}
sudo tunctl -t ${TAPDEV_0} -u ${USER}
sudo ip link set ${HOSTNETDEV_0} up
sudo ip addr add 192.168.0.99/24 dev ${HOSTNETDEV_0}
sudo ip route add 192.168.0.100 via 192.168.0.100 dev ${HOSTNETDEV_0}
变量解读:
tap${IID}_0
指的是利用项目id生成该项目对应的虚拟tap/网卡.最终的名称类似于tap1_0/tap2_0
一般情况下,一个项目默认只会生成一个 tap/网卡
- 变量
HOSTNETDEV_0
以及TAPDEV_0
都是tap${IID}_0
的代称 - 变量
${USER}
指代当前用户,用于设置 虚拟tap/网卡 的owner
指令解析:
tunctl -t ${TAPDEV_0} -u ${USER}
- 首先创建一个名为
${TAPDEV_0}
的虚拟网卡,网卡的拥有着者为当前用户
sudo ip link set ${HOSTNETDEV_0} up
sudo ip addr add 192.168.0.99/24 dev ${HOSTNETDEV_0}
- 接着将虚拟出的网卡设置为 运行状态
- 然后设置虚拟网卡的IP地址为
192.168.0.99
,掩码为24
sudo ip route add 192.168.0.100 via 192.168.0.100 dev ${HOSTNETDEV_0}
- 最后设置路由表:通过虚拟网卡来访问 主机
192.168.0.100
- 主机
192.168.0.100
就是firmadyne探测到的固件的ip地址
总结:
- 以上就是firmadyne模拟固件网络的具体流程
- 这一切都建立在firmadyne检测出固件的ip地址.或者说固件本身 会去/可以 配置ip地址
- 根据实际情况是要按照规则修改
run.sh
中的参数即可 - 如果需要配置桥接网络,只要删除上面这些默认的规则,然后直接将
${HOSTNETDEV_0}
桥接到目标交换机上就可以了
One comment
针不戳