Security

Fuzzing 기초 1

SpruceMoon 2026. 5. 18. 19:27

1. 퍼징 (Fuzzing) 이란

출처 : 카이스트 사이버보안연구센터

   - 비정상적인 데이터를 계속 던져서 프로그램이 언제 무너지는지 관찰하는 자동화 테스트

   - 소프트웨어에 무작위이거나 의도적으로 Invalid/Unexpected data를 지속적으로 주입하는 테스팅 기법

   - 이렇게 해서 약간 예외 사항이나 알고리즘으로 치면 반례 같은 걸 찾아내는 과정이라고 보면 됨!

   - 반례 찾아내는 걸 사람 머리도 물론 쓰지만 기계를 써서 (엣지 케이스라는 용어가 있다) 더 빨리 찾아낼 수 있는 게 장점...

   - 엣지 케이스 :: 개발자 측면에선 최소/최대 경계값을 넣어서 테스트할 때 정상 동작하는지 확인하는 거!

   +) 코너 케이스는 뭐냐 -> 엣지 케이스는 만족하는데 외부 변수나 특정 조건에서 문제가 발생하는 경우 ... 약간 집에선 잘 되던 스마트폰이 등산하면 잘 안 터지는 그런 쪽 문제라고 이해했다!

2. 퍼징 과정

   1) Seed(초기값) 준비 :: 정상적인 파일을 초기 입력값으로 설정

   2) Mutation(변이) :: Seed 파일 비트나 바이트를 무작위로 뒤집거나 쪼개서 이상한 데이터들을 막 생성해보는 거 (방법론으로는 비트 플립, 바이트 스왑 등이 있다고 함.)

   3) Execution(실행) :: 변이된 데이터를 타겟 프로그램에 입력해 실행

   4) Monitoring(감시) :: 어떻게 돌아가는지 실시간으로 모니터링하기

   5) Logging(기록) :: 만약 크래시가 발생했다면 그 크래시를 유발한 정확한 입력 데이터를 별도로 저장 (추후 분석 및 디버깅에 사용)

   - 방법 자체는 간단하다!

3. 퍼징의 종류

   1) 블랙박스 퍼징 :: 내부 코드 모르는 상태로 입출력만 조작 (속도 빠름, 얕은 버그 탐지 유리)

   2) 화이트박스 퍼징 :: 소스코드 완벽 분석 + Symbolic Execution 등을 사용 (속도 느림, 깊숙한 코드 라인까지 도달, 분석에 연산량 多)

   3) 그레이박스 퍼징 :: 블 + 화 합친 것. 코드를 완벽 분석까지는 아니어도 프로그램이 실행되는 경로는 추적함.

      ㄴ 이게 요즘 가장 많이 쓰이며, AFL (American Fuzzy Lop) 이 대표적.

4. 커버리지 기반 퍼징 (Coverage-Guided Fuzzing)

   - 코드 커버리지 (Code Coverage) :: 프로그램 실행 시 전체 소스코드 중 어느 부분이 실행되었는지 나타내는 지표

   - 어떻게 쓰는가 :: A 데이터 넣었을 때 이전에 안 가봤던 새로운 코드 경로가 나오면 그 A 데이터를 '좋은 시드'로 승격

   - '좋은 시드'를 바탕으로 다시 변이가 진행 -> 프로그램의 로직을 점점 더 깊게 파고들게 됨!

5. Sanitizer

   - 퍼징할 때 꼭 같이 세팅해야 하는 컴파일러 옵션 (GCC, Clang)

   - 필요한 이유? : 메모리 꼬였는데 프로그램이 우연히 안 죽고 버티는 경우 (Silent Bug라고 한다네요) 퍼저가 이걸 취약점으로 인지 못하고 넘어갈 수 있기 때문!

   - 하는 역할 : 프로그램 코드 사이사이에 들어가 있는데, 미세한 메모리 오류가 발생하면 그 즉시 강제로 크래시를 유발해 퍼저가 버그를 인식하게 만들어준다!

   - 대표적으론 ASan (AddressSanitizer, BOF와 UAF 등의 메모리 침범 버그 특화)와 MSan(MemorySanitizer, 초기화되지 않은 메모리 사용 탐지)가 있다.

6. 퍼징에 대한 추가 팁?

   1) Harness를 작성하자

     - 하네스(Harness)는 무엇인가 :: 테스트하고 싶은 특정 함수만 따로 떼서 퍼저가 주는 입력값을 바로 먹일 수 있게 연결해주는 약간.. 바로가기 창 같은 걸 만들어주는 껍데기 코드 같은 것.

     - 하네스를 어떻게 짜느냐에 따라 퍼징의 속도와 질이 달라진다고 함!

   2) 시드를 최소화하자

     - Corpus :: 퍼저에게 줄 시드 파일의 묶음

     - 데이터를 최소화해서 작게 여러번 변이시키는 게 버그 확률도 낮고 속도도 빠르다! 

     - AFL 기준으론 두 가지 최소화 기법이 있는데, 

         a) cmin (Corpus Minimization) :: 중복되는 코드 경로를 실행하는 코드 파일을 걸러냄 (중복 제거)

         b) tmin (TestCase Minimization) :: 시드 파일 자체의 크기만 줄이기 (경로는 그대로!) 

   3) 모든 크래시가 보안 취약점은 아님!

     - 크래시가 엄청나게 쌓였을 때도 단순 버그와 치명적 보안 취약점을 구분해낼 줄 알아야 한다.

     - Triage :: 크래시를 유발한 입력값을 디버거에 넣고 돌려보면서 메모리의 어느 주소에서 프로그램이 죽었는지, 분석자가 메모리 값(레지스터 같은)을 조작할 수 있는지 분석하는 것! (매우 중요)

'Security' 카테고리의 다른 글

[최신 보안 사례 조사]  (0) 2026.03.23