使用Jazzer编写fuzz目标

  • 使用Jazzer编写fuzz目标已关闭评论
  • 10 views
  • A+

译文声明

本文作者Fabian Meumertzheim

原文来自https://blog.code-intelligence.com/fuzz-targets-jazzer

Jazzer简介

Jazzer是Java虚拟机(JVM)的开源模糊测试引擎。使用Jazzer开发人员可以增加测试覆盖率,有利于发现边缘情况作出处理来防止软件BUG。

jazzer构建基于流行并可靠的工具,包括libFuzzer模糊测试引擎和JaCoCo用于覆盖测试范围。和大多数现代模糊测试器一样,Jazzer是一个覆盖引导的进程内模糊器,它在自己的JVM实例中运行Java目标,同时监视所到达的代码路径,这使得开发人员可以高速测试需要测试的软件,因为Jazzer直接在JVM字节码上操作,所以即使没有源代码也可以做到。

libFuzzer vs. Jazzer

Jazzer拥有libFuzzer的所有高级特性,并将它们移植到了Java,此外还添加了一些其他的Java智能,比如“继续运行”模式,该模式允许开发人员快速跳过无用的异常,而转去其他有用的bug和漏洞。

经过考验的libFuzzer特性:

1、最小化和重复数据删除

2、叉子模式下的并行模糊测试

3、价值分析

其他Java功能:

1、纯Java复制

2、继续进行模式

3、方法连接框架

使用Jazzer会触发许多错误, 但从Java开发人员角度来看会更希望调试代码时没有没有或减少模糊测试的“开销”,因此我们创建了简单的Java类,主要为了触发恶意输入,即所谓的复制器。

方法挂钩是jazzer的一项高级功能,可用于编写bug检测和sanitizers(相关信息请参阅GitHub documentation)。

使用Jazzer建立模糊目标

下面是一个小型但具有演示意义的示例应用程序,该应用程序使用一个String变量和两个long变量,首先它使用Base64对String变量进行编码,并检查它是否等于预定义的String变量,(SmF6emVy是Jazzer的Base64编码),只有当Base64编码匹配时程序才会继续。然后应用程序使用静态密钥对2个long变量进行XOR加密,之后再次将它们与预定义值进行比较。如果两者都匹配,程序会继续执行并到达漏洞。虽然人类可以简单解决这个简单示例,但因为需要找到非常具体的magic值才能通过检查,所以模糊测试人员可以使用此类代码轻松解决该问题。另外这种情况下,模糊器还需要破坏XOR加密。

ApplicationUnderTest

上述示例来源。

jazzer优化

Jazzer可以轻松解决上述问题。下面可以看到一个Jazzer模糊测试目标,它只是一个静态fuzzerTestOneInput函数,该函数使用FuzzedDataProvider,一个帮助对象用于切割,将fuzz输入拆分成有用的原始类型,并获取示例应用程序所需的String变量和两个long变量。 然后使用获得的数据调用应用程序即可。

ExampleValueProfileFuzzer

该示例在这。

只需要5秒钟

运行Jazzer进行测试只需5秒钟即可使该目标崩溃,在执行大约250万次,每秒60万次运行之后,Jazzer将发现magic值,该值使其通过Base64编码和XOR加密并触发了该bug。
Jazzer能够迅速地克服这些障碍的原因与libFuzzer一样,Jazzer使用value概要分析指导fuzzer更加有效地通过这种类型的检查,这比简单的发现value更加有效。

要了解更多信息请访问https://llvm.org/docs/LibFuzzer.html#value-profile和https://github.com/CodeIntelligenceTesting/jazzer/#value-profile。

Jazzer output
示例

为什么模糊测试像Java那样的内存安全语言

开发人员有一个普遍的误解,即模糊测试只适合于检测内存损坏bug,因为Java是一种内存安全语言,所以不需要对Java进行模糊测试处理。但是fuzzer可以发现比内存损坏更多的bug,只是像C和C++这样的语言有较多的内存bug,并且它们具有很高的影响,所以它们吸引了所有人的关注。事实上fuzzers可以发现任何类型的错误,测试人员可以指定想要指定的任何类型的错误,简单且常见的例子是未捕获的异常和导致服务或应用程序崩溃的内存泄漏,除此之外还可以找到可用于DoS攻击的无限循环。更有趣的是任何可以表示为断言的东西都可以很简单地找到,例如对于给定的输入,多个实现或库应该产生相同的输出,但在边界情况下却不同。

也可能会发现SQL注入甚至是远程代码执行错误,正因为所有语言都容易受到功能错误以及严重的安全漏洞的影响,所以需要对内存安全语言进行模糊处理。

可以通过模糊检测发现的常见Java漏洞

功能性bug:

1、未捕获的异常

2、断言

3、不一致的实现(不同的模糊测试)

安全问题:

1、无限循环

2、OutOfMemoryError

3、SQL注入

4、XSS

5、RCE

···········

示例:模糊测试一个流行的Java库

因此,在通过清理程序运行不受信任的输入之后,您应该能够将其安全地嵌入HTML的脚本块中,就像下面的橙色框一样。让我们来看一个我们在Jazzer上发现的一个真正的bug,在这个特定的示例中,我们将讨论JSON-sanitizer,它是一个由谷歌开发,由OWASP基金会维护的流行Java库。您可以向JSON-sanitizer提供任意字节和字符串,它确保输出始终是有效的JSON,JSON-sanitizer保证输出永远不会包含某些子字符串,由于HTML解析方式的原因,这些子字符串可能会弄乱您的脚本,甚至导致XSS,因此在通过sanitizer运行不受信任的输入之后,您应该能够安全地将其嵌入HTML中的脚本块中,就像下面的橙色框中所示。

wKg0C2CXryiASukeAACl38GiA8550.png

JSON-sanitizer:嵌入式脚本示例。

我们在Jazzer中使用了基于属性的模糊测试方法,我们使用一个字符串,并通过sanitizer传递,然后我们断言清理从程序中发出的“safe”JSON不包含指定的子字符串,因为这样做很容易受到跨站点脚本的攻击。

fuzzerTestOneInput

基于属性的模糊目标要点

JSON sanitizer中的XSS(CVE-2021-23899

通过这个模糊目标,我们在JSON sanitizer中发现了一个漏洞,这个漏洞不难触发,通过“转义”JSON字符串中HTML标记的第一个字母,您可以通过sanitizer传递它,它将输出原始标记。因为HTML的性质,这个关闭脚本标记即使包含在JavaScript字符串文字中也会关闭脚本块,然后启动一个新程序插入一个新警报,就会得到一个跨站点脚本攻击。

XXS in JSON sanitizer

fuzzing使我们可以轻松地在这个流行且经过测试的Java项目中找到一个严重性较高的安全漏洞。

更新:Google将Jazzer集成到OSS-Fuzz中,现在开源项目可以利用Google的基础架构和计算能力来保护它们的Java库,阅读Google安全博客上的完整发行说明。

Jazzer发现

自从Jazzer于2021年2月中旬发布以来,我们已经在20多个开源项目中发现了100多个bug,在50个bug中有8个是安全问题,其中5个是在稳定版本中发现的,因此分配给cve。

希望这篇文章能给你一个良好的第一印象,让你知道用Jazzer在Java应用程序中查找bug是多么容易,如果你想了解更多关于Jazzer的知识,我也推荐Engineering Jazzer这篇文章。或者在GitHub上看看Jazzer。

相关推荐: Vlunhub-Hacksudo系列1.0.1

靶机环境 这个靶机是hacksudo系列的第一部。 靶机名称:Hacksudo1.0.1 IP地址为:192.168.17.143 攻击机:kali2021 IP地址为:192.168.17.131 主机发现 nmap -sC -sV -p- 192.168.…