취약점분석/Fuzzing

Hybrid Fuzzing - 1 ( 실패일지 )

poiri3r 2026. 1. 15. 15:17

안녕하세요.

오늘 포스팅 할 주제는 저번에 이은 SymCC Fuzzing입니다.

이번에는 AFL++와 결합해서 하이브리드 퍼징을 하는 식으로 진행을 해볼 것이고, 다시 데스크탑 컴퓨터로 왓기 때문에 환경구성부터 다시해주겠습니다.

AFL++은 로컬에 깔려있는데 SymCC는 로컬로 설치가 안되어 있어서 SymCC를 먼저 git으로 로컬에 설치해 주었습니다.

git clone https://github.com/eurecom-s3/symcc.git

 

그 다음 다운로드된 dockerfile을 수정하여  안에 AFL++이 추가되게 수정하였습니다.

Dockerfile
0.00MB

필요하신 분은 다운로드 받아서 이미지 빌드하시면 될 것 같습니다.

sudo docker build -t symcc .

 

symcc랑 afl++ --help 명령어가 잘 먹히는지 확인합니다.

 

이번에도 환경 구성에 애를 좀 먹고 있는데, 어제도 카페에서 한 2시간동안 스트레스 받아가면서 한 것 같은데 넘 어렵네요 ..

 

일단 바이너리를 두가지 방법으로 컴파일을 해줘야합니다.

하나는 AFl용이고 하나는 symCC용도입니다.

 

# 컴파일러: afl-cc
afl-cc -o vuln_afl vuln.c
export SYMCC_OUTPUT_DIR=/tmp/symcc_out
# 컴파일러: symcc
/symcc_build/symcc -o vuln_sym vuln.c

 

취약점이 있는 코드는 저번에 symCC할때 만들었던 코드를 그대로 사용하였습니다.

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

void complex_loop(unsigned int *val, int iterations) {
    // 경로 폭발 유도: 반복문 내부에 조건부 연산을 넣어 
    // 정적 분석 도구가 탐색해야 할 경로를 기하급수적으로 늘림
    for (int i = 0; i < iterations; i++) {
        if ((*val) % 2 == 0) {
            *val = (*val >> 1) + 0x1337;
        } else {
            *val = (*val * 3) + 1;
        }
    }
}

int main() {
    unsigned int magic1, magic2;
    char buf[16];

    // 1단계: 4바이트 읽기 (Magic Value)
    if (read(0, &magic1, 4) < 4) return 0;
    
    // magic value check로 fuzzer의 연산을 방해
    if (magic1 == 0xdeadbeef) {
        printf("[1단계 통과]\n");

        // 2단계: 경로 폭발 구간
        if (read(0, &magic2, 4) < 4) return 0;
        unsigned int temp = magic2;
        // complex_loop로 경로폭발 유도
        complex_loop(&temp, 10); 

        // 루프를 돌고 난 결과값이 특정값이어야 함 (역산이 매우 힘듦)
        if (temp == 0x12345678) {
            printf("[2단계 통과]!\n");

            // 3단계: 문자열 비교
            if (read(0, buf, 4) < 4) return 0;
            if (memcmp(buf, "HACK", 4) == 0) {
                printf("[최종 성공]\n");
                abort();
            }
        }
    }
    return 0;
}

 

 

vuln_afl과 vuln파일이 있고, vuln은 symCC를 위한 테스트기입니다.

일단 터미널을 두개 열거나, tmux를 사용해서 창을 두개 띄워야합니다. 하나는 AFL 하나는 symCC용입니다.

그리고 AFL++을 돌릴 터미널에서 저번에 AFL실습때 한것처럼 input, output을 만든 뒤 seed파일을 넣어둡니다.

 

 

afl--fuzz help를 치면 다음과 같은 모드가 있습니다.

Master모드는 병렬 퍼징을 수행할때 사용하는 모드입니다. Master 모드에서는 비교적 느리지만 Deterministic방식으로 순차적/논리적 변형을 사용하고, -S옵션을 주면 상대적으로 빠르지만 Havoc/Random모드로 탐색합니다.

 

하이브리드 퍼징에서는 AFL이 기본적인 변형을 가하며 퍼징을 주도하고, SymCC는 보조역할을 하기 때문에 Afl이 퍼징하는 쉘에서 -M 모드로 실행해줍니다.

afl-fuzz -M afl_master -i in -o out ./vuln_afl

 

 

한쪽 터미널은 위와 같이 띄워뒀습니다.

 

그리고 여기서 SymCC가 보조를 해야하기 때문에 다른 터미널로는 symCC로 컴파일한 바이너리를 찾아줘야 합니다.

symcc에는 symcc_fuzzing_helper라는 파일이 있는데 해당 스크립트는 AFL과의 호환을 도와주는 스크립트입니다.

옵션에 -a에 fuzzer name을 적으면 되는데 아까 afl_master라고 만들었기 때문에 그걸 넣어두면 됩니다.

 

/symcc_build/symcc_fuzzing_helper -o output -a afl_master -n symcc -- ./vuln_sym

 

 

구조를 살펴보면 AFL++이 퍼징을 돌리다가 흥미로운 구간이 있으면 queue 폴더에 저장을 합니다.

해당 queue폴더에 파일이 생기면 symcc에서 파일을 확인하고 분석을 한 뒤 다시 afl로 넘기는 방식입니다.,

이런식으로 SymCC로부터 넘겨받은 파일이 있으면 위의 imported항목의 숫자가 올라간다고 하는데 아직 잘 돌아가진 않는 것 같아서 손을 좀 봐야 될 것 같습니다.

 

근데 이게 데스크탑에서 새로 깔았다 보니  AFL은 잘돌아가는데 SYMCC는 어제 했던거 그대로 해도 안되고, afl이랑 연동하는거 말고 그냥 symcc만 돌려도 안되더라고요.

 

며칠동안 헤맸는데 symcc에 clang이 설치가 안되어있어서, 컴파일할 때 symCC심볼이 안들어가있는걸 확인했습니다.

그래서 clang이랑 다른 의존성 패키지도 없어서 설치를 했는데, 이미 도커파일로 빌드가 되었다 보니까 설치한다고 연결이 되는게 아니고 과정이 복잡하더라고요 ㅣ,, 그래서 그냥 새 데스크탑에 아예 처음부터 새로 설치를 해주었습니다.

 

공식 문서를 찾아봐서 해석해서 읽어봤는데, 방법이 좀 많이 잘못됐더라고요 ..

symcc를 설치하고, afl도 따로 설치한 뒤, rustc랑 cargo를 깔고 fuzzing_helper를 따로 빌드해야 한다고 하는데, 이전에 글 쓴거에서 왜 fuzzing_helper가 됐는진 모르겠네요. 애초에 왜 symcc로 심볼릭 실행도 안되는지는 더 모르겠습니다.

 

일단 해당 내용을 인지한상태로 조금 더 찾아보고, 아예 새로운 포스팅으로 작성해오겠습니다 ..

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

Hybrid Fuzzing - 2 ( SymCC + AFL )  (0) 2026.01.15
SymCC Fuzzing - 1 ( Symbolic executor )  (0) 2026.01.11
[Fuzzing] Boofuzz Fuzzing  (0) 2026.01.09
[Fuzzing] AFL++ Fuzzing  (0) 2026.01.08