
Manul은 Windows, Linux 및 MacOS에서 오픈소스 및 블랙박스 바이너리를 위한 커버리지 기반 병렬 퍼저입니다.

Manul은 Windows, Linux 및 macOS(베타)에서 오픈소스 및 블랙박스 바이너리를 위한 커버리지 기반 병렬 퍼저이며, 순수 Python으로 작성되었습니다.
pip3 install psutil
git clone https://github.com/mxmssh/manul
cd manul
mkdir in
mkdir out
echo "AAAAAA" > in/test
python3 manul.py -i in -o out -n 4 "linux/test/test_afl @@"
sudo apt-get install gcc make git wget
git clone https://gitlab.com/akihe/radamsa.git && cd radamsa && make && sudo make install
Windows에서는 radamsa를 설치할 필요가 없습니다. Manul은 이 플랫폼에서 radamsa 네이티브 라이브러리와 함께 배포됩니다.
| CVE ID | 제품 | 발견자 |
|---|---|---|
| CVE-2019-9631 CVE-2019-7310 CVE-2019-9959 | Poppler | Maksim Shudrak |
| CVE-2018-17019 CVE-2018-16807 CVE-2019-12175 | Bro/Zeek | Maksim Shudrak |
Manul을 사용하여 새로운 버그를 발견하셨다면 저에게 연락해 주시면 목록에 추가하겠습니다.

pip install pywin32) (DBI 지속성 모드에만 필요).현재 Manul은 AFL 기반(afl-gcc, afl-clang 및 afl-clang-fast)과 DBI 두 가지 유형의 계측을 지원합니다.
대상을 afl-gcc 또는 afl-clang-fast와 Address Sanitizer로 계측하십시오 (더 나은 결과를 위해 권장). 예:
CC=afl-gcc CXX=afl-g++ CFLAGS=-fsanitize=address CXXFLAGS=-fsanitize=address cmake <path_to_your_target>
make -j 8
USE_ASAN=1 CC=afl-clang-fast CXX=afl-clang-fast++ cmake <path_to_your_target>
make -j 8
자세한 내용은 이 지침을 참조하세요.
이 모드에서는 대상을 계측할 필요가 없지만 Windows 또는 Linux용 최신 버전의 DynamoRIO 프레임워크를 다운로드해야 합니다.
Manul은 Linux 및 Windows용 x86/x64 사전 컴파일된 클라이언트와 함께 배포됩니다. 다음 폴더에서 찾을 수 있습니다:
linux/dbi_32|dbi_64/libbinafl.so (DynamoRIO 클라이언트)
win/dbi_32|dbi_64/binafl.dll
안타깝게도 DynamoRIO는 macOS에서 공식적으로 지원되지 않습니다.
최신 DynamoRIO 릴리스 패키지는 DynamoRIO 다운로드 페이지에서 찾을 수 있습니다.
manul.config 파일에서 다음 줄의 주석을 해제하고 DynamoRIO 런처 및 클라이언트의 올바른 경로를 제공해야 합니다.
# Manul에 커버리지를 제공하기 위해 DBI 프레임워크 선택 ("dynamorio" 또는 "pin"). 예: dbi = dynamorio
dbi = dynamorio
# dbi 매개변수가 None이 아닌 경우 dbi 엔진 런처와 dbi 클라이언트의 경로를 지정해야 합니다.
dbi_root = /home/max/DynamoRIO/bin64/drrun
dbi_client_root = /home/max/manul/linux/dbi_64/libbinafl.so
dbi_client_libs = None
또한, 지속적인 인메모리 퍼징을 사용하여 블랙박스 퍼징 캠페인의 성능을 높일 수 있습니다. 이 모드에서는 특정 함수(예, 바이너리를 디스어셈블하여 찾아야 함)를 계측하도록 Manul에 지시하고 다음 줄의 주석을 해제하여 루프에서 실행합니다:
dbi_persistence_mode = 1
dbi_target_module = afl_test
dbi_target_method = open_file
#dbi_target_offset = 0x3198 # 선택적으로 이름 대신 이 함수의 오프셋을 제공할 수 있습니다
dbi_fuzz_iterations = 1000
winAFL 작성자는 이것이 실제로 어떻게 작동하는지 여기에 잘 설명합니다. Manul은 winAFL 계측 라이브러리 코드의 많은 부분을 사용하여 대상과 통신하고 계측합니다.
중요 참고: 32비트 바이너리를 퍼징하려면 32비트 런처와 32비트 클라이언트를 사용하고, 64비트 바이너리에는 64비트 런처와 64비트 클라이언트를 사용해야 합니다!
계측 라이브러리를 컴파일하려면 최신 버전의 DynamoRIO를 사용해야 합니다. 계측 라이브러리의 소스 코드는 Manul 메인 폴더에 있는 dbi_clients_src에서 찾을 수 있습니다.
64비트 Linux
cd dbi_clients_src
wget <DynamoRIO-x86_64-Linux-X.XX.XXXX-X.tar.gz> - 최신 DynamoRIO 다운로드
tar xvf DynamoRIO-x86_64-X.XX.XXXX-X.tar.gz
mkdir client_64
cd client_64
cmake ../dr_cov/ -DDynamoRIO_DIR=/home/max/manul/dbi_clients_src/DynamoRIO-x86_64-Linux-X.XX.XXXX-X.tar.gz/cmake
make
32비트 Linux
cd dbi_clients_src
wget <DynamoRIO-i386-Linux-X.XX.XXXX-X.tar.gz> - 최신 DynamoRIO 다운로드
tar xvf DynamoRIO-x86_64-X.XX.XXXX-X.tar.gz
mkdir client_64
cd client_64
CFLAGS=-m32 CXXFLAGS=-m32 cmake ../dr_cov/ -DDynamoRIO_DIR=/home/max/manul/dbi_clients_src/DynamoRIO-i386-Linux-X.XX.XXXX-X.tar.gz/cmake
make
Windows에서 라이브러리를 컴파일하는 가장 쉬운 방법은 Visual Studio(2017 및 2013 버전에서 테스트됨)를 설치하고 VS20XX Cross Tools 명령 프롬프트를 실행한 후 다음 명령을 실행하는 것입니다:
64비트 Windows
cd dbi_clients_src
<최신 DynamoRIO 다운로드 및 압축 해제>
mkdir client_64
cd client_64
cmake -G"Visual Studio 15 Win64" ..\dr_cov\ -DDynamoRIO_DIR=C:\Users\max\manul\dbi_clients_src\DynamoRIO-Windows-XXXX.XX.X.X\cmake
cmake --build . --config RelWithDebInfo (필요한 경우 Debug)
32비트 Windows
cd dbi_clients_src
<최신 DynamoRIO 다운로드 및 압축 해제>
mkdir client_32
cd client_32
cmake -G"Visual Studio 15" ..\dr_cov\ -DDynamoRIO_DIR=C:\Users\max\manul\dbi_clients_src\DynamoRIO-Windows-XXXX.XX.X.X\cmake
cmake --build . --config RelWithDebInfo (필요한 경우 Debug)
Manul은 원래 Intel PIN 커버리지 기반 퍼징을 지원했지만 낮은 성능과 높은 유지 관리 오버헤드로 인해 더 이상 지원되지 않습니다.
가장 자주 사용되는 옵션은 명령줄을 통해 제공할 수 있습니다. 더 많은 옵션은 구성 파일(manul.config)을 사용하여 지원됩니다.
예: python3 manul.py -i corpus -o out_dir -n 40 "target @@"
위치 인수(positional arguments):
target_binary 실행할 대상 바이너리 및 옵션 (따옴표 포함을 잊지 마세요, 예: "target e @@").
선택적 인수(optional arguments):
-h, --help 도움말 메시지를 표시하고 종료합니다
-n NFUZZERS 병렬 퍼저의 수
-s 더미 퍼징 실행 (코드 계측 없음)
-c CONFIG 추가 옵션이 있는 구성 파일 경로 (아래 구성 파일 옵션 섹션 참조)
-r 이전 세션 복원
필수 매개변수:
-i INPUT 초기 코퍼스 디렉토리 경로
-o OUTPUT 출력 디렉토리 경로
Manul은 기본 manul.config 파일과 함께 배포되며, 여기에서 사용자는 지원되는 모든 옵션과 사용 예제를 찾을 수 있습니다. 옵션은 다음 형식으로 지정해야 합니다 Format: <option_name> = <value>. 기호 #는 줄을 무시하는 데 사용할 수 있습니다.
dict = /home/max/dictionaries/test.dict. AFL 변이 전략은 사용자가 퍼징된 파일의 임의 위치에 삽입할 수 있는 사용자 정의 토큰 목록을 지정할 수 있도록 합니다. Manul은 이 옵션을 통해 이 기능을 지원합니다 (절대 경로 선호).
mutator_weights=afl:7,radamsa:2,my_mutator:1. 변이기 가중치는 사용자가 특정 퍼저가 10번 실행 중 몇 번의 변이를 수행해야 하는지 Manul에 알릴 수 있게 합니다. 이 예에서 AFL 변이기는 7/10 변이에서 실행되고 Radamsa 2/10, 사용자 정의 my_mutator는 1/10을 차지합니다. 특정 변이기를 비활성화하려면 가중치를 0으로 할당해야 합니다 (예: mutator_weights=afl:0,radamsa:1,my_mutator:9).
deterministic_seed = False|True. True를 제공하면 Radamsa 변이가 결정론적이 되어 Manul의 각 실행이 동일한 출력을 생성합니다.
print_per_thread = False|True. 이 옵션을 활성화하면 Manul은 전체 요약 대신 실행 중인 각 스레드에 대한 요약을 출력합니다.
disable_volatile_bytes = False|True 이 옵션을 활성화하면 Manul은 휘발성 경로를 블랙리스트에 추가하지 않습니다.
forkserver_on = False|True AFL의 포크서버를 활성화 또는 비활성화합니다.
dbi = dynamorio|pin. 이 옵션은 Manul에 대상 계측에 사용할 DBI 프레임워크를 알려줍니다.
dbi_root = <path>. 이 옵션은 Manul에 DBI 프레임워크 메인 런처의 위치를 알려줍니다.
dbi_client_root = <path>. 이 옵션은 Manul에 계측을 수행할 DBI 클라이언트의 위치를 알려줍니다.
dbi_client_libs = name_#1,name_#2|None. 이 옵션은 메인 대상과 함께 계측해야 하는 라이브러리 목록을 지정하는 데 사용할 수 있습니다 (예: 대상 라이브러리와 버그를 찾고자 하는 몇 가지 다른 라이브러리를 로드하는 실행 파일이 있는 경우).
dbi_persistence_mode = 0|1|2. 이 옵션은 DBI 지속성 모드를 선택하는 데 사용됩니다. 0 - 지속성 없음, 1 - 표준 지속성(함수 래핑), 2 - 아직 지원되지 않음.
dbi-persistence_mode = 1|2인 경우 다음 옵션을 지정해야 합니다:
dbi_target_module = <module name>. Manul은 여기에 지정된 모듈에서 대상 함수를 검색합니다.
dbi_target_method = <function name>. 지속성을 위해 래핑할 함수 이름입니다.
dbi_target_offset = <function offset 예: 0x3198>. 지속성을 위해 래핑할 함수 오프셋입니다. 디버그 기호를 사용할 수 없는 경우 dbi_target_method 대신 이 옵션을 사용할 수 있습니다.
dbi_fuzz_iterations = 500. 전체 프로그램이 다시 시작되기 전에 인메모리에서 실행할 퍼징 반복 횟수입니다. 이 인수를 조정하여 대상에 가장 잘 맞는 값을 찾을 수 있습니다.
dbi_thread_coverage = False. 대상 함수를 실행한 스레드에서만 커버리지 계측 (아직 지원되지 않음).
timeout = 10. 대상을 종료하고 다음 테스트 케이스를 보내기 전까지 대기할 시간입니다.
init_wait = 1. 이 옵션은 대상 초기화에 필요한 타임아웃을 설정하는 데 사용할 수 있습니다.
net_config_master 및 net_config_slave 옵션은 네트워크를 통해 Manul 인스턴스를 분산하는 데 사용됩니다. 분산 퍼징을 실행하려면 다음 3단계를 수행해야 합니다.
IP:port 형식으로 파일에 만듭니다.net_config_slave = 0.0.0.0:1337. Manul은 인스턴스를 시작하고 1337 포트에서 마스터 인스턴스의 연결을 기다립니다.net_config_master = file_name을 사용하여 제공합니다.debug = False|True - 디버그 정보 출력.
logging_enable = False|True - 디버그 정보를 로그에 저장.
manul_logo = False|True - 시작 시 Manul 로고 출력.
no_stats = False|True - 통계 저장.
sync_freq = 10000. 사용자가 커버리지 비트맵 동기화 빈도를 변경할 수 있습니다. 이 옵션은 Manul이 병렬 퍼징 인스턴스 간에 커버리지를 얼마나 자주 동기화해야 하는지 알려줍니다. 낮은 값은 성능을 저하시키지만 인스턴스 간 조정을 증가시킵니다.
#custom_path = test_path - 이 옵션은 사용자 정의 폴더에 테스트 케이스를 저장할 수 있게 합니다 (대상이 미리 정의된 위치에서 로드하려는 경우).
cmd_fuzzing = True|False. 이 옵션이 활성화되면 Manul은 파일에 저장하는 대신 명령줄을 통해 대상을 입력으로 제공합니다.
user_signals = 6,2,1|None. 사용자는 Manul에 대상의 어떤 신호를 무시해야 하는지 (충돌로 간주하지 않음) 알릴 수 있습니다.
target_ip_port = 127.0.0.1:7715|None - 대상 IP 및 PORT 지정에 사용됩니다.
target_protocol = tcp|tcp - 네트워크를 통해 대상을 입력을 보내는 데 사용할 프로토콜을 지정합니다.
net_sleep_between_cases = 0.0. 이 옵션은 대상으로 전송되는 테스트 케이스 사이의 지연 시간을 정의하는 데 사용할 수 있습니다.
현재 네트워크 퍼징은 실험적 기능입니다 (자세한 내용은 이슈 참조).
사용자 정의 변이기는 다음 세 단계로 추가할 수 있습니다: 1단계. Python (.py) 파일을 만들고 이름을 지정합니다 (예: example_mutator.py)
2단계. 두 개의 함수 def init(fuzzer_id)와 def mutate(data)를 만듭니다. 자세한 내용은 example_mutator를 참조하세요. Manul은 퍼징 초기화 중에 init 함수를 호출하고 대상에 제공되는 각 파일에 대해 mutate를 호출합니다.
3단계. manul.config의 mutator_weights를 사용하여 변이기 이름을 지정하여 활성화합니다. 예: mutator_weights=afl:2,radamsa:0,example_mutator:8.
참고: AFL 및 Radamsa 변이기는 항상 지정되어야 합니다. AFL 및/또는 Radamsa를 비활성화하려면 가중치를 0으로 할당하기만 하면 됩니다.
TBD
