퍼징(Fuzzing)은 자동으로 생성된 무작위/변형 입력을 프로그램에 공급하여 크래시, 메모리 오류, 예외 동작을 발견하는 자동화된 소프트웨어 테스팅 기법이다. AFL, libFuzzer, OSS-Fuzz 등이 대표적이다.
퍼징 분류
| 종류 | 방식 | 특징 |
|---|
| Blackbox | 프로그램 내부 무시, 완전 무작위 | 단순, 효율 낮음 |
| Greybox | 커버리지 피드백 활용 | AFL/libFuzzer 방식 |
| Whitebox | 소스 코드 분석 + 심볼릭 실행 | SAGE, KLEE |
AFL++ (커버리지 가이드 퍼저)
bash
# 설치
apt-get install afl++
# 계측(Instrumentation)으로 컴파일
CC=afl-gcc ./configure && make
# 시드 입력 준비
mkdir in && echo "test" > in/seed1
# 퍼징 실행
afl-fuzz -i in -o out -- ./target_binary @@
# ^^ 입력 파일 위치
# 결과 확인
ls out/crashes/ # 크래시 유발 입력
ls out/hangs/ # 무한 루프 유발 입력
# 커버리지 맵으로 새 경로 탐색 시 자동 seed 추가
libFuzzer (LLVM 기반)
c
// fuzz_target.c
# include <stdint.h>
# include <stddef.h>
// 퍼저가 반복 호출하는 진입점
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 4) return 0;
// 취약한 파서 (예시)
if (data[0] == 'F' && data[1] == 'U' &&
data[2] == 'Z' && data[3] == 'Z') {
// 버그: 경계 검사 없음
char buf[4];
memcpy(buf, data + 4, size - 4); // 오버플로우!
}
return 0;
}
// 컴파일
// clang -fsanitize=fuzzer,address fuzz_target.c -o fuzz
// ./fuzz -max_total_time=60
Sanitizer 조합
bash
# AddressSanitizer: 메모리 접근 오류
clang -fsanitize=fuzzer,address target.c
# UndefinedBehaviorSanitizer: 정의되지 않은 동작
clang -fsanitize=fuzzer,undefined target.c
# MemorySanitizer: 초기화되지 않은 메모리 읽기
clang -fsanitize=fuzzer,memory target.c
OSS-Fuzz
Google이 운영하는 오픈소스 프로젝트 퍼징 인프라
- 500개 이상 오픈소스 프로젝트 지속 퍼징
- 발견된 취약점 10,000개+ (OpenSSL, Chromium 등)
- 무료 (오픈소스 프로젝트 대상)
- ClusterFuzz 엔진 사용
관련 문서
- •[symbolic-execution|[심볼릭 실행]]
- •[[dynamic-analysis|동적 분석]]
- •[[property-based-testing|속성 기반 테스팅]]