0x10 物联网设备模糊测试

对于物联网设备,比如家用路由器模块,UPNP、HTTP server、Telnet都是用户经常接触的模块,通常也能够与外界交互,从而提供了入口。如果这些模块或者使用的协议存在漏洞,往往能够直接利用,达到远程攻击的效果。

IoT 固件分析往往涉及到二进制代码审计、静态扫描以及动态调试等,其中模糊测试作为一种重要的方法,能够给安全测试添砖加瓦。针对IoT设备的模糊测试主要有两类

  • 固件的二进制Fuzz测试,如AFL
  • 物联网协议Fuzz测试,如Peach、Sulley

本次重点介绍Sulley的衍生项目——boofuzz的使用。对物联网设备的协议fuzz测试,不可丢失的一环是监控器,能够发现bug是监控器的作用所在。一般来说,大多数针对协议的fuzz测试,在每次发送变异报文后,通过ping或者其他协议监测对方是否在线从而判断设备是否出现异常。这种方法较为简单,但是粗粒度的监视器带来的后果是较高的误报率;另一种方式是ssh或者telnet登录目标设备,实时观察当前设备的状态,这种方式优点是随时捕捉异常信号,缺点是,针对不同设备可能要开发不同的监控API。所以当前诸多的协议Fuzz工具,大部分使用第一种,即通过目标设备是否可达来判断崩溃情况。

0x20 boofuzz 框架介绍

0x21 从Sulley说起

项目地址:https://github.com/Bit9/sulley。该项目基于Python2.7,也就是说,如果你要安装此工具,需要该Python环境的支持。

sulley 是一款模糊测试框架,可以使用 sulley 进行协议Fuzzing。Sulley(以作者的观点来看)所具有的能力超过了以前所发布的大多数模糊测试技术,包括商业工具和那些在公开领域中可用的工具。该框架的目标是不仅要简化数据的表示,而且还要简化数据的传输以及对目标的监视。Sulley从Monsters,Inc创建之后就被亲切的命名 ,因为它是模糊化的工具。现在sulley 已经停止更新,不再维护。1

大多数情况下,现代模糊器只专注于数据生成。Sulley不仅具有令人印象深刻的数据生成能力,而且还朝着更进一步的方向迈进了一步,其中还包括现代模糊器应提供的许多其他重要方面。Sulley监视网络并有条不紊地维护记录。Sulley可以检测和监视目标的运行状况,并可以使用多种方法将其恢复到已知的良好状态。Sulley对检测到的故障进行检测,跟踪和分类。Sulley可以并行进行测试,从而显着提高测试速度。Sulley可以自动确定哪些独特的测试用例序列会触发故障。Sulley可以自动完成所有这些工作。

图 Sulley框架 2

上图是Sulley的整体框架图,来源于BlackHat。Sulley主要包括四大组件

  1. Data Generation 数据生成
  2. Session 会话管理
  3. Agents 代理
  4. Utilities 独立单元工具

其中,数据生成和会话管理是比较重要的两个模块。Sulley数据生成方式是基于generation-based的方式,需要对协议或者文件进行建模。数据生成的特点3

  • 一个数据报文由基元(Primitives)、块(Blocks组成)
  • 多个基元可以组成块,块可以相互嵌套
  • 在基元的基础上我们可以创建自定义的特殊的复杂基元(Legos,数据积木,暂且这么翻译吧),例如Email的地址,IP地址等。
  • 最后还有一些有用的工具,例如算length长度、校验和、加密模块等

会话模块,根据已经构建好的Request,利用 Pgraph 绘制, Pgraph 可以创建、修改和渲染图

图 Session2

在上图中,节点ehlo、helo、mail from、rcpt to、data表示5个请求,路径’ehlo’->‘mail form’->‘rcpt to’->‘data’和’helo’->‘mail from’->‘rcpt to’->data’体现了请求之间的先后顺序关系。callback_one()和callback_two()表示回调函数,当从节点echo移动到节点mail from时会触发该回调函数,利用这一机制,节点mail from可以获取节点ehlo中的一些信息。而pre_send()和post_send()则负责测试前的一些预处理工作和测试后的一些清理工作。每个节点连接起来,组成状态图,可以对图中的每个节点进行操作,也可以自定义callback回调函数。

由于该项目不再更新,为此,本次将使用另外一个版本boofuzz,该工具基于Sulley,并且作者积极更新。Boofuzz是古老的Sulley模糊测试框架的分支和后续版本。除了大量的错误修复之外,boofuzz还致力于扩展性。

0x22 boofuzz API

Session对象是Fuzz测试的核心,当你创建Session的时候,你会传递一个Target对象,该对象本身接收一个Connection对象

session = Session(target=Target(connection=SocketConnection("127.0.0.1", 8021, proto='tcp')))

连接对象实现ITargetConnection。可用的选项包括 SocketConnection和SerialConnection。

准备好会话对象后,接下来需要在协议中定义消息。细节请参照 静态协议定义功能定义协议 。每一条消息均以一个s_initialize
函数开头,比如这是fuzz FTP协议中的几个消息定义:

s_initialize("user")
s_string("USER")
s_delim(" ")
s_string("anonymous")
s_static("\r\n")s_initialize("pass")
s_string("PASS")
s_delim(" ")
s_string("james")
s_static("\r\n")s_initialize("stor")
s_string("STOR")
s_delim(" ")
s_string("AAAA")
s_static("\r\n")s_initialize("retr")
s_string("RETR")
s_delim(" ")
s_string("AAAA")
s_static("\r\n")

定义消息后,将使用刚刚创建的Session对象将它们连接到图中:

session.connect(s_get("user"))
session.connect(s_get("user"), s_get("pass"))
session.connect(s_get("pass"), s_get("stor"))
session.connect(s_get("pass"), s_get("retr"))

之后,就可以进行fuzz测试了

session.fuzz()

每次运行的日志数据将保存到当前工作目录下boofuzz-results目录中的SQLite数据库中。可以随时通过以下任一方式在任何这些数据库上重新打开Web界面

boo open <run-*.db>

该段译自:https://boofuzz.readthedocs.io/en/stable/user/quickstart.html# API接口的详细说明,参照手册4即可。

0x30 Fuzz HTTP协议

0x31 boofuzz安装

Boofuzz需要Python。建议的安装要求pip。

Ubuntu: sudo apt-get install python-pip

请注意,源码是用python2写成的,高版本ubuntu自带python3,需要自己安装python2,所以应该用pip2

Ubuntu: pip2 install boofuzz

其他系统安装,请参考手册。官方手册中,提供了两个开源的示例 5

  • boofuzz-ftp
  • boofuzz-http

0x32 fuzz 某一路由器

在理解了 boofuzz (Sulley) 的架构之后,现在我们用boofuzz实战操作一波吧。

Created with Raphaël 2.2.0开始构造请求设置会话信息添加监控开始fuzz结束

Step1 根据API接口的数据包构造请求

比如,我们要对路由器的登录接口进行fuzz测试,首先需要使用Burpsuite设置代理,进行抓包。以下为某路由器的登录界面

Burpsuite抓包结果

现在需要根据报文,利用boofuzz框架提供的原语对http请求进行定义

s_initialize(name="Request")with s_block("Request-Line"):# LINE 1s_static("POST", name="Method")s_delim(" ", name='space-1')s_string("/fromLogin", name='Request-URI')  # 需要变异s_delim(" ", name='space-2')s_static('HTTP/1.1', name='HTTP-Version')   s_static("\r\n")# LINE 2s_static("Host", name="Host")s_static(": ")s_static("192.168.10.1", name="ip")s_static("\r\n")# LINE 3  对应 Content-Length: 400s_static('Content-Length')s_static(': ')s_size('data', output_format='ascii', fuzzable=True)    # size的值根据data部分的长度自动进行计算,同时对该字段进行fuzzs_static('\r\n')# ...s_static('\r\n')# 对应http请求数据with s_block('data'):s_static('login_name=&curTime=1581845487827&setLang=&setNoAutoLang=&login_n=admin&login_pass=')s_string('123456', max_len=1024)  # 需要变异,且最大长度为1024s_static('&languageSel=1')

Step2 设置会话信息

以下是最简单的一个会话的设置,包括设备的IP地址以及端口

session = Session(target=Target(connection=SocketConnection("192.168.10.1", 80, proto='tcp')netmon=Remote_NetworkMonitor(host, port, proto='tcp'))  # 服务可用性监控 非必须代码),)

如果需要fuzz多个请求,比如说,还要继续fuzz登录后的一些接口,还需要将之前定义的请求按照一定的先后顺序连接,比如说

session.connect(s_get('login'))        # 默认前置节点为root
session.connect(s_get('login'), s_get('setsysemailsettings'), callback=add_auth_callback)
session.connect(s_get('login'),s_get('setsyslogsettings'), callback=add_auth_callback)
session.connect(s_get('login'),s_get('setschedulesettings'), callback=add_auth_callback)

上面的代码中等同于下面的图例

由于setsysemailsettingssetsyslogsettingssetschedulesettings等请求需要在登录之后才可以正常使用,所以需要在login请求之后发生。而setsysemailsettingssetsyslogsettingssetschedulesettings这几个请求之间则没有明确的先后关系。add_auth_callback为自定义的回调函数,主要用于从login请求中获取用于登录认证的信息如cookie,然后将其设置于setsysemailsettingssetsyslogsettingssetschedulesettings等请求中。

Step3 添加监视器

正如我们在0x10节所说,通过当前设备是否在线,就是判断目标设备是否崩溃的方法之一。结合Step 2中,我们已经引用的函数Remote_NetworkMonitor(),其核心代码如下,此函数并非官方API,也可不添加

# 通过TCP全连接来判断目标端口是否在监听
if self.proto == "tcp" or self.proto == "ssl":try:self._sock.connect((self.host, self.port))self.alive_flag = 1except socket.error as e:self.alive_flag = 0

Step4 开始fuzz

最后只需要调用session.fuzz() 即可。运行我们编写好的脚本,正如0x22最后所述,每次运行的日志数据将保存到当前工作目录下boofuzz-results目录中的SQLite数据库中,运行boo open <run-*.db>,会在26000端口开启一个Web服务器,控制和查看测试进度(某些版本,运行fuzz脚本,会自动打开26000端口,所以只需要打开如下页面即可)。

上图表明,第238个用例测试结果出现了异常。tips:在打开数据库监控状态的时候,如果提示26000端口已经占用,可以使用netstat -anp | grep 26000找到进程,并杀死即可

0x33 结果分析

具体的原因,就要靠我们自己进行后续的分析了。可以使用数据库查看软件,Kali自带 DB Browser for SQLite,打开 boofuzz-results 目录下的相关文件可看到fuzz的日志

从数据库中可以看到,的确是按照我们的代码,对相关字段进行变异,从而达到fuzz的效果。进一步观察238个用例的前一个用例,找到发送的内容,重新发送,观察设备状态,看问题是否能够复现,最终确定漏洞是否存在。

0x40 总结

IoT 设备在移动互联网时代,是一个兴起并且正在壮大的群体,其安全性不容忽视。对 IoT 设备的协议进行模糊测试,是一种有效的漏洞挖掘手段。boofuzz就是这样一个优秀的针对协议fuzz的工具,笔者深入浅出,从原理出发,介绍其架构组成,并最终进行实战演练,更多的细节说明,请参考相关用户手册,这个工具更多的功能等你发现!

附:fuzz脚本

#!/usr/bin/env python
# Designed for use with boofuzz v0.0.9
# coding=utf-8
from boofuzz import *def main():session = Session(target=Target(connection=SocketConnection("192.168.10.1", 80, proto='tcp')),)s_initialize(name="Request")with s_block("Request-Line"):# LINE 1s_static("POST", name="Method")s_delim(" ", name='space-1')s_string("/fromLogin", name='Request-URI')  # variations_delim(" ", name='space-2')s_static('HTTP/1.1', name='HTTP-Version')   s_static("\r\n")# LINE 2s_static("Host", name="Host")s_static(": ")s_static("192.168.10.1", name="ip")s_static("\r\n")# LINE 3  对应 Content-Length: 400s_static('Content-Length')s_static(': ')s_size('data', output_format='ascii', fuzzable=True)    # size的值根据data部分的长度自动进行计算,同时对该字段进行fuzzs_static('\r\n')# ...s_static('\r\n')# 对应http请求数据with s_block('data'):s_static('login_name=&curTime=1581845487827&setLang=&setNoAutoLang=&login_n=admin&login_pass=')s_string('123456', max_len=1024)s_static('&languageSel=1')session.connect(s_get("Request"))session.fuzz()if __name__ == "__main__":main()

  1. https://www.jianshu.com/p/5993d5f003d3 ↩︎

  2. Fuzzing Sucks! Introducing the sulley fuzzing framework. Pedram Amini & Aaron Portnoy. Black Hat US 2007 ↩︎ ↩︎

  3. https://blog.csdn.net/u012397189/article/details/79758931 ↩︎

  4. https://boofuzz.readthedocs.io/en/stable/user/quickstart.html# ↩︎

  5. https://boofuzz.readthedocs.io/en/stable/index.html ↩︎

IoT 设备网络协议模糊测试工具boofuzz实战相关推荐

  1. 【网络协议模糊测试实战】使用sulley对PCManFTP进行模糊测试

    0x01 准备工作 1.首先需要安装好sulley,具体安装流程可以参考https://blog.csdn.net/u012397189/article/details/76084919 这篇文章介绍 ...

  2. EPF:一种基于进化、协议感知和覆盖率引导的网络协议模糊测试框架

    本文系原创,转载请说明出处:from 信安科研人,关注公众号信安科研人,获取更多安全资讯 文章目录 实验 工具的安装 1.安装AFL++ 2.安装epf 对IEC104协议库进行fuzz 实验准备 使 ...

  3. 2021年软件测试工具总结——模糊测试工具

    ~ 什么是模糊测试?~ 模糊测试(Fuzz Testing)是一种自动化的软件测试技术,最初是由威斯康辛大学的巴顿·米勒于1989年开发的,通常用于识别程序中的潜在漏洞.模糊测试的核心是自动或半自动的 ...

  4. 他们从各大操作系统中发现了26个 USB 漏洞,用的是这款模糊测试工具

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 普渡大学的研究员 Hui Peng 和瑞士洛桑联邦理工学院的研究员 Mathias Payer 在多种操作系统(如 Linux.mac ...

  5. 模糊测试工具defensics

    defensics是一个模糊测试工具,百度百科对模糊测试(Fuzzing)的定义是,是一种通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法.它是通过异常输入的方式触发原来未知的漏洞. ...

  6. Mip22:一款高级网络钓鱼安全测试工具

    关于Mip22 Mip22是一款功能强大的高级网络钓鱼安全测试工具,在该工具的帮助下,广大研究人员可以研究和测试组织内部抵御网络钓鱼攻击的能力和抗风险等级. 该工具出于安全研究和教育目的而开发,请在授 ...

  7. 模糊测试工具Simple Fuzzer

    模糊测试工具Simple Fuzzer 模糊测试是一种不同于渗透测试的漏洞检测方式.它向目标系统发送各种非预期的输入,然后通过监视异常结果来发现漏洞.Kali Linux虽然作为渗透测试系统平台,但也 ...

  8. Web模糊测试工具Powerfuzzer

    Web模糊测试工具Powerfuzzer Powerfuzzer是Kali Linux自带的一款Web模糊测试工具.该工具基于各种开源模糊测试工具构建,集成了大量安全信息.该工具高度智能化,它能根据用 ...

  9. cpu针脚测试软件,Sandsifter:一款专门针对X86处理器的模糊测试工具

    前言 今天给大家介绍的是一款名叫Sandsifter的x86处理器模糊测试工具.该工具可以通过系统生成的机器码来搜索处理器指令集,并通过监控异常数据来审计x86处理器中的隐藏指令和硬件漏洞.Sands ...

最新文章

  1. html给文字加动态效果,20种配合场景的CSS3鼠标滑过文字动画特效
  2. MySQL高级 - 存储引擎 - 特性
  3. 【渝粤教育】国家开放大学2018年春季 8659-22T计算机平面设计(1)(2) 参考试题
  4. poj 1330 Nearest Common Ancestors LCA/DFS
  5. 字符串的相关方法 2101 0310
  6. ICML 2022 第一届关于新冠病毒的智慧医疗研讨会
  7. phpMyAdmin无法导入大的数据库文件的解决方法
  8. 逼真照片随手画,马良神笔已上线 | 点击收获这份英伟达GauGAN开源代码
  9. hive内部表和外部表的区别_3000字揭秘Greenplum的外部数据加载——外部表
  10. Django中ORM常用字段及字段参数
  11. 实现滑动到中间变大的效果
  12. android studio按键精灵,51模拟器怎么连接按键精灵 51安卓模拟器按键精灵连接教程...
  13. java 订单支付_Java多订单多支付方式分配金额问题的解决
  14. 单反相机的传奇—佳能单反50年辉煌之路(连载十八)
  15. 代币标准--ERC721协议源码解析
  16. 滑动验证码--前端部分
  17. FreeModbus快速入门指南
  18. 2020年团体程序设计天梯赛
  19. win10系统 该文件没有与之关联的应用来执行该操作,请安装应用,若已经安装应用,请在“默认应用设计“页面中创建关联
  20. linux 删除目录下所有指定的子目录

热门文章

  1. 我的学习笔记 9月6号
  2. Build tool简介
  3. C++推箱子项目(带图带资料)
  4. Infoworld发布2009年度开源软件大奖
  5. 小程序switch内部加上文字_假王子恋爱手册2:女生向文字恋爱游戏小程序!女扮男装日记!...
  6. Lab5 Cache Lab
  7. 聚簇索引(Clustered Index)和非聚簇索引 (Non-Clustered Index)
  8. 如何自定义PickerView 以及改变字体大小和字体颜色
  9. 关于学习Java是应该是自学还是选择培训班
  10. 【安卓逆向】护眼软件去广告教程(简单详细)软件名护眼宝