mxmssh / manul Goto Github PK
View Code? Open in Web Editor NEWManul is a coverage-guided parallel fuzzer for open-source and blackbox binaries on Windows, Linux and MacOS
License: Apache License 2.0
Manul is a coverage-guided parallel fuzzer for open-source and blackbox binaries on Windows, Linux and MacOS
License: Apache License 2.0
We assume that our path to binary doesn't have spaces.
Add cool graphs (crashes found per time, coverage found per time and etc.)
Timeout is not the best choice for killing the target process (consider kill).
We have to print stats for each file executed (exec per sec).
Current implementation is not compatible with Python3.
https://stackoverflow.com/questions/10058140/accessing-items-in-an-collections-ordereddict-by-index
Hello. Me again. I wanted to know if their could be anything like read from stdin for the afl? As in the -f option in afl. This would help for programs with the stdin bit of things.
Just a suggestion
P.S. Thank you for working on this tool, and replying to my past posts.
Some threads running in dumb-mode + some threads running in coverage-guided and share knowledge.
Hello. It's me again. So after letting pdfcrack fuzz. I wanted to analyze the crashes. However as it turns out. They weren't even crashes. When I looked pdfcrack gives an error about them not being save files (pdfcrack has save file feature I used to make go by faster). Sure an error, but no a crash.
It also let this fuzz overnight. It took up over 200GB by logging manul though to be crashes.
I'll upload the file so you can test this.
Recreate Issue :
Just run the command
manul.py -i in2 -o out -n 3 -c pdfcrack_manul.config "pdfcrack_scource/pdfcrack -l @@"
The pdfcrack is already instrumented. When you have fuzzed as much as you want. Then you can run. pdfcrack_source/pdfcrack -l <a .sav in out>, and it should tell you that this is not a save or is corrupted, not crash.
We have to check that our backend fuzzer actually exist and supported by manul.
Some packets are missed when we are doing testing of test_net and test_net_tcp. For some reason, our target is not receiving some input files (thereby not causing the crash).
handle when dbi_tool_libs is None.
Does this has Persistence and Inapp Persistence mode like winafl ?
We have to think about naming convention of crashes and queue files.
Running a test application works fine with instrumented build but fails under dynamic instrumentation with recommended version of DynamoRIO (7.0.1 release).
Linux
root@computer:/<path>/manul/manul# python3 manul.py -i in -o out --debug "./test.out @@"
> [WARNING] Output directory is not empty, creating backup of output folder
> [INFO] Done
> [INFO] 1 fuzzer instances sucessfully launched
> [INFO] Starting fuzzer 0
> [INFO] Setting up shared mem 2 for fuzzer:0
> [INFO] Initializing mutators
> [INFO] Performing dry run
> [INFO] Launching /<path>/manul/DynamoRIO-Linux-7.1.0-1/bin64/drrun -c /<path>/manul/manul/linux/dbi_64/libbinafl.so -coverage_module test.out -debug -- ./test.out in/inp.txt
> /<path>/manul/DynamoRIO-Linux-7.1.0-1/bin64/drrun -c /<path>/manul/manul/linux/dbi_64/libbinafl.so -coverage_module test.out -debug -- ./test.out in/inp.txt
> [INFO] Target started, waiting for return
> [INFO] Output from target <Application /<path>/manul/manul/test.out (79). Client library targets an incompatible API version and should be re-compiled.>
> [ERROR] inp.txt doesn't cover any path in the target, Make sure the binary is actually instrumented
> [WARNING] Fuzzer 0 unexpectedly terminated
> ^C[INFO] Stopping all fuzzers and threads
> Killed
Windows doesn't even get to that point due to #28, but is included for completeness.
Windows
C:\<path>\manul\manul>python3 manul.py -i in -o out --debug "<different_path>\Test.exe @@"
> [INFO] 1 fuzzer instances sucessfully launched
> [INFO] Starting fuzzer 0
> [INFO] Setting up shared mem 1565800978_0 for fuzzer:0
> [INFO] Initializing mutators
> [INFO] Performing dry run
> Process Process-1:
> Traceback (most recent call last):
> File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1264.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 297, in _bootstrap
> self.run()
> File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1264.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 99, in run
> self._target(*self._args, **self._kwargs)
> File "C:\<path>\manul\manul\manul.py", line 895, in run_fuzzer_instance
> fuzzer_instance.run() # never return
> File "C:\<path>\manul\manul\manul.py", line 753, in run
> self.dry_run()
> File "C:\<path>\manul\manul\manul.py", line 495, in dry_run
> memset(self.trace_bits, 0x0, SHM_SIZE)
> OSError: exception: access violation writing 0x0000000062420000
> [WARNING] Fuzzer 0 unexpectedly terminated
> [INFO] Stopping all fuzzers and threads
Add simple and intermediate level of example. Written tutorial would be helpful
Hello. It's me again. I have another suggestion
So I was fuzzing pdfcrack. For pdf zero day, and I must say I'm impressed manul actually found unique crashes faster than afl (great job). However this program did crash a lot, and an "[INFO] New crash found" appears on screen. Is there already a way to turn this off. If so please tell me. If not I could PR a verbose option to turn this on or off. Maybe call it the notify option. It's up to you at that point.
We have to read options provided from config file instead of terminal and print them in user-friendly format (in case of wrong parameter).
Radamsa can be compiled as a library now. It would be great to integrate it.
See also:
https://gitlab.com/akihe/radamsa/issues/66
https://gitlab.com/akihe/radamsa/issues/28
Hello I had an error about the radamsa not being installed for the linux version. I installed in the same path and got the same error.
Fix:
instead of
if "radamsa:0" not in args.mutator_weights:
if sys.platform == "win32":
check_binary("radamsa.exe")
else:
check_binary("radamsa")
tried this
if "radamsa:0" not in args.mutator_weights:
if sys.platform == "win32":
check_binary("radamsa.exe")
else:
check_binary("./radamsa")
However flowing the commands to install radamsa
git clone https://gitlab.com/akihe/radamsa.git && cd radamsa && make && sudo make install
solved it
Set mutator weights in manul.config to:
mutator_weights=afl:7,radamsa:3
And get this error during fuzzing.
[WARNING] Fuzzer 1 failed to generate new input from in/test due to some problem with radamsa. Error code 1. Return msg b'The process cannot access the file because it is being used by another process.\r\n'
[ERROR] Fuzzer 1 failed to generate and save new input on disk
Have not debugged. Any ideas?
Hello. I like the idea of your manul fuzzier. However I notice a lack of stdin fuzzing. As the program keeps saying how i forgot the @@ for the string. This means that I can't fuzz my stdin because the program takes no arguments. This actually leads to an error (put in another topic).
P.S. Thank you for taking the time to read and hopefully fix this issue.
Attempting to use manul as a blackbox network fuzzer requires the user to specify a target_binary argument even though it's not really necessary. It doesn’t appear to matter what binary is provided to manul (I used /bin/cat) as long as it can be found and launched by manul. Provided the remote side blackbox end is up and running manul will continue sending the fuzzed data until the remote side crashes. Please change the behavior so that the user does not need to provide a target_binary when a blackbox fuzzer mode is in use.
My example setup has a simple python http server on a remote system.
Local Fuzzer System:
$ python3 manul.py -s -i IN -o OUT --target_ip_port 10.0.0.1:8888 --target_protocol=tcp "/bin/cat"
Remote Blackbox System:
$ python -m SimpleHTTPServer 8888
The problem is that Python doesn't have a regular way to kill functions by timeout. This blogpost (probably outdated) explains the problem https://eli.thegreenplace.net/2011/08/22/how-not-to-set-a-timeout-on-a-computation-in-python
This error appears when trying to use radamsa
Probably an easy fix but still wanted to report it.
Traceback (most recent call last):
File "./manul.py", line 557, in init_mutators
self.user_mutators[module_name] = importlib.import_module(module_name)
File "/usr/lib/python3.7/importlib/init.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 1006, in _gcd_import
File "", line 983, in _find_and_load
File "", line 965, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'adamsa'
Continuation from #28. Config file below for reference.
# Manul - configuration file
# -------------------------------------
# Maksim Shudrak <[email protected]> <[email protected]>
#
# 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.
# Manul config file
# Format: <option_name> = <value>
# -----------------
# absolute path to dictionary with usefull tokens
#dict = dictionaries/test.dict
# Mutator weights (should be 10 in total). Use my_mutator:x,my_mutator_2:x to define and use your own
# custom mutator (should be 10 in total). Specify 0 to disable certain mutators. Weights basically are
# used to tell manul how many mutations per 10 executions should be performed by certain fuzzer.
# example afl:5,radamsa:2,my_awesome_fuzzer:3
# afl will be used to mutate 5 out of 10 cases, 2 out of 10 for radamsa and 3 out of 10 for my_awesome_fuzzer
# Your custom mutator's main file should be located in the same folder as manul.py.
# Two default mutators should always be defined (afl, radamsa)
mutator_weights=afl:10,radamsa:0
#mutator_weights=afl:6,radamsa:0,example_mutator:4
# Use determenistic seed for test cases generation (only radamsa option).
determenistic_seed = False
# Print fuzzing summary per thread instead of total summary
print_per_thread = False
# disable volatile bytes suppression algorithm
#disable_volatile_bytes = True
# Choose DBI framework to provide coverage back to Manul ("dynamorio" or "pin"). Example dbi = dynamorio
dbi = dynamorio
# If dbi param is not None the path to dbi engine launcher and dbi client should be specified.
dbi_root = C:\Users\Wes\source\repos\AutoFuzz\AutoFuzz\bin\Debug\netcoreapp3.0\manul\DynamoRIO-Windows-7.0.0-RC1\bin64\drrun.exe
dbi_client_root = C:\Users\Wes\source\repos\AutoFuzz\AutoFuzz\bin\Debug\netcoreapp3.0\manul\manul\win\dbi_64\binafl.dll
dbi_client_libs = None
# Timeout for target binary
timeout = 10
# net_config_master and net_config_slave below are used to share manul instances over network.
# Path to network configuration file with a list of IP:port slave addresses. Specified for master instance.
net_config_master = None
# IP and port to listen for connections from master (e.g. net_config_slave = 0.0.0.0:1337)
net_config_slave = None
# Run in debug mode, print details in console
debug = False
# Print Manul ASCII logo at the beginning
manul_logo = False
# Disable stats saving in the manul working dir
#no_stats = True
# Save debug messages to log files (one per thread)
logging_enable = False
# Bitmap sync frequency (5000 recommended for DBI mode)
sync_freq = 10000
# Custom path to save input file
#custom_path = test_path
# Command line fuzzing (experimental)
#cmd_fuzzing = True
# define signals to be ignored by manul
user_signals = 6
# Network fuzzing. Target IP address
#target_ip_port = 127.0.0.1:7715
# tcp | udp
#target_protocol = tcp
# wait time before actually start sending test cases in the socket
#net_init_wait = 1
# wait time between test cases
#net_sleep_between_cases = 0.0
Integrate AFL mutation algorithm.
Hi, I'm trying to run tests which are included in repo.
I've edited config:
# Choose DBI framework to provide coverage back to Manul ("dynamorio" or "pin"). Example dbi = dynamorio
dbi = dynamorio
# If dbi param is not None the path to dbi engine launcher and dbi client should be specified.
dbi_root = z:\s\tools\DynamoRIO-Windows-7.0.0-RC1\bin32\drrun.exe
dbi_client_root = z:\s\git\manul\win\dbi_32\binafl.dll
dbi_client_libs = None
Created in\out dirs with "AAAA" testcase inside of in directory.
Now I'm trying to start fuzzing.
manul.py -i in -o out -n 1 "win\test\test32.exe @@"
And it seems DR client is just crashing.
If I add debug options, I can see command line for drrun.exe execution:
[INFO] Initializing mutators
[INFO] Performing dry run
[INFO] Launching z:\s\tools\DynamoRIO-Windows-7.0.0-RC1\bin32\drrun.exe -c z:\s\git\manul\win\dbi_32\binafl.dll -coverage_module test32.exe -debug -- win\test\test32.exe z:\s\git\manul\out/0/mutations/.cur_input
[INFO] Target started, waiting for return
And ...proc.log reveals only this:
Module loaded, test32.exe
Module loaded, drx.dll
Module loaded, drwrap.dll
Module loaded, drreg.dll
Module loaded, MSVCR120.dll
Module loaded, drmgr.dll
Module loaded, binafl.dll
Module loaded, dynamorio.dll
Module loaded, KERNEL32.dll
Module loaded, KERNELBASE.dll
Module loaded, ntdll.dll
This appears to be a program issue. I haven't dug into but I will. I was trying to fuzz with radamsa then this happens.
AttributeError: 'ModuleNotFoundError' object has no attribute 'message'
Using manul for blackbox network fuzzing mode works well for sending fuzzed data, but it does not appear to have any instrumentation to detect and/or recover from a remote target crash.
Provided the remote side blackbox is up and running manul will continue sending the fuzzed data until the remote side crashes. Once a remote side crash happens, the manul threads all die and even if the remote side comes back online manul is still considers the target as dead. It also doesn’t detect remote side crashes in any way I could tell other than executions stop in the UI.
It would be useful to have a "health check" functionality along with some logic on how to handle a remote side crash like saving the last know fuzzed input upon failed health check along with restarting the fuzz run when the remote side is available again.
Support Windows fuzzing.
Support Pin/DynamoRIO with option to select range of addresses/modules to cover.
I use latest manul on windows 10 1903, I found afl not increase new path for additional client libs, it only can detect 3 new path, but tested on winafl for same windows exe, it can detect 36 new path shortly, I tested not worked on DynamoRIO-Windows-7.91.18299-0 and DynamoRIO-Windows-7.91.18157-0,
Hi!
I'm playing with manul, and have a simple fuzz function like this:
void fuzz() {
FILE* fd = fopen(g_path, "r");
static char tgt[] = "tgt";
if (fgetc(fd) == tgt[0] &&
fgetc(fd) == tgt[1] &&
fgetc(fd) == tgt[2]) {
*(char*)0 = 0;
}
fclose(fd);
}
I noticed that if I provide input corpus as a one file one byte long, it never grows to 2 bytes. If I provide input corpus 3 bytes long or more it finds a crash quite fast. So, it seems to me that alf mutator can't grow mutating buffer size. Could you please give me some pointers to resolve this issue?
Thanks!
This error appears when trying to fuzz stdin on a program (not arguments, just stdin). However manul forces the @@ which is for arguments.
Error :
Traceback (most recent call last):
File "/usr/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
self.run()
File "/usr/lib/python3.7/multiprocessing/process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "./manul.py", line 993, in run_fuzzer_instance
fuzzer_instance.run() # never return
File "./manul.py", line 851, in run
self.dry_run()
File "./manul.py", line 613, in dry_run
if "is for the wrong architecture" in err_output:
TypeError: argument of type 'NoneType' is not iterable
P.S. Thank you for taking time to read this issue, and hopefully fix it.
Hello Maksim!
Allow me to be the first to create an issue hehe :)
Thanks for the tool, (the talk was great as well!)
Am trying to run the test.exe sample just to experiment but I'm getting the following error:
C:\Users\ida\Desktop\manul>C:\Users\ida\AppData\Local\Programs\Python\Python37\python.exe manul.py --logging_enable --debug -i in -o out -n 2 "win\test\test64.exe @@"
[WARNING] Output directory is not empty, creating backup of output folder
[INFO] Done
[WARNING] Too many fuzzing instances for 1 files, same files will be mutated with different seeds
[INFO] 2 fuzzer instances sucessfully launched
[INFO] Starting fuzzer 1
[INFO] Starting fuzzer 0
[INFO] Setting up shared mem 1565656325_1 for fuzzer:1
[INFO] Setting up shared mem 1565656325_0 for fuzzer:0
[INFO] Initializing mutators
[INFO] Performing dry run
Process Process-2:
Traceback (most recent call last):
File "C:\Users\ida\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 297, in _bootstrap
self.run()
File "C:\Users\ida\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\ida\Desktop\manul\manul.py", line 894, in run_fuzzer_instance
fuzzer_instance.run() # never return
File "C:\Users\ida\Desktop\manul\manul.py", line 752, in run
self.dry_run()
File "C:\Users\ida\Desktop\manul\manul.py", line 495, in dry_run
memset(self.trace_bits, 0x0, SHM_SIZE)
OSError: exception: access violation writing 0x000000001C100000
[INFO] Initializing mutators
[INFO] Performing dry run
Process Process-1:
Traceback (most recent call last):
File "C:\Users\ida\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 297, in _bootstrap
self.run()
File "C:\Users\ida\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\ida\Desktop\manul\manul.py", line 894, in run_fuzzer_instance
fuzzer_instance.run() # never return
File "C:\Users\ida\Desktop\manul\manul.py", line 752, in run
self.dry_run()
File "C:\Users\ida\Desktop\manul\manul.py", line 495, in dry_run
memset(self.trace_bits, 0x0, SHM_SIZE)
OSError: exception: access violation writing 0xFFFFFFFFAB7E0000
[WARNING] Fuzzer 0 unexpectedly terminated
[WARNING] Fuzzer 1 unexpectedly terminated
[WARNING] Fuzzer 0 unexpectedly terminated
[WARNING] Fuzzer 1 unexpectedly terminated
[WARNING] Fuzzer 0 unexpectedly terminated
I am using Python 3.7.2, I don't know why you recommend to use 3.4 (as it's officially has reached end-of-life). I did modified a few variables to see why this is happening, it looks like the memset comes from ctypes, but not sure why it's causing an issue here. Am I missing something here? Also, where's the code for binafl.dll
, are you going to release that?
Thanks so much!
bin_coverage.c:328:false (error accessing__AFL_SHM_ID)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.