Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ruzzy — 一个针对纯Ruby代码和Ruby C扩展的覆盖率引导模糊测试器 | Kitploit
工具/GitHubGitHub/trailofbits/ruzzy
动态分析 (沙盒)漏洞分析代码分析模糊测试二进制分析学习与教育
GitHubtrailofbits/ruzzy

ruzzy

一个针对纯Ruby代码和Ruby C扩展的覆盖率引导模糊测试器

查看仓库
123742个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Ruzzy

Test Gem Version

一个基于覆盖率引导的模糊测试工具,用于纯 Ruby 代码和 Ruby C 扩展。

Ruzzy 深受 Google 的 Atheris(一个 Python 模糊测试器)启发。Ruzzy 使用 libFuzzer(或 LibAFL)作为其覆盖率检测和模糊测试引擎。在对 C 扩展进行模糊测试时,Ruzzy 还支持 AddressSanitizer 和 UndefinedBehaviorSanitizer。如果您想了解更多关于 Ruzzy 背后的灵感,请参阅我们的论文:Design and Implementation of a Coverage-Guided Ruby Fuzzer。

目录:

  • 安装
  • 使用
    • 快速开始
    • 模糊测试纯 Ruby 代码
    • 模糊测试 Ruby C 扩展
  • API
    • Ruzzy
    • FuzzedDataProvider
  • macOS 用户注意事项
  • 成果案例
  • 开发
    • 编译
    • 测试
    • 代码检查
    • 发布
  • 延伸阅读

安装

Ruzzy 支持 Linux(x86-64、AArch64/ARM64)和 macOS(Apple Silicon)。在 Windows 上,您可以构建 Dockerfile 和/或使用开发环境。Ruzzy 需要较新版本的 clang(已测试至 14.0.0),最好使用最新版本。有关 macOS 的特定设置,请参阅 macOS 用户注意事项。

使用以下命令安装 Ruzzy:

root@kitploit:~
MAKE="make --environment-overrides V=1" \
CC="/path/to/clang" \
CXX="/path/to/clang++" \
LDSHARED="/path/to/clang -shared" \
LDSHAREDXX="/path/to/clang++ -shared" \
    gem install ruzzy

这里涉及很多内容,我们逐一解释:

  • MAKE 环境变量会在编译 Ruzzy C 扩展时覆盖 make 命令。这会告诉 make 在编译扩展时遵循后续的环境变量。
  • 其余环境变量在编译期间用于确保我们使用正确的 clang 二进制文件。这确保我们拥有最新的 clang 功能,这对于正确的模糊测试是必要的。

如果安装遇到问题,可以运行以下命令获取调试输出:

root@kitploit:~
RUZZY_DEBUG=1 gem install --verbose ruzzy

如果您的纯 Ruby 模糊测试目标大量使用正则表达式,请安装 regexp_parser:

root@kitploit:~
gem install regexp_parser

安装后,Ruzzy 将自动使用此功能对模糊测试中遇到的正则表达式进行采样(即求解)。这允许模糊测试器绕过正则表达式条件,解锁额外的覆盖率。

使用

快速开始

Ruzzy 包含一个玩具示例来演示其工作原理。首先,设置以下环境变量:

root@kitploit:~
export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"
理解这些选项不是必须的,但如果您好奇,请点击这里。

ASAN_OPTIONS

  1. 内存分配失败很常见且影响较小(DoS),因此暂时跳过。
  2. 与 Python 类似,Ruby 解释器会泄漏数据,因此暂时忽略这些。
  3. Ruby 建议禁用 sigaltstack。

然后您可以使用以下命令运行示例:

root@kitploit:~
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby -e 'require "ruzzy"; Ruzzy.dummy'

LD_PRELOAD 是必需的,原因与 Atheris 相同。但与 ASAN_OPTIONS 不同,您可能不希望 export 它,因为它可能会干扰其他程序。

它应快速产生如下崩溃:

root@kitploit:~
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2527961537
...
==45==ERROR: AddressSanitizer: heap-use-after-free on address 0x50c0009bab80 at pc 0xffff99ea1b44 bp 0xffffce8a67d0 sp 0xffffce8a67c8
...
SUMMARY: AddressSanitizer: heap-use-after-free /var/lib/gems/3.1.0/gems/ruzzy-0.8.0/ext/dummy/dummy.c:18:24 in _c_dummy_test_one_input
...
==45==ABORTING
MS: 4 EraseBytes-CopyPart-CopyPart-ChangeBit-; base unit: 410e5346bca8ee150ffd507311dd85789f2e171e
0x48,0x49,
HI
artifact_prefix='./'; Test unit written to ./crash-253420c1158bc6382093d409ce2e9cff5806e980
Base64: SEk=

我们可以看到它正确找到了导致内存违规的输入("HI")。更多信息,请查看 dummy.c 了解为什么会出现此违规。

您可以使用以下命令重新运行崩溃案例:

root@kitploit:~
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby -e 'require "ruzzy"; Ruzzy.dummy' \
    ./crash-253420c1158bc6382093d409ce2e9cff5806e980

以下消毒器可用:

  • Ruzzy::ASAN_PATH 用于 AddressSanitizer
  • Ruzzy::UBSAN_PATH 用于 UndefinedBehaviorSanitizer

模糊测试纯 Ruby 代码

让我们以一个小的 Ruby 脚本为例进行模糊测试。模糊测试纯 Ruby 代码需要两个 Ruby 脚本:一个追踪器脚本和一个模糊测试驱动。由于 Ruby 解释器的一个实现细节,追踪器脚本是必需的。

首先,追踪器脚本,我们称之为 test_tracer.rb:

root@kitploit:~
# frozen_string_literal: true

require 'ruzzy'

Ruzzy.trace('test_harness.rb')

接下来,模糊测试驱动,我们称之为 test_harness.rb:

root@kitploit:~
# frozen_string_literal: true

require 'ruzzy'

def fuzzing_target(input)
  if input.length == 4
    if input[0] == 'F'
      if input[1] == 'U'
        if input[2] == 'Z'
          if input[3] == 'Z'
            raise
          end
        end
      end
    end
  end
end

test_one_input = lambda do |data|
  fuzzing_target(data) # Your fuzzing target would go here
  return 0
end

Ruzzy.fuzz(test_one_input)

您可以使用以下命令运行此文件并开始模糊测试:

root@kitploit:~
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby test_tracer.rb

它应快速产生如下崩溃:

root@kitploit:~
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2311041000
...
/app/ruzzy/bin/test_harness.rb:12:in `block in <top (required)>': unhandled exception
	from /var/lib/gems/3.1.0/gems/ruzzy-0.8.0/lib/ruzzy.rb:15:in `c_fuzz'
	from /var/lib/gems/3.1.0/gems/ruzzy-0.8.0/lib/ruzzy.rb:15:in `fuzz'
	from /app/ruzzy/bin/test_harness.rb:35:in `<top (required)>'
	from bin/test_tracer.rb:7:in `require_relative'
	from bin/test_tracer.rb:7:in `<main>'
...
SUMMARY: libFuzzer: fuzz target exited
MS: 1 CopyPart-; base unit: 24b4b428cf94c21616893d6f94b30398a49d27cc
0x46,0x55,0x5a,0x5a,
FUZZ
artifact_prefix='./'; Test unit written to ./crash-aea2e3923af219a8956f626558ef32f30a914ebc
Base64: RlVaWg==

我们可以看到它正确找到了导致异常的输入("FUZZ")。

要对您自己的目标进行模糊测试,请修改 test_one_input 的 lambda 以调用您的目标函数。

模糊测试 Ruby C 扩展

让我们以 msgpack-ruby 库为例进行模糊测试。首先,安装 gem:

root@kitploit:~
MAKE="make --environment-overrides V=1" \
CC="/path/to/clang" \
CXX="/path/to/clang++" \
LDSHARED="/path/to/clang -shared" \
LDSHAREDXX="/path/to/clang++ -shared" \
CFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
CXXFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
    gem install msgpack

除了编译 Ruzzy 时使用的环境变量外,我们还指定了 CFLAGS 和 CXXFLAGS。这些标志有助于模糊测试过程。它们启用了有用的功能,例如地址消毒器和改进的堆栈跟踪信息。更多信息请参阅 AddressSanitizerFlags。

接下来,我们需要一个针对 msgpack 的模糊测试驱动。以下内容可能对具有 libFuzzer 经验 的人来说很熟悉:

root@kitploit:~
# frozen_string_literal: true

require 'msgpack'
require 'ruzzy'

test_one_input = lambda do |data|
  begin
    MessagePack.unpack(data)
  rescue Exception
    # We're looking for memory corruption, not Ruby exceptions
  end
  return 0
end

Ruzzy.fuzz(test_one_input)

我们称此文件为 fuzz_msgpack.rb。您可以使用以下命令运行此文件并开始模糊测试:

root@kitploit:~
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby fuzz_msgpack.rb

libFuzzer 选项可以像这样传递给 Ruby 脚本:

root@kitploit:~
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby fuzz_msgpack.rb /path/to/corpus

更多信息请参阅 libFuzzer 选项。

要对您自己的目标进行模糊测试,请修改 test_one_input 的 lambda 以调用您的目标函数。

API

Ruzzy

Ruzzy 模块暴露了顶层入口点。

FuzzedDataProvider

Ruzzy::FuzzedDataProvider 拆分 原始模糊测试字节为类型化的 Ruby 值。

root@kitploit:~
test_one_input = lambda do |data|
  fdp = Ruzzy::FuzzedDataProvider.new(data)
  name = fdp.consume_random_length_string(50)
  age = fdp.consume_int_in_range(0, 150)
  score = fdp.consume_float_in_range(0.0, 100.0)
  role = fdp.pick_value_in_list(['admin', 'user', 'guest'])
  User.new(name: name, age: age, score: score, role: role).validate!
end

Ruzzy.fuzz(test_one_input)

所有方法在数据耗尽时返回默认值(0、""、false、min)。

macOS 用户注意事项

macOS 上的 Ruzzy 需要 Homebrew 安装的 LLVM(Apple Clang 不包含 libFuzzer)和非系统 Ruby(位于 /usr/bin/ruby 的系统 Ruby 受 SIP 保护,会在 Ruby 启动前剥离 DYLD_* 环境变量)。

前提条件

root@kitploit:~
brew install llvm ruby

任何非系统 Ruby 都可以(brew、rbenv、asdf),但 shim 类型的版本管理器请参阅下面的注意事项。

安装

使用 Homebrew 的 Clang 路径和适用于 macOS 的链接器标志:

root@kitploit:~
MAKE="make --environment-overrides V=1" \
CC="$(brew --prefix llvm)/bin/clang" \
CXX="$(brew --prefix llvm)/bin/clang++" \
LDSHARED="$(brew --prefix llvm)/bin/clang -dynamic -bundle -undefined dynamic_lookup" \
LDSHAREDXX="$(brew --prefix llvm)/bin/clang++ -dynamic -bundle -undefined dynamic_lookup" \
    gem install ruzzy

运行

使用 DYLD_INSERT_LIBRARIES 代替 LD_PRELOAD:

root@kitploit:~
DYLD_INSERT_LIBRARIES=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby -e 'require "ruzzy"; Ruzzy.dummy'

在 macOS 上,Ruzzy::ASAN_PATH 和 Ruzzy::UBSAN_PATH 解析为 .dylib 文件。

注意事项

  • **版本管理器 shim(asdf、rbenv)会剥离 DYLD_* 环境变量。**这些 shim 使用 #!/usr/bin/env bash,而 /usr/bin/env 受 SIP 保护,因此 macOS 会在 Ruby 启动前剥离 DYLD_INSERT_LIBRARIES。要么使用 Homebrew Ruby(没有 shim),要么调用已安装 Ruby 二进制的绝对路径:
    root@kitploit:~
    DYLD_INSERT_LIBRARIES=$(/path/to/ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
        /path/to/ruby your_fuzzer.rb
    
  • **需要较新的 LLVM。**某些旧版本的 Homebrew LLVM(特别是 19.x)存在一个错误,即使用 DYLD_INSERT_LIBRARIES 注入 ASan dylib 会导致进程在启动时挂起。如果您看到 Ruzzy 在启动时挂起,请更新 Homebrew LLVM(brew upgrade llvm)。

成果案例

使用 Ruzzy 发现的漏洞:

  • toml gem: #76
  • toml-rb gem: #150
  • ox gem: #351, #410
  • Ruby Marshal garbage collector crash: #20941
  • XML parser differential: REXML vs. Nokogiri
  • redcarpet gem: #813

开发

可以在本地或使用本仓库提供的 Dockerfile 进行开发。

您可以使用以下命令构建 Ruzzy Docker 镜像:

root@kitploit:~
docker build --tag ruzzy .

然后,您可以使用以下命令进入容器:

root@kitploit:~
docker run -it -v $(pwd):/app/ruzzy --entrypoint /bin/bash ruzzy

编译

我们使用 rake-compiler 来编译 Ruzzy 的 C 扩展。

您可以使用以下命令在容器内编译 C 扩展:

root@kitploit:~
rake compile

测试

我们使用 rake 单元测试来测试 Ruby 代码。

您可以使用以下命令在容器内运行测试:

root@kitploit:~
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    rake test

代码检查

我们使用 rubocop 来检查 Ruby 代码的格式。

您可以使用以下命令在容器内运行 rubocop:

root@kitploit:~
rubocop

发布

当推送新的 git 标签时,Ruzzy 会自动发布到 RubyGems。

要发布新版本,请运行以下命令:

root@kitploit:~
git tag vX.X.X
root@kitploit:~
git push --tags

延伸阅读

  • Ruby C 扩展
    • https://guides.rubygems.org/gems-with-extensions/
    • https://www.rubyguides.com/2018/03/write-ruby-c-extension/
    • https://rubyreferences.github.io/rubyref/advanced/extensions.html
    • https://silverhammermba.github.io/emberb/c/
    • https://ruby-doc.org/3.3.0/extension_rdoc.html
    • https://ruby-doc.org/3.3.0/stdlibs/mkmf/MakeMakefile.html
    • https://github.com/flavorjones/ruby-c-extensions-explained
    • https://github.com/ruby/ruby/blob/v3_3_0/lib/mkmf.rb
  • Ruby 模糊测试
    • https://github.com/twistlock/kisaten
    • https://github.com/richo/afl-ruby
    • https://github.com/krypt/FuzzBert
    • https://z2-2z.github.io/2024/jan/16/fuzzing-ruby-c-extensions-with-coverage-and-asan.html
    • https://bsidessf2018.sched.com/event/E6jC/fuzzing-ruby-and-c-extensions
  • Atheris
    • https://github.com/google/atheris/blob/master/native_extension_fuzzing.md
    • https://security.googleblog.com/2020/12/how-atheris-python-fuzzer-works.html
    • https://github.com/google/atheris/blob/2.3.0/setup.py
    • https://github.com/google/atheris/blob/2.3.0/src/native/core.cc
下载工具
方法描述
Ruzzy.fuzz(test_one_input, args = DEFAULT_ARGS)对 test_one_input(一个接受原始字节的 proc/lambda)进行模糊测试。
Ruzzy.trace(harness_script)用 Ruby 分支覆盖率检测包装 harness_script,然后 require 它。纯 Ruby 模糊测试必需。
Ruzzy.dummy对捆绑的玩具驱动进行模糊测试(堆释放后使用演示)。
Ruzzy.dummy_test_one_input(data)玩具驱动本身。
常量描述
Ruzzy::ASAN_PATHASan + fuzzer 包装器的路径。与 LD_PRELOAD(Linux)/ DYLD_INSERT_LIBRARIES(macOS)一起使用。
Ruzzy::UBSAN_PATH同上,用于 UBSan。
Ruzzy::EXT_PATHext/cruzzy 构建目录的路径。
Ruzzy::DEFAULT_ARGS传递给模糊测试器的默认参数。
方法描述返回类型
remaining_bytes剩余未消费的字节数Integer
consume_bytes(count)消费最多 count 个原始字节二进制 String
consume_random_length_string(max_length)消费一个可变长度字符串;以 \ + 非 \ 字节终止String
consume_remaining_bytes消费所有剩余字节二进制 String
consume_remaining_as_stringconsume_remaining_bytes 的别名二进制 String
consume_uint(count)从 count 字节中获取无符号整数Integer
consume_int(count)从 count 字节中获取有符号(二进制补码)整数Integer
consume_int_in_range(min, max)在 [min, max] 范围内均匀分布的整数Integer
consume_bool从一个字节(最低有效位)获取布尔值true/false
consume_float跨越完整双精度范围的浮点数Float
consume_float_in_range(min, max)在 [min, max] 范围内的浮点数Float
consume_probability在 [0.0, 1.0] 范围内的浮点数Float
pick_value_in_list(list)从 list 中随机选取一个元素元素
  • https://github.com/google/atheris/blob/2.3.0/src/native/tracer.cc
  • https://github.com/google/atheris/blob/2.3.0/src/native/counters.cc
  • https://github.com/google/atheris/blob/2.3.0/src/instrument_bytecode.py
  • 覆盖率
    • https://calabi-yau.space/blog/sanitizer-coverage-interface.html
    • https://carstein.github.io/2020/05/21/writing-simple-fuzzer-4.html
    • https://h0mbre.github.io/Fuzzing-Like-A-Caveman-5/
    • https://github.com/mirrorer/afl/blob/master/docs/technical_details.txt
    • https://lcamtuf.coredump.cx/afl/historical_notes.txt
    • https://www.code-intelligence.com/blog/the-magic-behind-feedback-based-fuzzing
    • https://blog.includesecurity.com/2024/04/coverage-guided-fuzzing-extending-instrumentation/
    • https://git.sr.ht/~myrrc/ba-thesis/blob/master/thesis.pdf
    • https://www.politesi.polimi.it/bitstream/10589/173614/3/2021_04_Frighetto.pdf
    • https://wcventure.github.io/FuzzingPaper/Paper/SP18_ColLAFL.pdf
    • https://www.ndss-symposium.org/wp-content/uploads/2020/02/24422.pdf
    • https://mboehme.github.io/paper/ICSE22.pdf
    • https://www.usenix.org/system/files/raid2019-wang-jinghan.pdf