1nzag

[winAFL] winAFL DynamoRIO 관련 분석

fuzzer

*dynamoRIO

 

dynamoRIO option: 기존 인자를 파싱하는 opt_arg 함수에 -D 옵션 추가. DynamoRIO (drrun.exe) 사용하기 위해 해당 파일의 path 지정하는 변수이다.

 

DynamoRIO option: 해당 DynamoRIO 실행파일에 넣어줄 인자를 따로 받는 구간이 존재한다.

 

 

 

해당 인자는 dynamorio_dir 전역변수에 저장되며, target 실행시킬 해당 인자를 drrun.exe 전달해준다.

 

 

 

이때 -c option (-client) winafl.dll 들어가는데, 이는 winafl.c 으로부터 컴파일되는 dll 파일이다.

dynamoRIO 사용자와 interact 하기 위해 client 지정할 있는데, 이를 지정해 주는 옵션이다.

 

 

클라이언트에 커스터마이징한 클라이언트 winafl.dll 넣음으로써 afl-fuzz drrun.exe 서로 interact 하며 작동될 있다.

 

둘은 서로 named pipe 통신한다.

관련된 대표적 함수는 WriteCommandFromPipe() ReadCommandFromPipe() 함수임 해당 파이프라인은 Create_target_process() 함수에서 target 실행시킬 생성시킨다.

 

 

다음은 run_target() 함수에서 파이프라인에 command 보내는 부분이다.

 

다음은 winafl.c 에서 파이프를 통해 메시지를 읽고 쓰는 함수다.

 

 

이러한 command F, Q, P, K 4가지이다.

 

F: afl-fuzz winafl.dll에게 퍼징을 시작한다는 신호를 보내는 command

Q: afl-fuzz winafl.dll에게 process exit 하라는 신호를 보내는 command

 

P: winafl.dll afl-fuzz 에게 프로그램 사이클을 끝냈다고 신호를 보내는 command

K: winafl.dll afl-fuzz 에게 프로그램 사이클을 시작한다고 신호를 보내는 command

 

또하나로, drrun winafl.dll coverage afl-fuzz 에게 전달할 때는 shared memory 사용한다.

 

 

 

커버리지를 등록하는 알고리즘은 두가지가 있다. 두가지는 다음과 같다.

 

    1. bb coverage
    2. edge coverage

 

알고리즘을 설명하기 전에 먼저 dynamorio에서 어떠한 인자(변수) 참고하는지 필요가 있다.

 

module_data_t : 로드한 모듈(바이너리) 정보를 담고 있는 구조체. module_data_t start 해당 바이너리의 start_address 담고 있다. (엔트리 포인트를 담고 있다고 생각하면 된다.)

 

app_pc: 특정 pc (program counter) 지정하는 변수명

 

dr_fragment_app_pc(): 해당 테그가 존재하는 pc 반환한다.

 

drmgr_register_bb_instrumentation_event:

Registers callback functions for the second and third instrumentation stages: application analysis and instrumentation insertion. drmgr will call func as the second of four instrumentation stages for each dynamic application basic block.

 

라고 적혀있는데 instrument 진행될때마다 call 되는 callback 함수라고 보면 같다. (정확하지 않음)

 

winafl.dll 로드 메인 함수에서 옵션에 따라 coverage 등록하는 함수를 instrument 진행될 때마다 callback 있도록 한다.

 

 

 

bb coverage:

instrument 진행되면 때의 pc 엔트리포인트의 차이를 구해 거리를 공유메모리 내의 테이블에 등록한다.

 

이때 start_pc 다음으로 구한다.

 

 

edge coverage:

처음엔 bb coverage 마찬가지로 엔트리포인트와 해당 pc 와의 거리를 구하지만 전의 거리값과 특정 연산을 그에 해당하는 테이블에 값을 더한다.

 

이러한 차이를 두는 지는 모르겠지만 edge bb 다르게 전에 있었던 pc카운터를 활용하기때문에 coverage 정확히 구분할 하다.

 

 

 

'fuzzer' 카테고리의 다른 글

[WinAFL] WinAFL 퍼저 요약  (1) 2020.04.20

[WinAFL] WinAFL 퍼저 요약

fuzzer
  1. WinAFL:

윈도우에서 동작할 있게 만든 AFL 퍼저. 기존 AFL 퍼저는 리눅스 환경에서 만들어졌으나 윈도우에서는 구조상의 차이 (instrument, forkserver ) 쉽게 AFL 돌릴 없었음. 이후 윈도우에서 AFL 구동시킬 있게 하기 위해 만든 것이 WinAFL

 

WinAFL 특징은 크게 다음과 같이 나눌 있음

 - 윈도우 환경에서 AFL 돌릴 있음

 - 블랙박스 퍼징이 가능함 **

 - 서버를 퍼징하는 것이 가능함(있는 기능이지만 아직 공부 안했음)

 

WinAFL 다음의 3가지 하나의 instrument 사용해 블랙박스 퍼징 경로(path) 추적을 가능하게

 - DynamoRIO

 - IntelPT

 - Syzygy

 

보통 WinAFL 사용할 때는 DynamoRIO 범용성이 높고 접근성이 높기 때문에 DynamoRIO 사용한다.

 

  1. DynamoRIO:

DynamoRIO 프로그램이 실행되는 동안 프로그램의 모든 부분에서 코드 변환을 지원하는 런타임코드 조작 시스템임. 따라서 특징을 이용해 AFL 에서 컴파일 추적 코드를 삽입하는 과정을 WinAFL 블랙박스에서도 적용 있도록하게 .

하지만 instrument 사용하면 퍼징하는 시간 전체는 느리다는 단점이 있음

 

  1. WinAFL 컴파일

WinAFL 컴파일을 위해서는 다음과 같은 컴파일 소스가 필요하다.

 - WinAFL 코드

 - VC 컴파일러 (Visual Studio cmake)

 - DynamoRIO 코드

 

WinAFL 소스를 다운로드 뒤에 디렉토리 내부에서 다음과 같은 명령어를 VisualStudio 명령 프롬프트로 실행시켜 컴파일한다.

mkdir build32
cd build32
cmake -G"Visual Studio 15 2017" .. -DDynamoRIO_DIR=..\path\to\DynamoRIO\cmake -DINTELPT=1
cmake --build . --config Release

 

출처: <https://github.com/googleprojectzero/winafl>

 

64비트로 컴파일 하기 위해서는 -G 옵션에 Win64 아키텍쳐를 추가하고 IntelPT 사용하지 않는다면 -DINTELPT=1 옵션을 제거한다.

 

  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 @@

 

  1. 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

PDF 자바스크립트 추출

rev

pdfinfo -js 


모든 코드를 추출하고 싶다면 peepdf 이용


https://github.com/jesparza/peepdf


https://stackoverflow.com/questions/29342542/how-can-i-extract-a-javascript-from-a-pdf-file-with-a-command-line-tool

'rev' 카테고리의 다른 글

[IDA] C++ decompile failure : call analysis failed  (0) 2018.09.03
[Python] gmpy invert, divm (rctf 2018 babyre2)  (0) 2018.08.06
[IDA] 자주쓰는 IDA 단축키  (0) 2018.08.01