본문 바로가기

Testing Tools/Fuzzing

Python Fuzzer - Manul 소개 및 사용법

참고자료

 

Manul 이란?

Manul은 Python으로 작성된 Windows / Linux / macOS에서 사용가능한 병렬 처리를 지원하는 Coverage Guided Fuzzer 이다.

AFL과의 성능 비교는 이 곳의 자료를 참고한다.

 

준비하기

Python으로 작성되어 있어 설치도 매우 쉽다.

pip3 install psutil
git clone https://github.com/mxmssh/manul

필요하다면, clone 받은 위치를 path 환경 변수에 추가하여 사용한다.

 

Fuzzing  수행

하부 폴더에 이미 저정되어 있는 afl-gcc로 빌드된 바이너리 test_afl을 사용한다. (linux/test/test_afl)

해당 소스코드는 아래와 같다.

/*
   Manul - test file for Linux
   -------------------------------------
   Maksim Shudrak <mshudrak@salesforce.com> <mxmssh@gmail.com>

   Copyright 2019 Salesforce.com, inc. All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at:
     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    char *buf = NULL;
    int size = 0;
    if(argc < 2) {
        printf("Usage: %s <input file>\n", argv[0]);
        exit(-1);
    }
    FILE *fp = fopen(argv[1], "rb");
    if (!fp) {
        printf("Couldn't open file specified %s", argv[1]);
        exit(-1);
    }
    printf("Opening %s\n", argv[1]);
    // obtain file size:
    fseek(fp , 0 , SEEK_END);
    size = ftell(fp);
    rewind(fp);

    // allocate memory to contain the whole file:
    buf = (char*) malloc (sizeof(char ) * size);
    if (buf == NULL) {printf("Unable to read file"); exit (-1);}

    // copy the file into the buffer:
    fread(buf, 1, size, fp);
    fclose(fp);

    if (buf[0] == 'P') {
        if (buf[1] == 'W') {
            if (buf[2] == 'N') {
                if (buf[3] == 'I') {
                    if (buf[4] == 'T') {
                        printf("Found it!\n");
                        ((void(*)())0x0)();
                    }
                }
            }
        }
    }

    printf("Parsed %d bytes\n", size);
    free(buf);
}

 

 

초기 테스트 입력 AAAAAA을 최초 입력으로 하여 진행한다.

cd manul
mkdir in
mkdir out
echo "AAAAAA" > in/test
python3 manul.py -i in -o out -n 4 "linux/test/test_afl @@"

 

 

아래와 같이 구동됨을 확인할 수 있다.

 

 

htop으로 확인해보니 가용한 cpu 자원을 다 사용하고 있음을 확인할 수 있다.

(AFL은 별도 옵션을 주어 master / slave1 / slave 2 등과 같이 구분하여 수행해야 함.)

 

 

결과확인

output 으로 지정된 폴더 내에 생성된 테스트 데이터를 확인할 수 있다.

"PWNIA" 를 성공적으로 찾아낸 것을 볼 수 있다.

 

Coverage-guided Fuzzing 수행 방법

현재 Manul은 AFL(afl-gcc, afl-clang, afl-clang-fase 등)와 DBI 기반 실행파일을 지원한다.

AFL 기반 실행파일 생성 시, 효과적인 수행을 위해 Address Sanitizer를 활성화하여 빌드한다.

(자세한 건 Link 를 확인한다.)

 

CC=afl-gcc CXX=afl-g++ CFLAGS=-fsanitize=address CXXFLAGS=-fsanitize=address cmake <path_to_your_target>
make -j 8