Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
ruzzy — 순수 Ruby 코드와 Ruby C 확장을 위한 커버리지 기반 퍼저 | Kitploit
도구/GitHubGitHub/trailofbits/ruzzy
Dynamic Analysis (Sandboxing)Vulnerability AnalysisCode AnalysisFuzzingBinary AnalysisLearning & Education
GitHubtrailofbits/ruzzy

ruzzy

순수 Ruby 코드와 Ruby C 확장을 위한 커버리지 기반 퍼저

저장소 보기
1237264개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Ruzzy

Test Gem Version

순수 Ruby 코드와 Ruby C 확장을 위한 커버리지 기반 퍼저입니다.

Ruzzy는 Python 퍼저인 Google의 Atheris에서 큰 영감을 받았습니다. Ruzzy는 커버리지 계측과 퍼징 엔진을 위해 libFuzzer(또는 LibAFL)를 사용합니다. 또한 Ruzzy는 C 확장을 퍼징할 때 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를 설치하세요:

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 기능을 사용할 수 있게 해 줍니다.

설치 중 문제가 발생하면 다음 명령어를 실행하여 디버깅 출력을 확인할 수 있습니다:

RUZZY_DEBUG=1 gem install --verbose ruzzy

순수 Ruby 퍼징 대상이 정규식을 많이 사용한다면 regexp_parser를 설치하세요:

gem install regexp_parser

설치 후 Ruzzy는 퍼징 중 만나는 정규식을 샘플링(즉, 해결)하기 위해 이 기능을 자동으로 사용합니다. 이를 통해 퍼저는 정규식 조건을 통과하여 추가 커버리지를 확보할 수 있습니다.

사용

시작하기

Ruzzy는 동작 방식을 보여주는 예제를 포함하고 있습니다. 먼저 다음 환경 변수를 설정하세요:

export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"
이 옵션들을 이해할 필요는 없지만, 궁금하다면 여기를 클릭하세요.

ASAN_OPTIONS

  1. 메모리 할당 실패는 흔하고 영향이 낮은(DoS) 문제이므로 일단 건너뜁니다.
  2. Python과 마찬가지로 Ruby 인터프리터도 데이터를 누출하므로 일단 무시합니다.
  3. Ruby는 sigaltstack 비활성화를 권장합니다.

그런 다음 다음 명령어로 예제를 실행할 수 있습니다:

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

LD_PRELOAD는 Atheris와 동일한 이유로 필요합니다. 그러나 ASAN_OPTIONS와 달리 다른 프로그램을 방해할 수 있으므로 export하지 않는 것이 좋습니다.

그러면 곧 다음과 같은 크래시가 생성됩니다:

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를 참조하세요.

다음 명령어로 크래시 케이스를 다시 실행할 수 있습니다:

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

다음과 같은 sanitizer를 사용할 수 있습니다:

  • Ruzzy::ASAN_PATH — AddressSanitizer용
  • Ruzzy::UBSAN_PATH — UndefinedBehaviorSanitizer용

순수 Ruby 코드 퍼징

예시로 작은 Ruby 스크립트를 퍼징해 보겠습니다. 순수 Ruby 코드를 퍼징하려면 트레이서 스크립트(tracer script)와 퍼징 하니스(fuzzing harness)라는 두 개의 Ruby 스크립트가 필요합니다. 트레이서 스크립트가 필요한 이유는 Ruby 인터프리터의 구현 세부 사항 때문입니다.

먼저 트레이서 스크립트를 작성합니다. 이름을 test_tracer.rb라고 하겠습니다:

# frozen_string_literal: true

require 'ruzzy'

Ruzzy.trace('test_harness.rb')

다음으로 퍼징 하니스를 작성합니다. 이름을 test_harness.rb라고 하겠습니다:

# 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)

다음 명령어로 이 파일을 실행하여 퍼징을 시작할 수 있습니다:

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

그러면 곧 다음과 같은 크래시가 생성됩니다:

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을 설치하세요:

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를 지정하고 있습니다. 이 플래그들은 퍼징 과정을 돕습니다. address sanitizer와 같은 유용한 기능과 개선된 스택 트레이스 정보를 활성화합니다. 자세한 내용은 AddressSanitizerFlags를 참조하세요.

다음으로 msgpack용 퍼징 하니스가 필요합니다. 아래 코드는 libFuzzer 경험이 있는 분들에게 익숙할 것입니다:

# 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라고 하겠습니다. 다음 명령어로 이 파일을 실행하여 퍼징을 시작할 수 있습니다:

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

libFuzzer 옵션은 다음과 같이 Ruby 스크립트에 전달할 수 있습니다:

도구 다운로드