[WinAFL] WinAFL 퍼저 요약
fuzzer- WinAFL:
윈도우에서 동작할 수 있게 만든 AFL 퍼저. 기존 AFL 퍼저는 리눅스 환경에서 만들어졌으나 윈도우에서는 구조상의 차이 (instrument, forkserver 등) 에 쉽게 AFL 을 돌릴 수 없었음. 이후 윈도우에서 AFL 을 구동시킬 수 있게 하기 위해 만든 것이 WinAFL
WinAFL 의 특징은 크게 다음과 같이 나눌 수 있음
- 윈도우 환경에서 AFL을 돌릴 수 있음
- 블랙박스 퍼징이 가능함 **
- 서버를 퍼징하는 것이 가능함(있는 기능이지만 아직 공부 안했음)
WinAFL 은 다음의 3가지 중 하나의 instrument 를 사용해 블랙박스 퍼징 및 경로(path) 추적을 가능하게 함
- DynamoRIO
- IntelPT
- Syzygy
보통 WinAFL을 사용할 때는 DynamoRIO가 범용성이 높고 접근성이 높기 때문에 DynamoRIO 를 사용한다.
- DynamoRIO:
DynamoRIO 는 프로그램이 실행되는 동안 프로그램의 모든 부분에서 코드 변환을 지원하는 런타임코드 조작 시스템임. 따라서 이 특징을 이용해 AFL 에서 컴파일 할 때 추적 코드를 삽입하는 과정을 WinAFL은 블랙박스에서도 적용 할 수 있도록하게 함.
하지만 이 instrument 를 사용하면 퍼징하는 시간 전체는 느리다는 단점이 있음
- WinAFL 컴파일
WinAFL 컴파일을 위해서는 다음과 같은 컴파일 툴 및 소스가 필요하다.
- WinAFL 코드
- VC 컴파일러 (Visual Studio cmake)
- DynamoRIO 코드
WinAFL 소스를 다운로드 한 뒤에 그 디렉토리 내부에서 다음과 같은 명령어를 VisualStudio 명령 프롬프트로 실행시켜 컴파일한다.
mkdir build32
|
64비트로 컴파일 하기 위해서는 -G 옵션에 Win64 아키텍쳐를 추가하고 IntelPT를 사용하지 않는다면 -DINTELPT=1 옵션을 제거한다.
- WinAFL 옵션
WInAFL 을 사용할 때는 옵션을 다음과 같이 준다.
afl-fuzz [afl 옵션] -- [DynamoRIO 옵션] -- [타겟 프로그램] |
Afl 옵션은 다음과 같다.
- -i : testcase 디렉토리
- -o : output 디렉토리
- -D : DynamoRIO bin 디렉토리
- -t : 타임아웃
위 네 가지 옵션은 필수로 줘야 하는 옵션이다. 그 외에 옵션을 더 보고 싶으면 아래 링크를 확인하면 된다.
https://github.com/googleprojectzero/winafl
DynamoRIO 옵션은 다음과 같다.
- -nargs : 프로그램을 실행시킬 때 들어가는 인자의 갯수
- -covtype : 커버리지를 등록하는 타입
- -dry-run : 드라이 런 모드로 돌릴 때 사용하는 옵션
- -coverage_module : 커버리지를 등록하는 대상을 쓰는 옵션. 프로그램이 사용하는 dll
경로를 등록하고 싶으면 dll 을 추가한다.
- -target_module : persistant 모드를 사용하고 싶을 때 대상이 되는 코드가 들어있는
타겟을 쓴다. target_offset 을 무조건 같이 써줘야 한다.
- -target_offset : persistant 모드를 사용하고 싶을 때 대상이 되는 코드의 주소
위 옵션들은 대표적인 옵션들이고 추가 옵션은 위 링크를 통해 확인할 수 있다.
WinAFL을 사용하는 예시는 다음과 같다.
afl-fuzz.exe -i input_dir -o ouput_dir -t 10000 -D DynamoRIO_DIR\bin32 -- -covtype edge -coverage_module A.dll -coverage_module B.dll -nargs 2 -target_module target.exe -target_offset 0x1234566 -- target.exe @@ |
- Persistant mode
서버 프로그램이나 지속적으로 실행되는 프로그램의 경우 퍼징을 할때 굳이 프로그램을 새로 실행시켜가며 할 필요가 없다. 따라서 프로그램을 켜놓은 상태로 입력값만을 넣어주면서 퍼징하는 방법이 Persistant mode 이다.
Persistantmode 를 사용하기 위해서는 대상 코드에 다음과 같은 조건이 있어야 한다.
- inputfile을 open 해야 한다.
- 해당 파일의 내용을 파싱해야 한다
- 파일을 close 해야 한다.
- 정상적으로 리턴해야 한다.
해당 코드가 있으면 해당 코드의 시작지점의 주소를 target_offset 으로 설정해 Persistant mode fuzzing 을 할 수 있다.
Ex>
void OpenAndParse() { FILE *fp = fopen("input", "rb"); char c; while(fgetc() != EOF) { c ^= 0x33; }
fclose(fp); return 0; } |
다음과 같은 함수가 있을 때 target_offset 을 함수의 시작지점으로 놓으면 WinAFL 은 리턴하는 지점을 jmp target_offset 으로 패치하여 해당 부분을 무한루프로 돌며 실행하게 해준다.
따라서 프로세스는 그대로 돌아가게 유지하면서 입력값을 읽고 파싱하는 부분만 골라 퍼징할 수 있게 해준다.
이러한 모드는 퍼징의 속도를 늘리고 효율적인 퍼징을 할 수 있게 해준다.
그 외에 Custom mutate, server fuzzing (Network fuzzing)의 기능이 있다.
'fuzzer' 카테고리의 다른 글
[winAFL] winAFL DynamoRIO 관련 분석 (1) | 2020.06.15 |
---|