취약점분석/Fuzzing

[Fuzzing] AFL++ Fuzzing

poiri3r 2026. 1. 8. 15:15

안녕하세요! 오늘 포스팅 할 주제는 Fuzzing입니다.

퍼징은 소프트웨어 테스팅 기법으로, 무작위 또는 예상치 못한 데이터를 프로그램에 대량으로 주입하여 충돌, 메모리 누수와 같은 동작이나 보안 취약점, 버그를 찾아내는 자동화된 기법입니다.

저도 잘 모르기 때문에 오늘은 이론적인 부분보다는 실습을 한번 해보도록 하겠습니다.

 

먼저 설치입니다. 다음 명령어로 설치 가능합니다.

sudo apt install afl++

 

그리고 입력값을 찾아내면 abort가 발생하는 취약한 코드를 만들어보겠습니다.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    char buf[100];

    if (read(0, buf, 100) < 0) return 1;

    // F -> U -> Z -> Z 순서로 들어오는지 검사
    if (buf[0] == 'F') {
        if (buf[1] == 'U') {
            if (buf[2] == 'Z') {
                if (buf[3] == 'Z') {
                     abort(); 
                }
            }
        }
    }
    return 0;
}

 

위의 C코드는 FUZZ이라는 글자가 들어오면 abort가 발생합니다.

gcc로 컴파일 해주겠습니다.

위의 명령어를 사용하면 afl에서 제공하는 gcc로 컴파일 가능합니다.

mkdir input output

 

input과 output이라는 디렉토리를 만들어주고, 

echo "AAAA" > input/seed.txt

 

그 안에 seed.txt라는 파일을 만들고 아무런 글자나 넣어줍니다.

이 시드 파일의 경우 mutant를 생성하는 파일이므로, 만약에 PDF 뷰어를 퍼징해야할 경우, 정상적인 PDF파일을 시드로 넣어줘야 합니다.

 

input 디렉토리는 반드시 하나 이상의 파일이 들어있어야 하고,

output 디렉토리도 결과물이 저장되므로 필수적인 디렉토리입니다.

afl-fuzz -i input -o output ./vuln_fuzzer

위 명령어는 퍼징을 시작하는 명령어로 -i로 input파일을 -o로 output파일을 지정해줘야 합니다.

시작하면 다음과 같은 화면이 뜨게됩니다.

위의 경고는 WSL 환경이어서 뜨는 경고로, 실제 리눅스 컴퓨터를 사용하면 CPU 속도를 AFL이 직접 조절하지만, WSL에서는 AFL이 속도를 조절하기 때문에 뜨는 경고입니다.

나중에 컴퓨터나 노트북에 리눅스로 운영체제를 깔아봐야겠네요

하나하나씩 설명을 해보겠습니다.

가장 중요한 결과입니다.

  • cycles done : 퍼저가 준비 된 입력값을 돌렸는지
  • saved crashes : 해킹에 성공한 입력값의 개, 1이상이면 퍼징을 멈춰도 됩니다.
  • saved hangs : 프로그램이 멈추거나 무한 루프에 빠진 횟수 (버그의 일종)

 

퍼징 진행 시간이나, 마지막으로 찾은 crash의 시간 등 정보를 보여줍니다.

 

  • cycle processing은 
  • now trying : 현재 공격 방식으로, havoc은 대혼란 모드입니다. 입력값을 마구잡이로 자르고, 붙이고, 랜덤한 숫자를 끼워넣는 공격 방식을 havoc이라고 합니다.
  • stage execs는 현재 진행중인 havoc에서 진행할 변종 개수와 퍼센테이지를 보여줍니다. 이 숫자가 100%가 되면 다음 전략이나 다음 입력값으로 넘어갑니다.
  • total execs는 총 실행 개수로, 퍼저를 켠 순간부터 지금까지 94300번 시도했음을 보여줍니다.
  • exec speed는 초당 공격 속도인데, 현재 초당 179.9를 시도하는데, 보통 리눅스 네이티브에선 2000/sec 이상 나온다네요.

finding in depth는 퍼저가 찾아낸 유의미한 결과값을 나타냅니다.

total crashes는 총 442번인데, 다 같은 이유로 크래시가 났기에 1개의 유니크 파일만 저장했네요.

FUZZ + @의 겹치는 조합은 하나만 저장합니다.

이제 output 디렉토리를 확인해보러 가겠습니다.

 

여기서 가장 중요한 디렉토리는 crashes입니다

안에 들어가면 저장된 결과물이 있고 한번 읽어보면

다음과 같은 문자열이 저장되어 있습니다ㅡ.

FUZZ라는 문자열이 그대로 저장된 걸 확인 가능합니다.

 

다음은 queue를 확인해보겠습니다

queue는 크래시를 내진 못했어도 새로운 코드 경로를 발견한 의미 있는 입력값들이 모여 있는 코드입니다.

3가지 파일이 저장되어 있는데 확인해보겠습니다.

 

1,2,3번 파일을 보면 확인 가능한데, 저희의 if문은 F U Z Z를 따로 검사합니다. if문 분기가 갈라지는데, 퍼저가 한글자씩 찾을때마다 queue에 저장됩니다.

 

마지막으로 fuzzer_stats에는 

아까 화면에 떴던 스탯들을 확인 가능합니다.

이상으로 퍼징에 관해 간단한 실습을 마쳐보겠습니다. 

아직은 비밀번호를 뚫는 것 밖에 안해보았지만, 단순 비밀번호를 뚫는건 angr가 확실히 좋아보이긴 합니다.

하지만 angr에 비해서는 훨씬 돌리는게 가볍고, 메모리 커럽션을 찾아낼 수 있다는건 큰 장점인 것 같네요.

 

이상으로 1차 포스팅을 마치겠습니다.

다음 포스팅이 뭐가 될지 모르겠는데, 하이브리드 퍼징에 관한 논문도 읽고 있어서 더 깊이 있게 fuzzer를 보지 않을까 싶습니다.

읽어주셔서 감사합니다~

 

 

'취약점분석 > Fuzzing' 카테고리의 다른 글

Hybrid Fuzzing - 2 ( SymCC + AFL )  (0) 2026.01.15
Hybrid Fuzzing - 1 ( 실패일지 )  (0) 2026.01.15
SymCC Fuzzing - 1 ( Symbolic executor )  (0) 2026.01.11
[Fuzzing] Boofuzz Fuzzing  (0) 2026.01.09