Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to make boofuzz more compatible #594

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions boofuzz/fuzzable.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def __init__(self, name=None, default_value=None, fuzzable=True, fuzz_values=Non
Fuzzable.name_counter += 1
self._name = "{0}{1}".format(type(self).__name__, Fuzzable.name_counter)

self.index_mutation = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about mutation_index?

Suggested change
self.index_mutation = 0
self.mutation_index = 0


@property
def fuzzable(self):
"""If False, this element should not be mutated in normal fuzzing."""
Expand Down Expand Up @@ -132,6 +134,7 @@ def get_mutations(self):
if not self.fuzzable:
return
index = 0
self.index_mutation = 0
for value in itertools.chain(self.mutations(self.original_value()), self._fuzz_values):
if self._halt_mutations:
self._halt_mutations = False
Expand All @@ -141,6 +144,7 @@ def get_mutations(self):
elif isinstance(value, Mutation):
yield [value]
else:
self.index_mutation += 1
yield [Mutation(value=value, qualified_name=self.qualified_name, index=index)]
index += 1
finally:
Expand Down
8 changes: 5 additions & 3 deletions boofuzz/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ def _process_failures(self, target):
if not isinstance(self.fuzz_node.mutant, primitives.Group) and not isinstance(
self.fuzz_node.mutant, blocks.Repeat
):
skipped = max(0, self.fuzz_node.mutant.get_num_mutations() - self.mutant_index)
skipped = max(0, self.fuzz_node.mutant.get_num_mutations() - self.fuzz_node.mutant.index_mutation)
self._skip_current_element_after_current_test_case = True
self._fuzz_data_logger.open_test_step(
"Crash threshold reached for this element, exhausting {0} mutants.".format(skipped)
Expand Down Expand Up @@ -1051,8 +1051,10 @@ def _restart_target(self, target):
self._fuzz_data_logger.log_info("Restarting target process using {}".format(monitor.__class__.__name__))
if monitor.restart_target(target=target, fuzz_data_logger=self._fuzz_data_logger, session=self):
# TODO: doesn't this belong in the process monitor?
self._fuzz_data_logger.log_info("Giving the process 3 seconds to settle in")
time.sleep(3)
self._fuzz_data_logger.log_info(
"Giving the process %d seconds to settle in" % self.restart_sleep_time
)
time.sleep(self.restart_sleep_time)
restarted = True
break

Expand Down
31 changes: 19 additions & 12 deletions boofuzz/utils/debugger_thread_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,23 @@ def run(self):
gone, _ = psutil.wait_procs([self._psutil_proc])
self.exit_status = gone[0].returncode
else:
exit_info = os.waitpid(self.pid, 0)
self.exit_status = exit_info[1] # [0] is the pid
# Waitpid doesn't work well on windows, switching to _process.wait()
self.exit_status = self._process.wait()

default_reason = "Process died for unknown reason"
if self.exit_status is not None:
if os.WCOREDUMP(self.exit_status):
reason = "Segmentation fault"
elif os.WIFSTOPPED(self.exit_status):
reason = "Stopped with signal " + str(os.WTERMSIG(self.exit_status))
elif os.WIFSIGNALED(self.exit_status):
reason = "Terminated with signal " + str(os.WTERMSIG(self.exit_status))
elif os.WIFEXITED(self.exit_status):
reason = "Exit with code - " + str(os.WEXITSTATUS(self.exit_status))
else:
try:
if os.WCOREDUMP(self.exit_status):
reason = "Segmentation fault"
elif os.WIFSTOPPED(self.exit_status):
reason = "Stopped with signal " + str(os.WTERMSIG(self.exit_status))
elif os.WIFSIGNALED(self.exit_status):
reason = "Terminated with signal " + str(os.WTERMSIG(self.exit_status))
elif os.WIFEXITED(self.exit_status):
reason = "Exit with code - " + str(os.WEXITSTATUS(self.exit_status))
else:
reason = default_reason
except AttributeError: # Windows does not support WCOREDUMP
reason = default_reason
else:
reason = default_reason
Expand Down Expand Up @@ -208,7 +211,11 @@ def get_exit_status(self):

def stop_target(self):
try:
os.kill(self.pid, signal.SIGKILL)
try:
os.kill(self.pid, signal.SIGKILL)
except AttributeError:
# Windows does not support signal.SIGKILL
os.system("taskkill /F /PID:%d" % self.pid)
except OSError as e:
print(
'Error while killing process. PID: {0} errno: {1} "{2}"'.format(self.pid, e.errno, os.strerror(e.errno))
Expand Down
19 changes: 7 additions & 12 deletions process_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from boofuzz.utils.process_monitor_pedrpc_server import ProcessMonitorPedrpcServer


def serve_procmon(port, crash_bin, proc_name, ignore_pid, log_level):
def serve_procmon(ip, port, crash_bin, proc_name, ignore_pid, log_level):
with ProcessMonitorPedrpcServer(
host="0.0.0.0",
host=ip,
port=port,
crash_filename=crash_bin,
debugger_class=DebuggerThreadSimple,
Expand All @@ -20,14 +20,6 @@ def serve_procmon(port, crash_bin, proc_name, ignore_pid, log_level):
servlet.serve_forever()


# app.args.add_argument("-c", "--crash_bin", help='filename to serialize crash bin class to',
# default='boofuzz-crash-bin', metavar='FILENAME')
# app.args.add_argument("-i", "--ignore_pid", help='PID to ignore when searching for target process', type=int,
# metavar='PID')
# app.args.add_argument("-l", "--log_level", help='log level: default 1, increase for more verbosity', type=int,
# default=1, metavar='LEVEL')
# app.args.add_argument("-p", "--proc_name", help='process name to search for and attach to', metavar='NAME')
# app.args.add_argument("-P", "--port", help='TCP port to bind this agent to', type=int, default=DEFAULT_PROCMON_PORT)
@click.command()
@click.option(
"--crash-bin",
Expand Down Expand Up @@ -56,8 +48,11 @@ def serve_procmon(port, crash_bin, proc_name, ignore_pid, log_level):
)
@click.option("--proc-name", "--proc_name", "-p", help="process name to search for and attach to", metavar="NAME")
@click.option("--port", "-P", help="TCP port to bind this agent to", type=int, default=DEFAULT_PROCMON_PORT)
def go(crash_bin, ignore_pid, log_level, proc_name, port):
serve_procmon(port=port, crash_bin=crash_bin, proc_name=proc_name, ignore_pid=ignore_pid, log_level=log_level)
@click.option(
"--ip", "-I", help="Listen on this IP for incoming connections from boofuzz", type=str, default="127.0.0.1"
)
def go(crash_bin, ignore_pid, log_level, proc_name, port, ip):
serve_procmon(ip, port=port, crash_bin=crash_bin, proc_name=proc_name, ignore_pid=ignore_pid, log_level=log_level)


if __name__ == "__main__":
Expand Down
10 changes: 7 additions & 3 deletions process_monitor_unix.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def err(msg):
sys.stderr.write("ERR> " + msg + "\n") or sys.exit(1)


def serve_procmon(port, crash_bin, proc_name, ignore_pid, log_level, coredump_dir):
def serve_procmon(ip, port, crash_bin, proc_name, ignore_pid, log_level, coredump_dir):
with ProcessMonitorPedrpcServer(
host="0.0.0.0",
host=ip,
port=port,
crash_filename=crash_bin,
debugger_class=DebuggerThreadSimple,
Expand Down Expand Up @@ -92,11 +92,15 @@ def serve_procmon(port, crash_bin, proc_name, ignore_pid, log_level, coredump_di
help="directory where coredumps are moved to (you may need to adjust ulimits to create coredumps)",
default="coredumps",
)
def go(crash_bin, ignore_pid, log_level, proc_name, port, coredump_dir):
@click.option(
"--ip", "-I", help="Listen on this IP for incoming connections from boofuzz", type=str, default="127.0.0.1"
)
def go(crash_bin, ignore_pid, log_level, proc_name, port, coredump_dir, ip):
if coredump_dir is not None:
helpers.mkdir_safe(coredump_dir)

serve_procmon(
ip,
port=port,
crash_bin=crash_bin,
proc_name=proc_name,
Expand Down