iot安全学习之IoT_Sec_Tutorial
最近在网上看到了IoT_Sec_Tutorial这个项目项目地址,拿过来学习一下,分5个点
- 提取iot固件
- 静态分析iot固件
- 动态分析iot固件
- 解密dlink固件
- 修复固件运行环境
iot入门可以看看《揭密家用路由器0day漏洞挖掘》这本书,笔者目前的iot安全学习阶段觉得难得并不是分析固件漏洞,而是对固件进行模拟和动态分析这一块,有些环境总是搭建失败(可能是菜吧XD)。笔者会将自己遇见的一些坑点写出来。在这里笔者可能会借用很多IoT_Sec_Tutorial这个项目的东西
IoT_Sec_Tutorial
提取 IOT 固件
首先在提取iot固件中需要的工具就是binwalk。在前面的路由器初探之D-LINK DIR-815多次溢出漏洞分析中笔者使用kali 2022.1提取非标准的Squashfs文件系统的时候会出现错误需要安装sasquatch
。然后在网上搜索之后发现可能是kali的版本太新了导致安装报错,所以笔者直接在vm上装了一个ubuntu18,然后再安装sasquatch包括后面的固件模拟都需要安装很多环境,所以有点麻烦。笔者继续往下做这些实验的时候发现了一个osAttify
。这个操作系统将iot的环境基本都装好了。所以笔者就下载了,并且安装使用,只能说一句真***好用。
因为是国外的网盘下载链接,所以可能下的有点慢,这里笔者将这个os放到了百度网盘里,链接: https://pan.baidu.com/s/1eVVDXKVpH9ox_ein9pkchA 提取码: gprv 。ova直接使用虚拟机打开就可以了,界面如下图
有了上面这个os,接下来就很方便操作了,对这个固件RT-N300_3.0.0.4_378_9317-g2f672ff.trx进行提取
可以加上-t -vv参数查看详细的提取过程。通过输出信息,可以得知该固件系统没有加密压缩,好了之后就可以看到squashfs-root这个文件夹了。得到的squashfs-root就是固件系统
静态分析iot固件
接下来拿的是一个zip方式的固件,我们需要对它进行解压,在解压的时候发现有压缩包密码
使用frackzip工具可以破解该zip的密码,时间太长了,所以直接看这个项目里告诉的密码。最后的密码是beUT9Z
,有一个坑点unzip不能完整的解压需要使用7z
进入目录可以看到有很多的yaffs2文件和mbn文件。
YAFFS(Yet Another Flash File System)是由Aleph One公司所发展出来的NAND flash 嵌入式文件系统。
mbn:高通的一套用于加载网络环境的文件
核心的应该是2K-mdm-image-mdm9625.yaffs2。可以使用unyaffs来进行提取
unyaffs 2K-mdm-image-mdm9625.yaffs2 yaffs2-root/
出了这个错的话就是没有sudo了,但是对于静态分析来说影响不大,提取之后就可以看到文件系统了
接下来我们查找该路径下的所有.conf文件,.conf文件多是配置文件,有可能从中可以发现敏感的信息。
其中的inadyn-mt.conf文件引起了我们注意,这是no-ip应用的配置文件,no-ip就是一个相当于花生壳的东西,可以申请动态域名。我们从中可以发现泄露的no-ip的登陆账号及密码。同时在etc/shadow中发现了root的的密码
用john破解之后发现root的密码是1234。
为了发现更多价值的信息,我们可以使用firmwalker工具来自动化遍历该固件系统中的所有可疑文件
git clone https://github.com/craigz28/firmwalker.git
使用./firmwalker.sh ../IoT_Sec_Tutorial/02/DWR-932_B1_FW_v.02.02EU/yaffs2-root
之后会自动生成firmwalker.txt并将结果存入。
分析完敏感的配置文件后,我们接下来分析存在风险的二进制程序。查看自启动的程序,在etc/init.d中一个start_appmgr脚本引起了我们注意,mgr一般就是主控程序的意思。
看一下这个程序吧,发现该脚本会在开机的时候以服务的形式运行/bin/appmgr程序。
我们接下来对这个程序进行逆向分析,理解这个程序到底会做些什么 。在“/bin/appmgr”中,有一个线程会持续监听0.0.0.0:39889(UDP),并等待传入控制命令。
当传入HELODBG的时候会给一个shell。所以poc可以这样构造
1 | echo -ne "HELODBG" | nc -u 192.168.1.1 39889 |
这里先放一放了,后面的话会专门写一个DWR-932_B1_FW_v.02.02EU
漏洞分析
动态分析IoT固件
在这里我们采用的是DVRF这个固件,在这里我们先进行固件模拟,什么是固件模拟呢,其实就是让这个固件模拟一个真实的路由器有web服务器和telent这些功能。
前面说了attify,我们在attify里面进行固件模拟。将这个固件放到attiry中并运行下面的命令(后面的参数是固件的位置
注意:这里有两个固件,一个是DVRF_v03.bin还有一个是DWP2360b-firmware-v206-rc018.bin。模拟运行的是DWP2360b-firmware-v206-rc018.bin,因为DVRF_v03.bin笔者模拟运行一下发现network interfaces是空的,然后就用了这个项目给的DWP2360b-firmware-v206-rc018.bin来进行模拟。
运行这个命令就可以对dwp进行固件模拟./fat.py ~/IoT_Sec_Tutorial/o3/DWP2360b-firmware-v206-rc018.bin
红色框子里面就是路由器web端的入口。接下来按一下回车就可以模拟一个真实的路由器了。
这个时候就可以使用attify自带的firefox来访问一下这个地址,可以看到启动成功。DVRF这个固件是一个自制的充满漏洞的固件,供学习用的。接下来就是进行动态分析,在动态分析之前需要做的是binwalk -e 固件
跟进文件系统,pwnable这个文件夹存放着有漏洞的程序示例。
我们选取缓冲区漏洞程序stack_bof_01进行实验。首先使用file命令查看该程序的架构。
可以看到是MIPS32
保护方面的话基本什么都没开,想怎么溢出就怎么溢出,启动这个程序看一下是什么,需要将qemu-mipsel放到本目录下不然会出现一些找不到文件或目录这种错误
放到ghidra中看一下这个程序是什么样子的。
一个栈溢出,在第16行这里,当argv[1]超过austack206的空间时就会溢出。这个程序还给了一个后门,利用思路很简单,ret2text
我们需要先确定偏移是多少,这里采取动态调试。
接着我们需要输入数据,笔者用的是patternoffest.py至于为什么会用这个是因为笔者的gdb-multiarch里面的测试偏移的命令没反应
1 | # coding:utf-8 |
使用这个创建200个垃圾数据
1 | Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9 |
然后重新带这200个垃圾数据重新动态调试
在pwndbg里面运行c让这个程序跑起来
发现了返回地址被覆盖了,再次使用patternoffest.py这个脚本测试出偏移
offest = 204
,利用ret2text将返回地址覆盖成shell即可。
这里需要用0x5c的地址才能利用成功,原因看图
为了让shell正常运行所以我们肯定不能有gp从0x5c之里开始就可以顺利进行
成功利用
解密dlink固件
本次要研究的是路由器Dlink-882的固件
ftp://ftp2.dlink.com/PRODUCTS/DIR-882/REVA/,其中的zip文件就是各版本的固件。
然后笔者访问之后是这样的,直接打开了一个文件夹然后里面就是822的一些文件
将FW100B07、FW101B02、FW104B02、FW110B02、FW111B01、FW120B06、FW130B10
下载下来,然后解压并使用binwalk对其进行检测
检测发现100b07, 101b02, 104b02这些是没有加密的
FW110B02、FW111B01、FW120B06、FW130B10均是加密的
那么我们可以确定104B02是中间版本。固件版本迭代的过程经历了固件未加密到固件加密,说明中间肯定有个中间版本(类似下图),下图是固件从未加密到加密的升级原理图。
所以我们接下来需要从104b02这个版本中找到解密程序,先进行固件解包,笔者这次没有使用binwalk来解包,换了一个方式,使用了一个在线的网站iot在线解包 。
好了之后到达结果页面
在bin或者usr/bin中找到decrypt的相关程序,bin目录下就找到了
我们可以对这个加密程序进行一些逆向分析,分析出用的是什么加密算法。这里就不演示了,我们可以想个另一种方法,是不是可以使用这个程序直接对后面加密版本的固件进行解密呢?
nice,成功解密。
修复固件运行环境
之前我们学习了如何模拟运行IoT固件,但是,现实中并不是所有固件都能模拟运行成功,比如固件运行可能依赖于硬件,qemu无法完全模拟,所以,本节我们就来学习如何修复固件的运行环境,从而成功模拟固件运行。
我们本次使用的固件是D-Link的DIR-605L FW_113固件,附件可以去这个项目中下载
拿到固件后我们先放到fat里面看一下可不可以正常模拟
Interfaces那里为空,说明模拟运行失败了。不是所有固件都能用firmadyne模拟的,尤其是那些需要与硬件设备交互的固件
模拟固件运行的实质其实就是把固件的Web程序跑起来,而模拟失败则说明Web程序运行出错了,我们接下来就要针对看看Web程序报错的原因以及如何修复运行环境,我们提取固件的文件系统,提取出来的路径为squashfs-root-0
我们可以使用find ./ -name boa命令来定位该固件的Web程序。Boa程序是一个轻量级的web服务器程序,常见于嵌入式系统中。dlink就是在boa开源代码的基础上新增了很多功能接口以实现路由器上的不同功能。boa程序的路径为/bin/boa,同时我们发现在/etc/boa路径下还有个boa的密码配置文件,我们可以直接获取到boa加密后的密码。
我们模拟运行程序,会发现报错了,提示初始化MIB错误。
使用ghidra对boa程序进行逆向分析,我们快速的定位到错误的地方
跟进跟进
apmib_init这个函数是从flash中读取mib值到RAM中,模拟环境没有flash硬件,所以应该会读取失败。apmib_init读取数据失败返回0,赋值给$v0,然后bnez命令对$v0进行检测,若为0,则回显初始化失败,报错退出。
BENZ R1,NAME;//R1不等于0,程序跳转,以NAME为偏移地址
BEQZ R1,NAME;//R1=0,程序跳转到,以NAME为偏移地址
所以我们可以将bnez(0x14)命令改成beqz(0x10)
在想要patch的语句中按下ctrl + shift + G
保存程序具体的操作可以看https://materials.rangeforce.com/tutorial/2020/04/12/Patching-Binaries/
修补完成之后再次运行这个程序会发现这个程序还是有错误。。。。。创建东西错了,还有一个内存报错
没办法,继续跟进看一下
找到了报错的地点,open函数导致,但内存错误这里可以动态调试看哪个内存错了,先看函数由返回值引起的,所以看一下这个函数的引用
websaspinit中引用了它,而且刚刚的错误也是这个地方错了,所以我们跟进
前2个“Create chklist file error!”来自于create_chklist_file和create_devInfo_file函数,后面那个内存崩溃是apmib_get函数导致的。
动态调试一下看看。
在调试结束creat后,虽然报了创建错误的错但是还能往下运行,结果运行到apmib_get这里的时候就出错了
可以看到0x1001是个错误的地址。从第一个错误可以猜到websaspinit函数的功能是从RAM读取MIB值,所以有可能又是硬件依赖导致的错误。
我们可以将apmib_get里的跳转给nop掉,因为我们模拟固件,所以肯定没有硬件,这里对我们来说无用。
保存程序退出然后启动运行。ohhhhhhhhhhh
成功了,可以看到80端口已经跑起来了
访问一下。。。。。还有错的,继续看吧,看一下这个asp代码
vim web/Basic/Wizard_Easy_LangSelect.asp
通过文件名可以猜测功能是选择页面语言,而它尝试从硬件设备读取语言,显然又会出错了。
那我们就想办法不让它进入这个页面,查看入口网页,发现逻辑是先判断系统语言,成功则直接进入Webcome界面。那我们将失败和成功都进入welcome页面。
改完再次访问,ohhhhhhhhhhhh,成功。
总结
这几天一有空就在学习这个项目,总算是完成了(很开心),学习之后觉得这个项目对iot新手极其友好,真的是学到了很多东西,从提取iot固件到修复固件运行环境都讲得特清楚。iot安全之路还长继续加油。
Reference
https://github.com/G4rb3n/IoT_Sec_Tutorial
https://www.anquanke.com/post/id/245945#h2-14
https://materials.rangeforce.com/tutorial/2020/04/12/Patching-Binaries/