简介

这里 IOT 环境主要是指路由器的分析环境,当然摄像头之类的设备也是能够进行分析的。

下面配置是基于 ubuntu18.04 进行配置。

Binwalk

apt-get install 的 binwalk 是残缺版本,解析某些压缩固件时识别不了。因此选择到 github 仓库安装完整版本:

https://github.com/ReFirmLabs/binwalk/

apt 装的差点解释器,对于 ubuntu\debian 有提供一键脚本,安装的内容查阅官方文档。py2 和 py3 都支持,py3 速度快点就装它了,手动安装方法看前面官方文档。

1
2
3
4
5
6
git clone --depth 1 https://github.com/ReFirmLabs/binwalk.git
cd binwalk
# 安装binwalk
sudo python3 setup.py install
# 安装拓展
sudo ./deps.sh

其中 cramfsprogs 无法 apt 安装,要手动装下:

参考师傅文章:https://blog.csdn.net/wuyou1995/article/details/106215540/

1
2
wget http://launchpadlibrarian.net/251826685/cramfsprogs_1.1-6ubuntu1_amd64.deb
sudo dpkg -i cramfsprogs_1.1-6ubuntu1_amd64.deb

使用指令

按照预定的配置文件中提取方法从固件中提取探测到的文件及系统:

1
binwalk -e filename.bin

根据 magic 签名扫描结果进行递归提取:

1
binwalk -Me filename.bin

限制递归提取深度,默认深度 8 :

1
binwalk -Me -d 5 filename.bin

mips 交叉编译环境

这个目前来说主要是用在 hook 某些函数让整个固件系统或单个程序能正常运行,或者是制作后门时用到。这个编译环境两种安装方法:buildroot 或者是 apt 直接安装编译好的版本。

buildroot

这种方法所网络环境约束极大,主要是那个内核文件资源在国外,挂着代理也下载很慢。也尝试过通过下载软件把内核文件下载下来,放到对应文件夹进行 make ,它还是会重新下载。最后去冬令营的时候,蹭 hw 的网就能下载到,虽然还是很慢,但起码能下完。

参考师傅文章

1
2
3
4
5
6
7
8
9
10
11
12
# 安装依赖库
sudo apt-get update
sudo apt-get install libncurs*
sudo apt-get install libncurses5-dev patch

# 下载源码
git clone https://github.com/buildroot/buildroot.git

# 进行编译的配置
cd buildroot
make clean
make menuconfig

下面进入到 gui 配置窗口,需要修改三个属性(由于版本位置可能不同):

  • Target OptionTarget Architecture 修改为 MIPS(little endian)

    image-20210206212735360

  • Target OptionTarget Architecture Variant 修改为 Generic MIPS32

    image-20210206212756857

  • ToolchainKernel Headers 修改为小于等于主机内核的版本(查询指令:uname -r),我本地为 4.15.0 ,那就选 4.14.x

    image-20210206213129568

保存配置后退出

image-20210206213247200

进行编译,最好设置代理编译过程会下载国外资源,保持网络通畅:

1
sudo make

编译完成后在 output/host/bin 文件夹就能看到文件了,图中文件夹是我自己改了名字而已:

image-20210318173306250

将 output 文件夹改名字,然后重复上面步骤,安装 mipsel 交叉编译链。

apt install

apt 直接安装编译好的版本,免去下载内核资源编译的问题。这种方法也同样使用安装 arm 等交叉编译链。

参考文章:https://blog.csdn.net/wfxzf/article/details/88974144

mips(大端序)

1
2
sudo apt-get install emdebian-archive-keyring
sudo apt-get install linux-libc-dev-mips-cross libc6-mips-cross libc6-dev-mips-cross binutils-mips-linux-gnu gcc-mips-linux-gnu g++-mips-linux-gnu

image-20210206235709724

image-20210207010045821

mipsel(小端序)

1
2
sudo apt-get install emdebian-archive-keyring
sudo apt-get install linux-libc-dev-mipsel-cross libc6-mipsel-cross libc6-dev-mipsel-cross binutils-mipsel-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu

image-20210207115930839

qemu 虚拟机桥接网络

这里是给下面 mips 虚拟机打下网络基础的,至于这个 mips 虚拟机作用后面说。qemu apt 装个静态版本就即可。

我们这步做的是在 ubuntu 虚拟机里面配置一个网桥 br0 ,一端链接宿主机分配,另一端链接 qemu 虚拟机。

1
2
3
4
5
6
# 安装网桥依赖
sudo apt-get install bridge-utils uml-utilities
# 备份原来配置文件
sudo cp /etc/network/interfaces /etc/network/interface.bak
# 编译配置文件
sudo vim /etc/network/interfaces

将文件内修改为如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto ens33
iface ens33 inet manual
up ifconfig ens33 0.0.0.0 up

auto br0
iface br0 inet dhcp
bridge_ports ens33
bridge_stp off
bridge_maxwait 0

上面文件中的 ens33 可能需要根据自己系统网卡修改一下,我系统上没有 eht0 这个网卡,当填写网卡名是 eht0 ,等下重启失败,修改为 ens33 则成功。

image-20210207140952068

配置完成后,br0 获取宿主机分配的 ip :

在其他文章中接下来会配置 qemu 的网络启动脚本,用下来这脚本有点问题,还是手动配置比较香。

mips 虚拟机

mips 虚拟机主要是用来给固件一个运行的 linux 环境,后面仿真固件就是将固件放入到里面运行。

虚拟机需要下载内核文件、磁盘镜像,下载地址:

1
https://people.debian.org/~aurel32/qemu/mips/

大小端根据固件版本自行调整

配置网络

网桥

ifconfig 没有查看到 br0 网桥可以手动启动一下:

1
2
sudo brctl addbr br0
sudo ifconfig br0 192.168.211.7/24 up
  • Br0:网卡名
  • 192.168.211.7:宿主机(vmware)分配的 ip 段,只有不冲突即可

配置成功

网卡接口

1
2
3
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.211.50/24 up
sudo brctl addif br0 tap0
  • Tap0:网卡名称,后面 qemu 启动指定用这个网卡
  • 192.168.211.50:同前一步
  • brctl addif:网卡链接网桥

配置成功

启动虚拟机

1
sudo qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -netdev tap,id=tapnet,ifname=tap0,script=no -device rtl8139,netdev=tapnet -nographic
  • -kernel:指定内核版本
  • -hda:指定磁盘镜像
  • -netdev tap,id=tapnet,ifname=tap0:指定 qemu 网络模式

登录密码账号均为:root,在 qemu 虚拟机中给网卡配置 ip :

1
ifconfig eth0 192.168.211.51/24 up

image-20210318194120389

从 qemu 虚拟机 ping 主机:

![image-20210318194302315](../../../../Library/Application Support/typora-user-images/image-20210318194302315.png)

从主机 ping qemu 虚拟机:

image-20210318194340488

传输固件

1
scp -r squashfs-root/ [email protected]:~/

怎么启动固件系统,每个固件各有差异,结合实际分析。

IDA & plugin

mips 反编译可以用 ghidra 或者 IDA7.5 ,下载去看雪、吾爱逛逛

ida 装两个插件方便审查和查询 gadget ,安装方法看官方 wiki

mipsAudit

采用 t3ls 修改版本:mipsAudit

mipsrop

https://github.com/tacnetsol/ida/tree/master/plugins/mipsrop

调试工具

个人首选 gdb-multiarch ,偶尔会遇到 gdb 版本差异或者奇异原因而无法调试,然后用 ida 远程调试代替。

IDA 远程调试(带符号表)

这里调试时是用 qemu-user 模式用 -g 打开调试端口,确保被调试程序能正常运行,如果不能需要 hook 或者 peach 某些函数。

将需要调试文件拖到主机上,用 ida 打开程序,然后到 ubuntu -g 打开调试端口。ida 选 remote gdb :

image-20210207191440733

前两项都是自动识别文件在 mac 地址,最后一个就 ubuntu 调试端口:

截图是没有打开调试端口,提示连不上

image-20210207191516981

DIR-645 远程代码执行

先拿一个 web 洞复现练手,不用写 mips shellcode 。漏洞存在于 /htdocs/cgibin 二进制文件中,原因是 service.cgi 中未经过滤就将用户输入拼接到命令中。

复现环境

直接运行如下:

image-20210209215850264

漏洞分析

strrchr 匹配出 / 后面的参数后,strcmp 匹配参数进入各个服务函数:

image-20210209215637987

定位到 servicecgi_maingetenv 提取参数依据两种请求方式分别给 v2 赋值,不匹配或为空则退出;提取请求方式后,将参数传入 cgibin_parse_request 解析 http 请求:

image-20210209220241088

到里面分别提取REQUEST_URICONTENT_TYPECONTENT_LENGTH

image-20210209221145009

image-20210209221145009

当解析无误后返回上层函数,然后进入权限认证:

image-20210209221306768

在这个认证函数内部的函数 sess_get_uid ,可以看到是从 HTTP_COOKIE 里面获取 uid 判断:

image-20210209221716723

进入 sub_40A950 将 URL ? 后面部分与关键词匹配,如果一致就开始准备进入拼接命令字符串:

image-20210209222749033

lxmldbc_system 里面将预制指令和 URL 里面参数进行拼接:

image-20210209222937398

Event 命令字符串为:"event %s > /dev/null" ,中间我们可以加上任意指令比如:"event &ls& > /dev/null"

开始测试前,权限认证那里由于少文件等,要将那个函数 patch 改一下。把跳转 session 改掉不然会卡一段时间,因为仿真没有 /var/session 文件;v1 的复制改为 1 就是代表有权限:

image-20210209232026784

image-20210209231657216

测试一下,启动命令:

-0:传入第一个参数,进入 servicecgi_main

-E:选项传入自定义的环境变量

-strace:显示具体信息

1
2
3
4
5
6
7
8
sudo chroot . ./qemu-mipsel \
-0 "service.cgi" \
-E REQUEST_METHOD="POST" \
-E CONTENT_LENGTH=10 \
-E REQUEST_URI="service.cgi?EVENT=%26ls%26" \
-E CONTENT_TYPE="application/x-www-form-urlencoded" \
-E HTTP_COOKIE="uid=skye231" \
./htdocs/cgibin

启动后,报错解析不了:

image-20210209230233246

加上调试解析函数看都是解析正确,单步调试就发现是成功解析后执行 retrun 函数并没有返回到上一层,而是继续往下执行 95 行的 retrun v9 这是的 v9 为 -1 :

image-20210209231306395

cataLpa 师傅复现文章也出现相同情况,推测可能是 qemu 仿真问题。这里可以直接改寄存器或者 patch 一下。

再次启动,这次就正常回显,但是没有运行附加进去的指令:

image-20210209232205679

附加上 -strace 查看一下详细信息:

1
2
3
4
5
6
7
8
sudo chroot . ./qemu-mipsel -g 1234 -strace \
-0 "service.cgi" \
-E REQUEST_METHOD="POST" \
-E CONTENT_LENGTH=10 \
-E REQUEST_URI="service.cgi?EVENT=%26ls%26" \
-E CONTENT_TYPE="application/x-www-form-urlencoded" \
-E HTTP_COOKIE="uid=skye231" \
./htdocs/cgibin

image-20210209233118432

指令已经附加上去,应该是 qemu 环境问题运行不了。

参考文章

https://wzt.ac.cn/2019/09/05/CNVD-2018-01084/