探索什么是模糊测试 Fuzzing Test

什么是 "模糊测试"?

  Fuzzing 是一种发现软件缺陷的方法,它通过向程序提供随机输入来寻找导致程序崩溃的测试场景(原理有点类似Monkey Test)。可以帮助你快速了解程序整体的健壮性,并帮助你发现和修复关键的缺陷。

  它是一种黑盒测试技术,不需要访问源代码,但它仍然可以用来测试那些有源代码的软件。这是因为它能更快地发现缺陷,并降低大量代码评审成本。

  模糊测试优缺点

  Fuzzing在某些业务下虽然非常有用,但它毕竟不是银弹。以下是模糊技术的一些优点和缺点。

  优点

  ·可以说不费“吹灰之力”就能得到结果--一旦fuzzer启动并运行,它就可以在没有交互的情况下停留数小时、数天或数月来寻找错误。

  · 可以发现人工审计中遗漏的错误

  · 能对目标软件的健壮性提供一个整体性概述

  缺点

  · 不会穷尽所有bug--模糊测试可能会遗漏那些不会触发整个程序崩溃的bug,而且对那些只在非常特殊情况下触发的bug也难以覆盖。

  · 产生的崩溃测试用例可能难以分析,因为模糊测试的行为并不能告诉你关于软件内部运行方式的知识。

  · 具有复杂输入的程序可能需要更多的工作来产生一个足够聪明的模糊测试器,以获得足够的代码覆盖率。

  Smart/Dumb模糊测试

  Fuzzers向软件系统提供随机输入。内容形式可能是某种网络协议、某种格式的文件或用户能直接输入的数据。其输入方式是完全随机的,并不知道预期的输入应该是什么样子,也可以是经过一些修改后看起来像是有效的输入。

  产生完全随机输入的Fuzzer被称为 Dumb Fuzzer。少量的工作可以用很少的成本产生结果--这是模糊测试的一大优势。然而,有时一个程序只有在输入的特定场景才会执行某些处理。例如,一个程序的输入需要传入 "name"字段,而这个字段有一个与之相关的 "name length"。

  如果这些字段没有以足够有效的形式出现让程序识别,它可能永远不会读取这个名字。如果这些字段以有效的形式存在,但长度值被设置为不正确的值,程序可能会读到包含名字的缓冲区之外,并引发崩溃。如果缺乏有效的输入,这是不可能发生的。在这些情况下,可以使用 Smart Fuzzer,Smart Fuzzer是基于输入特定的规则实现的,例如协议定义或文件格式的规则。它可以构建大部分有效的输入,并且只对该基本格式内的输入进行模糊处理。

  Fuzzers的类型

  广义上讲,Fuzzer可以根据它们创建程序输入的方式分为两类--基于变异与基于生成.

  基于变异的fuzzer

  基于突变的Fuzzer可以说是最容易创建的类型之一。这种技术适合Dumb Fuzzer,但也可用于智能的Fuzzer。通过突变,有效输入的样本被随机突变以产生畸形的输入。

  dumb mutation Fuzzer可以简单地选择一个有效的输入样本,并随机地改变它的一部分。因为输入通常仍然与有效输入有足够的相似性,所以这意味着不需要进一步的智能化处理就可以实现良好的代码覆盖。

  下面是基于突变的Fuzzer可以使用的两种技术。

  流量回放

  Fuzzer可以采取保存的样本输入,并在突变后重新播放。这对文件格式的模糊处理很有效,可以保存一些样本文件并进行模糊处理以提供给目标程序。

  简单或无状态的网络协议也可以用重放来有效地进行模糊处理,因为Fuzzer不需要提出大量的合法请求来深入到协议中去。对于更复杂的协议,重放可能更困难。这是因为Fuzzer需要以动态方式响应程序,以允许处理继续深入协议。

  代理

  你可能听说过中间人(MITM)是渗透测试者和黑客使用的一种技术,但它也可以用于基于突变的网络协议模糊测试。通过MITM,你置身于客户端和服务器的中间,截获并可能修改它们之间传递的信息。通过这种方式,你就像两者之间的一个代理。

  通过将你的Fuzzer设置为代理,它可以根据你对服务器或客户端的模糊处理来改变请求或响应。同样,Fuzzer可以随机地改变一些请求,也可以在你感兴趣的协议的特定层次上智能地锁定请求。基于代理的模糊测试可以让你利用现有的网络程序部署架构,快速插入模糊测试层,而不需要让你的fuzzer像客户端或服务器本身一样行动。

  基于生成的fuzzer

  基于生成的Fuzzer实际上是从零开始生成输入,而不是突变现有的输入。它们通常需要一定程度的智能来构建至少对程序有一定意义的输入,尽管生成完全随机的数据在技术上也是生成。

  生成Fuzzer通常将协议或文件格式分成几块,它们可以按照有效的顺序建立起来,并随机地对其中一些块进行独立模糊。这可以创造出保留其整体结构的输入,但其中也包含不一致的数据。这些块的颗粒度和构建这些块的智能程度决定了Fuzzer的智能水平。虽然基于突变的模糊处理可以产生与生成模糊处理类似的效果(因为随着时间的推移,突变将被随机应用,而不会完全破坏输入的结构),但生成输入可以确保这种情况的发生。

  生成fuzzers也可以更容易地深入到协议中,因为它可以构建有效的输入序列,对该通信的特定部分进行模糊处理。它还允许Fuzzer作为一个真正的客户/服务器,生成正确的、动态的响应,但这些响应不能盲目地重放。

  进化型fuzzer

  进化型模糊测试是一种先进的技术。它允许Fuzzer使用来自每个测试用例的反馈,以了解随着时间推移输入的格式。例如,通过测量每个测试用例的代码覆盖率,Fuzzer可以计算出测试用例的哪些属性可以锻炼给定的代码区域,并逐渐演化出一套覆盖大部分程序代码的测试用例。进化型模糊测试通常依赖于与遗传算法类似的其他技术,并且可能需要某种形式的二进制工具来正确操作。

  模糊测试测什么?

  即使是相对dumb的模糊测试,也要记住你的测试用例实际上有可能击中代码的哪一部分。举个简单的例子,如果你正在摸索一个使用TCP/IP的应用协议,而你的Fuzzers随机突变了一个原始数据包的捕获,你很可能会破坏TCP/IP数据包本身。因此,你的输入根本不可能被应用程序所处理。再者,如果你正在测试一个将文本的图像解析为真实文本的OCR程序,但你正在突变整个图像文件,你最终可能会更频繁地测试其图像解析代码而不是实际的OCR代码。如果你想专门针对该OCR处理,你可能希望保持图像文件的标题有效。

  Fuzzer运行流程

  为了有效地运行,Fuzzer需要执行以下重要任务:

  ·生成测试用例

  · 记录测试用例或再现用例所需的任何信息

  · 对目标程序接口提供测试case作为输入

  · 检测崩溃

  Fuzzer通常将其中的许多任务分成独立的模块。例如,有一个库可以突变数据或根据定义生成数据,另一个库可以向目标程序提供测试用例等等。

  生成测试用例

  测试用例的生成将取决于是否采用了基于突变或基于生成的模糊处理。无论采用哪种方法,都会有一些需要随机转换的东西,无论是特定类型的字段还是任意的数据块。

  这些转换可以是完全随机的,但值得注意的是,边界和极端的情况往往是程序中错误的来源。因此,你可能希望偏向于这样的情况。

  · 非常长超长字符串或Null

  · 能支持的最大值和最小值整数

  · 像-1、0、1和2这样的值

  根据你要模糊处理的内容,可能会有一些特定的值或字符更容易触发bug。比如:

  · Null

  · 分号

  · 格式化字符串值(%n,%s等等)

  · 应用特定的关键词

  可重复性

  重现一个测试用例的最简单方法是记录检测到崩溃时使用的确切输入。在某些情况下,还有其他方法能实现重现性。一种方法是存储用于测试用例生成的随机部分的初始种子,并确保所有后续的随机行为遵循一个可以追溯到该种子的路径。通过用相同的种子重新运行Fuzzer,行为应该是可重复的。例如,你可以只记录测试用例编号和初始种子,然后用该种子快速重新执行生成,直到达到给定的测试用例。

  当目标程序可能基于过去的输入积累了依赖性时,这种技术就很有用。以前的输入可能导致程序在其内存中初始化各种项目,而这些项目是触发错误所必须的。在这些情况下,简单地记录崩溃的测试用例并不足以重现该错误。

  与目标程序对接

  与目标程序连接以提供模糊输入通常是简单的。对于网络协议,它可能涉及在网络上发送测试用例,或响应客户的请求。对于文件格式,它可能意味着用一个指向测试用例的命令行参数来执行程序。然而,有时提供的输入的形式不容易以自动化的方式生成,或者编写程序脚本来执行每个测试用例的开销很大,证明是非常缓慢的。在这些情况下,创造性的思考可以发现用正确的数据来锻炼相关的代码片断的方法。

  例如,这可以通过在内存中人为地设置程序来执行解析功能,而输入的参数完全在内存中。这可以消除程序在每个测试用例之前经过冗长的加载程序的需要。而且,通过让测试用例完全在内存中生成和提供,而不是通过硬盘驱动器,可以进一步提高速度。

  崩溃检测

  崩溃检测是模糊测试的关键。如果你不能准确地确定一个程序何时崩溃,你就不能确定一个测试用例是否触发了一个错误。

  · 附加一个调试器

  这可以为你提供最准确的结果,你可以编写调试器的脚本,以便在检测到崩溃时立即为你提供崩溃跟踪。然而,附加一个调试器会大大降低程序的速度,并会造成相当大的开销。在给定的时间内,你能产生的测试用例越少,你发现崩溃的机会就越少。

  · 看看目标进程是否消失了

  与其附加一个调试器,你可以简单地看看在执行测试用例后,目标的进程ID是否仍然存在于系统中。如果进程消失了,它可能已经崩溃了。如果你想了解更多关于崩溃的信息,你可以在以后用调试器重新运行测试用例。你甚至可以在每次崩溃时自动这样做,同时还可以避免在每个案例中都连接调试器而导致的速度下降。

  超时

  如果程序对你的测试用例有正常的响应,你可以设置一个超时,超时后你就认为程序已经崩溃。这也可以检测出导致程序无反应但不一定终止的错误。

  无论你使用哪种方法,只要程序崩溃或变得无反应,就应该重新启动,以便让模糊测试继续进行。

  模糊测试的质量

  你可以做一些事情来衡量或提高你的模糊测试的质量。虽然这些都是需要记住的有用的东西,但如果你已经在一定的时间范围内得到了很多独特的崩溃,你可能不需要再为这些事情费心了。

  速度

  速度可能是模糊测试中最重要的因素之一。你每秒钟/每分钟能运行多少个测试用例?合理的数值当然取决于目标,但你能执行的测试用例越多,你就越有可能在给定的时间段内发现崩溃。模糊测试是随机的,所以每一个测试用例就像一张彩票,你要尽可能多地得到它们。

  你可以做很多事情来提高测试用例的速度,比如提高生成或变异例程的效率,并行化测试用例,减少超时,或在不显示图形用户界面的 "无头 "模式下运行程序。如果你想的话,你可以简单地购买更快的套件。

  对崩溃进行归类

  找到崩溃只是过程的开始。一旦你找到一个崩溃的测试用例,你就需要分析它,找出错误所在,并根据你的动机,修复它或为它编写一个漏洞。如果你有成千上万个崩溃的测试用例,这可能是相当令人生畏的。通过对崩溃进行分类,你可以根据哪些崩溃是你最感兴趣的来确定它们的优先次序。这也可以帮助你识别一个测试用例何时触发了与另一个相同的错误,所以你只保留与独特崩溃有关的案例。

  为了做到这一点,你需要一些关于崩溃的自动信息,以便你能做出决定。在目标机上运行测试用例并连接到调试器,可以提供崩溃跟踪,你可以对其进行分析,找到诸如异常类型、寄存器值、堆栈内容等值。

  减少测试用例

  由于模糊测试是随机改变输入的,一个崩溃的测试用例通常会有多个与触发该错误无关的改变。测试用例缩减是将测试用例缩减到触发bug所需的有效输入的最小改动集,因此你只需要在分析中关注输入的这一部分。

  这种减少可以手动进行,但也可以由Fuzzer自动进行。当遇到一个崩溃的测试用例时,Fuzzer可以重新执行该测试用例几次。每一次,它都会逐渐减少对输入的改动,直到剩下最小的一组改动,同时仍然触发该错误。这可以简化你的分析,并有助于对崩溃的测试用例进行分类,因为你会准确知道输入的哪些部分受到影响。

  代码覆盖率

  这是一个衡量程序的代码有多少被Fuzzer执行的标准。其原理是,你得到的覆盖率越多,你实际测试的程序就越多。测量代码覆盖率可能很棘手,通常需要二进制仪器来跟踪代码的哪些部分正在被执行。你也可以用不同的方式测量代码覆盖率,比如按行、按基本块、按分支或按代码路径。

  代码覆盖率对于模糊测试来说并不是一个完美的衡量标准,因为有可能在执行代码的同时并没有发现其中的漏洞。而且,经常有一些代码区域几乎不会被执行,例如安全错误检查,反正我们不太可能真正需要,也不太感兴趣。尽管如此,某种形式的代码覆盖率测量可以让我们了解到你的Fuzzer在程序中触发了什么。特别是当你的模糊测试是完全黑箱的时候,你可能还不太了解程序的内部运作。一些可能有助于代码覆盖率的工具和技术包括Pai Mei、Valgrind、DynamoRIO和DTrace。

  模糊测试框架

  目前市面上有许多框架可以让你创建Fuzzer,而不必从头开始造。下面列出了这些框架:

  Radamsa

  Radamsa被设计为易于使用和灵活。它试图对各种输入类型进行 "公正的工作",并包含一些不同的模糊算法进行突变。

  Sulley

  Sulley提供了一个全面的生成框架,允许结构化数据被表示为基于生成的模糊处理。它还包含帮助记录测试用例和检测崩溃的组件。

  Peach

  Peach框架可以对文件格式和网络协议进行智能模糊测试。它可以执行基于生成和突变的模糊测试,并包含帮助建立模型和监控目标的组件。

  SPIKE

  SPIKE是一个网络协议Fuzzer。它需要用户熟悉掌握C语言,并被设计为在Linux上运行。

  Grinder

  Grinder是一个网络浏览器Fuzzer,它还具有帮助管理大量崩溃的功能。

  NodeFuzz

  NodeFuzz是一个基于node.js的网络浏览器线束,它包括仪器模块,可以从客户端获得更多信息。

  AFL

  AFL是一个灰盒式的模糊测试工具,利用编译在目标代码中的仪器。AFL最初是为Linux中的C和C++程序编写的,后来被分叉以支持WindowsJava和.Net。

 感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

 

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/404112.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python常用包】pathlib

目录 简介Pathlib 库实现Path 创建路径对象检查路径类型创建和删除路径(目录与文件)读写文件路径匹配路径拼接和解析路径属性路径迭代和列出目录内容 小结 简介 Pathlib 是一个用于处理文件路径的 Python 库,提供了许多实用的函数和方法来处…

windows安装编译的python包

有时windows无法直接通过网络安装python包,需要从一个地方先下载好,再去安装,下载的一些编译好的python包,安装时发现提示“is not a supported wheel on this platform”,那可能就是下载编译好的版本不对。 可以通过…

代码随想录第二十四天 39.组合总和 40.组合总和II 131.分割回文串

LeetCode 39 组合总和 题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个…

电表(3)EC600N 4G模块通过mqtt向服务器发送数据

工具 1、ec600 2、stm32f030c8 3、keil5 4、腾讯云服务器(ubutu20.04) mqtt服务器 sudo apt install mosquitto mosquitto-clients sudo systemctl start mosquitto sudo vim /etc/mosquitto/mosquitto.conf sudo systemctl status mosquittolistene…

Aspose.Words For JAVA 动态制作多维度表格(涵2024最新无水印包)

全网最全Aspose.Words For JAVA 高级使用教程: CSDNhttps://blog.csdn.net/LiHaoHang6/article/details/133989664?spm1001.2014.3001.5501 运行截图: 所谓多维度表格通常包含多个维度, 每个维度都代表一种数据属性,多维度表格可以用于数据分析,通过不…

ArcgisForJS如何使用ArcGIS Server发布的切片地图服务?

文章目录 0.引言1.准备海量地理数据2.ArcGIS Server发布切片地图服务3.ArcgisForJS使用ArcGIS Server发布的切片地图服务 0.引言 ArcGIS Server是一个由Esri开发的地理信息系统(GIS)服务器软件,它提供了许多功能,包括发布切片地图…

Python实战:统计字符串中的英文字母、空格、数字及其他字符出现的个数

Python实战:统计字符串中的英文字母、空格、数字及其他字符出现的个数 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &…

Servlet使用过程中常见问题总结

💕"Echo"💕 作者:Mylvzi 文章主要内容:Servlet使用过程中常见问题总结 前言:笔者在学习Servlet的过程中遇到了很多问题,这里总结一下 1.乱码问题 如果我们在响应报文中传输中文"你好",那么在浏览器之中显示…

Redis中的AOF重写到底是怎么一回事

首先我们知道AOF和RDB都是Redis持久化的方法。RDB是Redis DB,一种二进制数据格式,这样就是相当于全量保存数据快照了。AOF则是保存命令,然后恢复的时候重放命令。 AOF随着时间推移,会越来越大,因为不断往里追加命令。…

Java基于SpringBoot+Vue的图书馆管理系统,附源码,数据库

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

一款跳转警告HTML单页模板源码

一款跳转警告HTML单页模板,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 代码如下 <!DOCTYPE html> <html> <!--QQ沐编程 www.q…

HarmonyOS—使用预览器查看应用/服务效果

DevEco Studio为开发者提供了UI界面预览功能&#xff0c;可以查看应用/服务的UI界面效果&#xff0c;方便开发者随时调整界面UI布局。预览器支持布局代码的实时预览&#xff0c;只需要将开发的源代码进行保存&#xff0c;就可以通过预览器实时查看应用/服务运行效果&#xff0c…

统计图玫瑰图绘制方法

统计图玫瑰图绘制方法 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制&#xff0c;饼图环形图绘制较难。 还有一种玫瑰图的绘制也较难&#xff0c;今提供玫瑰图的绘制方法供参考。 本方法采用C语言的最基本功能&#xff1a; &am…

axure9.0 工具使用思考

原型设计软件【AxureRP】快速原型设计工具原型设计软件【AxureRP】快速原型设计工具原型设计软件【AxureRP】快速原型设计工具原型设计软件【AxureRP】快速原型设计工具原型设计软件【AxureRP】快速原型设计工具原型设计软件【AxureRP】快速原型设计工具原型设计软件【AxureRP】…

Kafka3.x进阶

来源&#xff1a;B站 目录 Kafka生产者生产经验——生产者如何提高吞吐量生产经验——数据可靠性生产经验——数据去重数据传递语义幂等性生产者事务 生产经验——数据有序生产经验——数据乱序 Kafka BrokerKafka Broker 工作流程Zookeeper 存储的 Kafka 信息Kafka Broker 总…

预告 | 飞凌嵌入式即将亮相第八届瑞芯微开发者大会(RKDC2024)

2024年3月7~8日&#xff0c;第八届瑞芯微开发者大会&#xff08;RKDC2024&#xff09;将在福州举办&#xff0c;本届大会以“AI芯片AI应用AloT”为主题&#xff0c;邀请各行业的开发者共启数智化未来。 本届大会亮点颇多&#xff0c;不仅有13大芯片应用展示、9场产品和技术论坛…

洛谷 【算法1-2】排序

【算法1-2】排序 - 题单 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 鄙人不才&#xff0c;刷洛谷&#xff0c;迎蓝桥&#xff0c;【算法1-2】排序 已刷&#xff0c;现将 AC 代码献上&#xff0c;望有助于各位 P1271 选举学生会 【深基9.例1】选举学生会 - 洛谷 题目 解答…

YOLOv9 | 利用YOLOv9训练自己的数据集 -> 推理、验证(源码解读 + 手撕结构图)

一、本文介绍 本文给大家带来的是全新的SOTA模型YOLOv9的基础使用教程&#xff0c;需要注意的是YOLOv9发布时间为2024年2月21日&#xff0c;截至最近的日期也没有过去几天&#xff0c;从其实验结果上来看&#xff0c;其效果无论是精度和参数量都要大于过去的一些实时检测模型&…

智能水浸传感器拆解指导,水浸传感器有哪些种类?

很多朋友听说过智能水浸传感器&#xff0c;当我们的厨房或者卫生间发生漏水&#xff0c;只要提前安装放置好一个水浸传感器&#xff0c;哪怕我们身处外地也能发现并及时处理。除此之外&#xff0c;数据中心、机房、仓库、实验室、工厂、档案馆等也是智能水浸传感器的常见应用场…

如何图片无损放大?分享两个无损放大方法

在数字化时代的洪流中&#xff0c;我们时常被细微之处的美丽所打动——那些精致的画面&#xff0c;那些清晰的细节。然而&#xff0c;随着图片的放大&#xff0c;我们常常面临一个难题&#xff1a;清晰度的损失。此时&#xff0c;图片无损放大软件能够在不损失图片质量的前提下…