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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
test-fuzz — Rust 매크로와 Cargo 하위 명령어로 afl.rs를 통한 퍼징을 자동화하는 도구로, 코퍼스 생성과 하네스 구현을 포함하며 Rust의 테스트 프레임워크와 통합됩니다. | Kitploit
도구/GitHubGitHub/trailofbits/test-fuzz
Dynamic Analysis (Sandboxing)Vulnerability AnalysisCode AnalysisFuzzing
GitHubtrailofbits/test-fuzz

test-fuzz

Rust 매크로와 Cargo 하위 명령어로 afl.rs를 통한 퍼징을 자동화하는 도구로, 코퍼스 생성과 하네스 구현을 포함하며 Rust의 테스트 프레임워크와 통합됩니다.

저장소 보기
210276710일 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
웹사이트

test-fuzz

test-fuzz는 [afl.rs]를 사용한 퍼징과 관련된 특정 작업을 자동화하는 Cargo 하위 명령이자 Rust 매크로 모음입니다. 여기에는 다음이 포함됩니다:

  • 퍼징 코퍼스 생성
  • 퍼징 하니스 구현

test-fuzz는 Rust의 테스트 기능을 사용하여 (부분적으로) 이러한 작업을 수행합니다. 예를 들어, 퍼징 코퍼스를 생성하기 위해 test-fuzz는 cargo test 실행 중 대상이 호출될 때마다 해당 대상의 인수를 기록합니다. 마찬가지로 test-fuzz는 cargo-test로 생성된 바이너리에서 퍼징 하니스를 추가 테스트로 구현합니다. Rust 테스트 기능과의 이러한 긴밀한 통합이 test-fuzz라는 이름의 동기가 되었습니다.

목차

  1. [설치]
  2. [개요]
  3. [구성 요소]
    • [test_fuzz 매크로]
    • [test_fuzz_impl 매크로]
    • [cargo test-fuzz 명령]
    • [편의 함수 및 매크로]
  4. [test-fuzz 패키지 기능]
  5. [자동 생성된 코퍼스 파일]
  6. [환경 변수]
  7. [제한 사항]
  8. [팁과 요령]
  9. [시맨틱 버전 관리 정책]
  10. [라이선스]

설치

다음 명령으로 cargo-test-fuzz와 [afl.rs]를 설치하세요:```sh cargo install cargo-test-fuzz cargo-afl

## 개요

`test-fuzz`를 사용한 퍼징은 기본적으로 세 단계로 이루어집니다:\*

1. **퍼징 타깃을 식별하세요**:
   - 대상 크레이트의 `Cargo.toml` 파일에 다음 `dependencies`를 추가하세요:
     ```toml
     serde = "*"
     test-fuzz = "*"
     ```
   - 대상 함수 앞에 [`test_fuzz`] 매크로를 추가하세요:
     ```rust
     #[test_fuzz::test_fuzz]
     fn foo(...) {
         ...
     }
     ```
2. `cargo test`를 실행하여 **코퍼스를 생성하세요**:   ```
   cargo test
  1. [cargo test-fuzz]를 실행하여 대상을 퍼징하세요: ``` cargo test-fuzz foo

* 재부팅 후 추가적인 사전 단계가 필요할 수 있습니다:```sh cargo afl system-config

위 명령은 내부적으로 `sudo`를 실행합니다. 따라서 비밀번호를 입력하라는 메시지가 표시될 수 있습니다.

## 구성 요소

### `test_fuzz` 매크로

함수 앞에 `test_fuzz` 매크로를 붙이면 해당 함수가 퍼즈 타깃(fuzz target)임을 나타냅니다.

`test_fuzz` 매크로의 주요 효과는 다음과 같습니다.

- 대상이 호출될 때마다 인수를 직렬화하여 코퍼스(corpus) 파일에 기록하도록 대상에 계측(instrumentation)을 추가합니다. 이 계측은 `#[cfg(test)]`로 보호되므로 테스트 실행 중에만 코퍼스 파일이 생성됩니다(단, 아래 [`enable_in_production`] 참조).
- 표준 입력에서 인수를 읽고 역직렬화하여 대상에 적용하는 테스트를 추가합니다. 이 테스트는 [`cargo test-fuzz`]가 설정한 환경 변수를 확인하므로, 일반적인 `cargo test` 실행 중에는 표준 입력을 읽기 위해 블로킹하지 않습니다. 이름 충돌 가능성을 줄이기 위해 테스트는 모듈 안에 포함됩니다. 현재 모듈 이름은 `target_fuzz`이며, 여기서 `target`은 대상의 이름입니다(단, 아래 [`rename`] 참조).

#### 인자

##### `bounds = "where_predicates"`

인수를 직렬화/역직렬화하는 데 사용되는 구조체에 `where_predicates`(예: 트레이트 바운드)를 적용합니다. 예를 들어 대상의 인수 타입이 연관 타입(associated type)인 경우 필요할 수 있습니다. 예시는 이 저장소의 [associated_type.rs]를 참조하세요.

##### `generic_args = "parameters"`

퍼징할 때 대상의 타입 매개변수로 `parameters`를 사용합니다. 예시:```rust
#[test_fuzz(generic_args = "String")]
fn foo<T: Clone + Debug + Serialize>(x: &T) {
    ...
}

참고: 대상의 인자는 타입 매개변수의 모든 인스턴스화에 대해 직렬화 가능해야 합니다. 그러나 대상의 인자가 역직렬화 가능해야 하는 것은 대상이 parameters로 인스턴스화될 때뿐입니다.

impl_generic_args = "parameters"

퍼징 시 parameters를 대상의 Self 타입 매개변수로 사용하세요. 예:```rust #[test_fuzz_impl] impl<T: Clone + Debug + Serialize> for Foo { #[test_fuzz(impl_generic_args = "String")] fn bar(&self, x: &T) { ... } }

참고: 대상의 인자는 `Self` 타입 매개변수의 **모든** 인스턴스화에 대해 직렬화 가능해야 합니다. 그러나 대상의 인자가 역직렬화 가능해야 하는 것은 대상의 `Self`가 `parameters`로 인스턴스화될 때뿐입니다.

##### `convert = "X, Y"`

대상의 인자를 직렬화할 때, `Y`의 `From<X>` 구현을 사용하여 타입 `X`의 값을 타입 `Y`로 변환하거나, 비표준 트레이트 `test_fuzz::FromRef<X>`에 대한 `Y`의 구현을 사용하여 타입 `&X`의 값을 타입 `Y`로 변환합니다. 역직렬화할 때는 비표준 트레이트 `test_fuzz::Into<X>`에 대한 `Y`의 구현을 사용하여 해당 값을 타입 `X`로 다시 변환합니다.

즉, `convert = "X, Y"`를 사용하려면 특정 구현이 함께 있어야 합니다. `X`가 [`Clone`]을 구현한다면, `Y`는 다음을 구현할 수 있습니다:```rust
impl From<X> for Y {
    fn from(x: X) -> Self {
        ...
    }
}

만약 X가 [Clone]을 구현하지 않는다면, Y는 다음을 구현해야 합니다:```rust impl test_fuzz::FromRef for Y { fn from_ref(x: &X) -> Self { ... } }

추가로, `Y`는 (`X`가 [`Clone`]을 구현하는지 여부와 관계없이) 다음을 구현해야 합니다:```rust
impl test_fuzz::Into<X> for Y {
    fn into(self) -> X {
        ...
    }
}

test_fuzz::Into의 정의는 [std::convert::Into]의 정의와 동일합니다. 표준이 아닌 트레이트를 사용하는 이유는 표준 트레이트의 포괄 구현(blanket implementations)에서 발생할 수 있는 충돌을 피하기 위해서입니다.

enable_in_production

테스트를 실행 중이 아닐 때도 [TEST_FUZZ_WRITE] 환경 변수가 설정되어 있으면 코퍼스 파일을 생성합니다. 기본값은 [TEST_FUZZ_WRITE] 설정 여부와 관계없이 테스트 실행 시에만 코퍼스 파일을 생성하는 것입니다. 패키지 디렉터리 밖에서 타깃을 실행하는 경우 [TEST_FUZZ_MANIFEST_PATH]를 패키지의 Cargo.toml 파일 경로로 설정하세요.

경고: enable_in_production을 설정하면 서비스 거부(denial-of-service) 벡터가 발생할 수 있습니다. 예를 들어, 다양한 인수로 여러 번 호출되는 함수에 이 옵션을 설정하면 디스크가 가득 찰 수 있습니다. [TEST_FUZZ_WRITE] 검사는 이러한 가능성에 대한 일부 방어를 제공하기 위한 것입니다. 그럼에도 불구하고 이 옵션을 사용하기 전에 신중히 고려하십시오.

execute_with = "function"

타깃을 직접 호출하는 대신:

  • FnOnce() -> R 유형의 클로저를 구성합니다. 여기서 R은 타깃의 반환 유형이며, 클로저를 호출하면 타깃이 호출됩니다.
  • 해당 클로저로 function을 호출합니다.

이렇게 타깃을 호출하면 function이 호출 환경을 설정할 수 있습니다. 예를 들어 [Substrate externalities]를 퍼징할 때 유용할 수 있습니다.

no_auto_generate

타깃에 대해 [auto-generate corpus files]를 시도하지 않습니다.

only_generic_args

테스트 실행 중 타깃의 제네릭 인자를 기록하되, 코퍼스 파일을 생성하지 않고 퍼징 하네스도 구현하지 않습니다. 이는 타깃이 제네릭 함수인데 퍼징에 사용할 타입 매개변수가 무엇인지 불분명할 때 유용할 수 있습니다.

의도된 워크플로는 다음과 같습니다: only_generic_args를 활성화한 다음 cargo test를 실행하고 이어서 cargo test-fuzz --display generic-args를 실행합니다. 결과로 나온 제네릭 인자 중 하나가 generic_args의 parameters로 사용할 수 있을 수 있습니다. 마찬가지로 cargo test-fuzz --display impl-generic-args의 결과로 나온 제네릭 인자는 impl_generic_args의 parameters로 사용할 수 있을 수 있습니다.

그러나 테스트 중 특정 매개변수로 타깃이 호출되었다고 해서 해당 매개변수를 사용할 때 타깃의 인수가 직렬화/역직렬화 가능하다는 의미는 아닙니다. --display generic-args/--display impl-generic-args의 결과는 단지 참고용일 뿐입니다.

rename = "name"

타깃을 둘러싼 범위에 모듈을 추가할 때 타깃의 이름이 name인 것처럼 취급합니다. test_fuzz 매크로의 확장은 둘러싼 범위에 모듈 정의를 추가합니다. 기본적으로 모듈 이름은 다음과 같이 지정됩니다:

  • 타깃이 impl 블록에 나타나지 않으면 모듈 이름은 target_fuzz__이며, 여기서 target은 타깃의 이름입니다.
  • 타깃이 impl 블록에 나타나면 모듈 이름은 path_target_fuzz__이며, 여기서 path는 impl의 Self 유형 경로의 마지막 세그먼트입니다.

그러나 이 옵션을 사용하면 모듈 이름이 대신 name_fuzz__가 됩니다. 예:```rust #[test_fuzz(rename = "bar")] fn foo() {}

// Without the use of rename, a name collision and compile error would result. mod foo_fuzz__ {}

#### 함수 인자에 대한 Serde 필드 속성

`test_fuzz` 매크로는 [Serde 필드 속성]을 함수 인자에 적용할 수 있게 해줍니다. 이는 다루기 어려운 타입을 처리하는 또 다른 도구를 제공합니다.

다음은 예시입니다. `Context`는 `Mutex`를 포함하기 때문에 `serde::Serialize` 및 `serde::Deserialize` 트레이트를 파생할 수 없습니다. 그러나 `Context`는 `Default`를 구현합니다. 따라서 `Context` 인자에 `#[serde(skip)]`을 적용하면 직렬화할 때 해당 인자가 생략되고, 역직렬화할 때 기본값을 사용하게 됩니다.```rust
use std::sync::Mutex;

// Traits `serde::Serialize` and `serde::Deserialize` cannot be derived for `Context` because it
// contains a `Mutex`.
#[derive(Default)]
struct Context {
    lock: Mutex<()>,
}

impl Clone for Context {
    fn clone(&self) -> Self {
        Self {
            lock: Mutex::new(()),
        }
    }
}

#[test_fuzz::test_fuzz]
fn target(#[serde(skip)] context: Context, x: i32) {
    assert!(x >= 0);
}

Serde 필드 속성이 인자에 적용되면 test_fuzz 매크로는 해당 인자에 대해 다른 [변환]을 수행하지 않습니다.

test_fuzz_impl 매크로

[test_fuzz] 매크로가 impl 블록에서 사용될 때마다, impl 앞에 반드시 test_fuzz_impl 매크로가 와야 합니다. 예시:```rust #[test_fuzz_impl] impl Foo { #[test_fuzz] fn bar(&self, x: &str) { ... } }

이 요구 사항의 이유는 다음과 같습니다. `test_fuzz` 매크로의 확장은 포함하는 범위에 모듈 정의를 추가합니다. 그러나 모듈 정의는 `impl` 블록 내부에 나타날 수 없습니다. `impl` 앞에 `test_fuzz_impl` 매크로를 배치하면 모듈이 `impl` 블록 외부에 추가됩니다.

다음과 같은 오류가 표시된다면 `test_fuzz_impl` 매크로 사용이 누락되었음을 의미할 가능성이 높습니다:```
error: module is not supported in `trait`s or `impl`s

test_fuzz_impl 현재 옵션이 없습니다.

cargo test-fuzz 명령

cargo test-fuzz 명령은 퍼즈 타겟과 상호 작용하고 해당 코퍼스(corpora), 크래시(crashes), 행(hangs), 작업 큐(work queues)를 조작하는 데 사용됩니다. 호출 예는 다음과 같습니다:

  1. 퍼즈 타겟 나열 ``` cargo test-fuzz --list
  2. 대상 foo의 코퍼스 표시 ``` cargo test-fuzz foo --display corpus
  3. 퍼즈 대상 foo ``` cargo test-fuzz foo
  4. 대상 foo에 대해 발견된 크래시 재생 ``` cargo test-fuzz foo --replay crashes

사용법```

Usage: cargo test-fuzz [OPTIONS] [TARGETNAME] [-- ...]

Arguments: [TARGETNAME] String that fuzz target's name must contain [ARGS]... Arguments for the fuzzer

도구 다운로드