Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
ruzzy — Ein abdeckungsgesteuerter Fuzzer für reinen Ruby-Code und Ruby-C-Erweiterungen. | Kitploit
Tools/GitHubGitHub/trailofbits/ruzzy
Dynamische Analyse (Sandboxing)SchwachstellenanalyseCode-AnalyseFuzzingBinäranalyseLernen & Bildung
GitHubtrailofbits/ruzzy

ruzzy

Ein abdeckungsgesteuerter Fuzzer für reinen Ruby-Code und Ruby-C-Erweiterungen.

Repository anzeigen
12374vor 2 MonatenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Ruzzy

Test Gem Version

Ein coverage-gesteuerter Fuzzer für reinen Ruby-Code und Ruby-C-Erweiterungen.

Ruzzy ist stark von Googles Atheris inspiriert, einem Python-Fuzzer. Ruzzy verwendet libFuzzer (oder LibAFL) für seine Coverage-Instrumentierung und als Fuzzing-Engine. Ruzzy unterstützt beim Fuzzing von C-Erweiterungen außerdem AddressSanitizer und UndefinedBehaviorSanitizer. Wenn Sie mehr über die Inspiration hinter Ruzzy erfahren möchten, lesen Sie unser Paper: Design and Implementation of a Coverage-Guided Ruby Fuzzer.

Inhaltsverzeichnis:

  • Installation
  • Verwendung
    • Erste Schritte
    • Fuzzing von reinem Ruby-Code
    • Fuzzing von Ruby-C-Erweiterungen
  • API
    • Ruzzy
    • FuzzedDataProvider
  • Hinweise für macOS-Benutzer
  • Trophäensammlung
  • Entwicklung
Tool herunterladen
  • Kompilieren
  • Testen
  • Linting
  • Veröffentlichen
  • Weiterführende Literatur
  • Installation

    Ruzzy unterstützt Linux (x86-64, AArch64/ARM64) und macOS (Apple Silicon). Unter Windows können Sie das Dockerfile erstellen und/oder die Entwicklungsumgebung nutzen. Ruzzy benötigt eine aktuelle Version von clang (getestet ab 14.0.0), vorzugsweise die neueste Version. Informationen zur macOS-spezifischen Einrichtung finden Sie unter Hinweise für macOS-Benutzer.

    Installieren Sie Ruzzy mit dem folgenden Befehl:

    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
    

    Hier passiert einiges; schauen wir uns das einmal genauer an:

    • Die Umgebungsvariable MAKE überschreibt den make-Befehl beim Kompilieren der Ruzzy-C-Erweiterung. Dadurch wird make angewiesen, die nachfolgenden Umgebungsvariablen beim Kompilieren der Erweiterung zu berücksichtigen.
    • Die übrigen Umgebungsvariablen werden während der Kompilierung verwendet, um sicherzustellen, dass die richtigen clang-Binaries zum Einsatz kommen. So wird gewährleistet, dass die neuesten clang-Funktionen verfügbar sind, die für ein ordnungsgemäßes Fuzzing erforderlich sind.

    Sollten beim Installieren Probleme auftreten, können Sie den folgenden Befehl ausführen, um Debug-Ausgaben zu erhalten:

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

    Wenn Ihr Fuzzing-Ziel für reinen Ruby-Code stark auf Regexps setzt, installieren Sie regexp_parser:

    root@kitploit:~
    gem install regexp_parser
    

    Nach der Installation nutzt Ruzzy diese Funktionalität automatisch, um Regexps, auf die es beim Fuzzing stößt, zu sampeln (d. h. zu lösen). Dadurch kann der Fuzzer an Regexp-Bedingungen vorbeigelangen und zusätzliche Coverage freischalten.

    Verwendung

    Erste Schritte

    Ruzzy enthält ein Toy-Beispiel, um zu demonstrieren, wie es funktioniert. Setzen Sie zunächst die folgende Umgebungsvariable:

    root@kitploit:~
    export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"
    
    Es ist nicht nötig, diese Optionen zu verstehen, aber wenn Sie neugierig sind, klicken Sie hier.

    ASAN_OPTIONS

    1. Speicherallokierungsfehler sind häufig und haben geringe Auswirkungen (DoS); überspringen Sie sie daher vorerst.
    2. Wie Python leakt auch der Ruby-Interpreter Daten; ignorieren Sie dies daher vorerst.
    3. Ruby empfiehlt, sigaltstack zu deaktivieren.

    Anschließend können Sie das Beispiel mit dem folgenden Befehl ausführen:

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

    LD_PRELOAD wird aus denselben Gründen benötigt wie bei Atheris. Anders als ASAN_OPTIONS sollten Sie es jedoch wahrscheinlich nicht per export setzen, da es andere Programme stören kann.

    Es sollte schnell einen Absturz wie den folgenden erzeugen:

    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=
    

    Wir können sehen, dass die Eingabe ("HI") korrekt gefunden wurde, die eine Speicherverletzung verursacht hat. Weitere Informationen dazu, warum diese Verletzung aufgetreten ist, finden Sie in dummy.c.

    Sie können den Absturzfall mit dem folgenden Befehl erneut ausführen:

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

    Die folgenden Sanitizer sind verfügbar:

    • Ruzzy::ASAN_PATH für AddressSanitizer
    • Ruzzy::UBSAN_PATH für UndefinedBehaviorSanitizer

    Fuzzing von reinem Ruby-Code

    Fuzzen wir als Beispiel ein kleines Ruby-Skript. Das Fuzzing von reinem Ruby-Code erfordert zwei Ruby-Skripte: ein Tracer-Skript und eine Fuzzing-Harness. Das Tracer-Skript ist aufgrund eines Implementierungsdetails des Ruby-Interpreters erforderlich.

    Zuerst das Tracer-Skript; nennen wir es test_tracer.rb:

    root@kitploit:~
    # frozen_string_literal: true
    
    require 'ruzzy'
    
    Ruzzy.trace('test_harness.rb')
    

    Als Nächstes die Fuzzing-Harness; nennen wir sie 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)
    

    Sie können diese Datei ausführen und mit dem folgenden Befehl das Fuzzing starten:

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

    Es sollte schnell einen Absturz wie den folgenden erzeugen:

    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==
    

    Wir können sehen, dass die Eingabe ("FUZZ") korrekt gefunden wurde, die eine Ausnahme verursacht hat.

    Um Ihr eigenes Ziel zu fuzzen, ändern Sie das test_one_input-lambda, sodass es Ihre Zielfunktion aufruft.

    Fuzzing von Ruby-C-Erweiterungen

    Fuzzen wir als Beispiel die Bibliothek msgpack-ruby. Installieren Sie zunächst das 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
    

    Zusätzlich zu den Umgebungsvariablen, die beim Kompilieren von Ruzzy verwendet werden, geben wir CFLAGS und CXXFLAGS an. Diese Flags unterstützen den Fuzzing-Prozess. Sie aktivieren nützliche Funktionen wie einen Address Sanitizer und verbesserte Stack-Trace-Informationen. Weitere Informationen finden Sie unter AddressSanitizerFlags.

    Als Nächstes benötigen wir eine Fuzzing-Harness für msgpack. Das Folgende dürfte denen bekannt vorkommen, die Erfahrung mit libFuzzer haben:

    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)
    

    Nennen wir diese Datei fuzz_msgpack.rb. Sie können diese Datei ausführen und mit dem folgenden Befehl das Fuzzing starten:

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

    libFuzzer-Optionen können wie folgt an das Ruby-Skript übergeben werden:

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

    Weitere Informationen finden Sie unter libFuzzer-Optionen.

    Um Ihr eigenes Ziel zu fuzzen, ändern Sie das test_one_input-lambda, sodass es Ihre Zielfunktion aufruft.

    API

    Das Modul Ruzzy stellt die zentralen Einstiegspunkte bereit.

    MethodeBeschreibung
    Ruzzy.fuzz(test_one_input, args = DEFAULT_ARGS)Fuzzt test_one_input (ein proc/lambda, das rohe Bytes entgegennimmt).
    Ruzzy.trace(harness_script)Umhüllt harness_script mit Ruby-Branch-Coverage-Instrumentierung und lädt es anschließend per require. Erforderlich für reines Ruby-Fuzzing.
    Ruzzy.dummyFuzzt die mitgelieferte Beispiel-Harness (Heap-use-after-free-Demo).
    Ruzzy.dummy_test_one_input(data)Die Beispiel-Harness selbst.
    KonstanteBeschreibung
    Ruzzy::ASAN_PATHPfad zum ASan- und Fuzzer-Wrapper. Verwendung mit LD_PRELOAD (Linux) / DYLD_INSERT_LIBRARIES (macOS).
    Ruzzy::UBSAN_PATHDasselbe für UBSan.
    Ruzzy::EXT_PATHPfad zum Build-Verzeichnis ext/cruzzy.
    Ruzzy::DEFAULT_ARGSStandardargumente, die an den Fuzzer übergeben werden.

    FuzzedDataProvider

    Ruzzy::FuzzedDataProvider zerteilt rohe Fuzzer-Bytes in typisierte Ruby-Werte.

    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)
    
    MethodeBeschreibungRückgabe
    remaining_bytesAnzahl der verbleibenden, noch nicht konsumierten BytesInteger
    consume_bytes(count)Konsumiert bis zu count rohe Bytesbinäre String
    consume_random_length_string(max_length)Konsumiert eine Zeichenkette variabler Länge; endet bei \ + Nicht-\-ByteString
    consume_remaining_bytesKonsumiert alle verbleibenden Bytesbinäre String
    consume_remaining_as_stringAlias für consume_remaining_bytesbinäre String
    consume_uint(count)Vorzeichenlose Ganzzahl aus count BytesInteger
    consume_int(count)Vorzeichenbehaftete (Zweierkomplement-)Ganzzahl aus count BytesInteger
    consume_int_in_range(min, max)Gleichverteilte Ganzzahl in [min, max]Integer
    consume_boolBoolescher Wert aus einem Byte (LSB)true/false
    consume_floatFloat über den gesamten Double-BereichFloat
    consume_float_in_range(min, max)Float in [min, max]Float
    consume_probabilityFloat in [0.0, 1.0]Float
    pick_value_in_list(list)Zufälliges Element aus list

    Alle Methoden geben Standardwerte (0, "", false, min) zurück, wenn die Daten erschöpft sind.

    Hinweise für macOS-Benutzer

    Ruzzy erfordert unter macOS ein per Homebrew installiertes LLVM (Apple Clang enthält kein libFuzzer) sowie ein Nicht-System-Ruby (das System-Ruby unter /usr/bin/ruby ist SIP-geschützt, wodurch die DYLD_*-Umgebungsvariablen entfernt werden, bevor Ruby startet).

    Voraussetzungen

    root@kitploit:~
    brew install llvm ruby
    

    Jedes Nicht-System-Ruby funktioniert (brew, rbenv, asdf); beachten Sie jedoch die Einschränkungen unten für Shim-basierte Versionsmanager.

    Installation

    Verwenden Sie die Homebrew-Clang-Pfade und die für macOS geeigneten Linker-Flags:

    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
    

    Ausführen

    Verwenden Sie DYLD_INSERT_LIBRARIES anstelle von LD_PRELOAD:

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

    Ruzzy::ASAN_PATH und Ruzzy::UBSAN_PATH verweisen unter macOS auf .dylib-Dateien.

    Einschränkungen

    • Version-Manager-Shims (asdf, rbenv) entfernen DYLD_*-Umgebungsvariablen. Diese Shims verwenden #!/usr/bin/env bash, und /usr/bin/env ist SIP-geschützt, weshalb macOS DYLD_INSERT_LIBRARIES entfernt, bevor Ruby startet. Verwenden Sie entweder Homebrew-Ruby (das keinen Shim hat) oder rufen Sie den absoluten Pfad zur installierten Ruby-Binärdatei auf:
      root@kitploit:~
      DYLD_INSERT_LIBRARIES=$(/path/to/ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
          /path/to/ruby your_fuzzer.rb
      
    • Aktuelles LLVM erforderlich. Einige ältere Versionen von Homebrew-LLVM (insbesondere 19.x) haben einen Fehler, bei dem das Setzen von DYLD_INSERT_LIBRARIES auf die ASan-dylib den Prozess beim Start aufhängt. Wenn Ruzzy beim Start hängen bleibt, aktualisieren Sie Homebrew-LLVM (brew upgrade llvm).

    Trophäensammlung

    Mit Ruzzy gefundene Fehler:

    • toml-Gem: #76
    • toml-rb-Gem: #150
    • ox-Gem: #351, #410
    • Ruby-Marshal-Garbage-Collector-Absturz: #20941
    • XML-Parser-Differential: REXML vs. Nokogiri
    • redcarpet-Gem: #813

    Entwicklung

    Die Entwicklung kann lokal oder mithilfe des in diesem Repository bereitgestellten Dockerfile erfolgen.

    Sie können das Ruzzy-Docker-Image mit dem folgenden Befehl erstellen:

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

    Anschließend können Sie mit dem folgenden Befehl eine Shell im Container öffnen:

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

    Kompilieren

    Wir verwenden rake-compiler, um die C-Erweiterungen von Ruzzy zu kompilieren.

    Sie können die C-Erweiterungen im Container mit dem folgenden Befehl kompilieren:

    root@kitploit:~
    rake compile
    

    Testen

    Wir verwenden rake-Unit-Tests, um den Ruby-Code zu testen.

    Sie können die Tests im Container mit dem folgenden Befehl ausführen:

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

    Linting

    Wir verwenden rubocop, um den Ruby-Code zu linten.

    Sie können rubocop im Container mit dem folgenden Befehl ausführen:

    root@kitploit:~
    rubocop
    

    Veröffentlichen

    Ruzzy wird automatisch auf RubyGems veröffentlicht, wenn ein neuer Git-Tag gepusht wird.

    Um eine neue Version zu veröffentlichen, führen Sie die folgenden Befehle aus:

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

    Weiterführende Literatur

    • Ruby-C-Erweiterungen
      • 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-Fuzzing
      • 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
      • 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
    • Coverage
      • 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
    Element