import sys import click from boofuzz import helpers from boofuzz.constants import DEFAULT_PROCMON_PORT from boofuzz.utils.debugger_thread_simple import DebuggerThreadSimple from boofuzz.utils.process_monitor_pedrpc_server import ProcessMonitorPedrpcServer """ By nnp http://www.unprotectedhex.com This intended as a basic replacement for Sulley's process_monitor.py on *nix. The below options are accepted. Crash details are limited to the signal that caused the death and whatever operating system supported mechanism is in place (i.e core dumps) Replicated methods: - alive - log - post_send - pre_send - start_target - stop_target - set_start_commands - set_stop_commands Limitations - Cannot attach to an already running process - Currently only accepts one start_command - Limited 'crash binning'. Relies on the availability of core dumps. These should be created in the same directory the process is ran from on Linux and in the (hidden) /cores directory on OS X. On OS X you have to add the option COREDUMPS=-YES- to /etc/hostconfig and then `ulimit -c unlimited` as far as I know. A restart may be required. The file specified by crash_bin will any other available details such as the test that caused the crash and the signal received by the program """ 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): with ProcessMonitorPedrpcServer( host="0.0.0.0", port=port, crash_filename=crash_bin, debugger_class=DebuggerThreadSimple, proc_name=proc_name, pid_to_ignore=ignore_pid, level=log_level, coredump_dir=coredump_dir, ) as servlet: servlet.serve_forever() @click.command() @click.option( "--crash-bin", "--crash_bin", "-c", help="filename to serialize crash bin class to", default="boofuzz-crash-bin", metavar="FILENAME", ) @click.option( "--ignore-pid", "--ignore_pid", "-i", type=int, help="PID to ignore when searching for target process", metavar="PID", ) @click.option( "--log-level", "--log_level", "-l", help="log level: default 1, increase for more verbosity", type=int, default=1, metavar="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) @click.option( "--coredump-dir", "--coredump_dir", "-d", 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): if coredump_dir is not None: helpers.mkdir_safe(coredump_dir) serve_procmon( port=port, crash_bin=crash_bin, proc_name=proc_name, ignore_pid=ignore_pid, log_level=log_level, coredump_dir=coredump_dir, ) if __name__ == "__main__": go()