def setupProject(project): orig_filename = project.application().getInputFilename("OGG/Vorbis file") mangle = OggMangle(project, orig_filename) if not INCR_MANGLE: mangle.hard_min_op = 1 mangle.hard_max_op = 100 else: from fusil.incr_mangle_op import InverseBit, Increment mangle.operations = (InverseBit, Increment) mangle.max_filesize = FILESIZE process = OggProcess(project, COMMAND, timeout=60.0) process.env.copy('HOME') if COMMAND[0] == 'ogg123': WatchProcess(process, exitcode_score=-0.25) else: WatchProcess(process, exitcode_score=0) stdout = WatchStdout(process) if True: # stdout.max_nb_line = (5000, 1.0) stdout.show_matching = True stdout.show_not_matching = True stdout.addRegex(r"The file may be corrupted", -0.50) stdout.addRegex(r"Corrupted ogg", -0.50) stdout.addRegex(r"Could not decode vorbis header packet", -0.50) # stdout.ignoreRegex('^Warning: Could not decode vorbis header packet') stdout.ignoreRegex('^Warning: sequence number gap') stdout.ignoreRegex('^New logical stream.*: type invalid$')
def setupProject(project): VIM = EnvVarLength(['VIM', 'VIMRUNTIME'], max_length=10000) process = ProjectProcess(project, ['vim', '--version']) process.env.add(VIM) WatchProcess(process) WatchStdout(process)
def setupProject(project): IGNORE_SYSCALLS = set(( 2, 120, 190, # fork, clone, vfork 29, 72, # pause, sigsuspend (suspend until signal send) 88, # reboot 91, # munmap 113, 166, # vm86old, vm86: enter VM86 mode (virtual-8086 in Intel literature) 119, 173, # sigreturn, rt_sigreturn 162, # nanosleep 252, # epoll_wait )) syscall = GenerateSyscall(project) syscall.fixed_arguments[SYS_EXIT] = {1: "0"} syscall.fixed_arguments[SYS_OLD_SELECT] = {5: "0"} syscall.syscalls = list(set(SYSCALL_NAMES.keys()) - IGNORE_SYSCALLS) process = SyscallProcess(project, name="syscall") WatchProcess(process) syslog = Syslog(project) syslog.syslog.patterns['syscall'] = 1.0 syslog.messages.patterns['syscall'] = 1.0
def setupProject(self): self.project.debugger.enabled = False FuzzedHttpServer(self.project, 8898) process = ProjectProcess( self.project, [ 'python3', '-m', 'wpull', '127.0.0.1:8898', '--timeout', '2.0', '--tries', '1', ], ) process.max_memory = 500000000 process.env.set( 'PYTHONPATH', os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', '..')) WatchProcess(process, exitcode_score=0.45) stdout_watcher = WatchStdout(process) stdout_watcher.ignoreRegex(r'Read timed out', ) stdout_watcher.ignoreRegex(r'Error parsing status line', ) stdout_watcher.ignoreRegex( r'WARNING Invalid content length: invalid literal for int') stdout_watcher.ignoreRegex(r'encountered an error: zlib error: ')
def setupProject(project): process = MyProcess(project, ['/usr/bin/at'], timeout=5.0) WatchProcess(process, exitcode_score=0.15) stdout = WatchStdout(process) stdout.ignoreRegex(r'Bug reports to') stdout.words['error'] = 0.10 stdout.words['usage'] = 0.10
def setupProject(project): process = ProjectProcess(project, ['xterm', 'ls'], timeout=1.0) setupX11Process(process) process.env.add(EnvVarLength('PATH', max_length=1000)) WatchProcess(process, timeout_score=0) WatchStdout(process)
def setupProject(project): # Locate MO full path mo_filename = 'libc.mo' COMMAND = ['/bin/bash', '/nonexistantpath'] orig_filename = locateMO(project, COMMAND, mo_filename) # Create (...)/LC_MESSAGES/ directory LocaleDirectory(project, "locale_dir") # Create mangled MO file mangle = MangleGettext(project, orig_filename) mangle.max_size = None mangle.config.max_op = 2000 # Run program with fuzzy MO file and special LANGUAGE env var process = GettextProcess(project, COMMAND) process.timeout = 10.0 process.env.add(EnvVarValue('LANGUAGE')) process.env.copy('LANG') # Watch process failure with its PID # Ignore bash exit code (127: command not found) WatchProcess(process, exitcode_score=0) # Watch process failure with its text output stdout = WatchStdout(process) stdout.words['failed'] = 0
def setupProject(project): # Use non trival program to make sure that libc uses many environment variables # COMMAND = ['/bin/bash', '-c', 'echo "Hello World!"'] COMMAND = ['python', '-c', 'print "Hello World!"'] MAX_COUNT = 5 # Run program with fuzzed environment variables vars = list(LIBC_VARIABLES) if False: # AVOID libc bugs vars.remove('LD_HWCAP_MASK') vars.remove('MALLOC_TOP_PAD_') if False: var = EnvVarInteger(vars, max_count=MAX_COUNT) elif False: var = EnvVarLength(vars, max_count=MAX_COUNT) elif False: var = EnvVarRandom(vars, max_length=200, max_count=MAX_COUNT) var.characters = LETTERS | PUNCTUATION else: var = EnvVarRandom(vars, max_length=2000, max_count=MAX_COUNT) process = ProjectProcess(project, COMMAND) process.env.add(var) # Watch process failure with its PID WatchProcess(process) # Watch process failure with its text output stdout = WatchStdout(process) stdout.words['failed'] = 0
def setupProject(project): orig_filename = project.application().getInputFilename("JPEG picture") if INCR_MANGLE: mangle = IncrMangle(project, orig_filename) mangle.operation_per_version = 25 mangle.max_version = 50 # mangle.min_offset = 2 # mangle.max_offset = 555 else: AutoMangle(project, orig_filename) process = IdentifyProcess(project, ['exif', "<picture>"]) WatchProcess(process, # exitcode_score=-0.50, exitcode_score=0, ) stdout = WatchStdout(process) stdout.min_nb_line = (3, -0.5) stdout.words['error'] = 0.10 # "Color Space |Internal error (unknown value 4097)." is not a fatal error # stdout.ignoreRegex(r'Internal error \(unknown value') # stdout.addRegex(r'^Corrupt data', -1.0) # stdout.addRegex(r'does not contain EXIF data!$', -1.0) stdout.addRegex(r'The data supplied does not seem to contain EXIF data.$', -1.0) stdout.addRegex(r'does not contain EXIF data!$', -1.0) stdout.addRegex(r'^Unknown encoding\.$', -1.0) if DEBUG: stdout.show_not_matching = True
def setupProject(self): parrot_root = self.options.parrot_root runcore = self.options.runcore parrot = locateProgram(parrot_root + "/parrot") process = ParrotProcess(self.project, [parrot, runcore, "<fuzzy.pir>"]) pirgen = PirGenerator(self.project, self.options) WatchProcess(process) WatchStdout(process)
def setupProject(project): ioctl = GenerateIOCTL(project) process = IoctlProcess(project, name="ioctl") WatchProcess(process) syslog = Syslog(project) logs = [syslog.syslog, syslog.messages] for log in logs: log.show_not_matching = True
def __init__(self, project, program): ProjectAgent.__init__(self, project, "unix") self.program = program self.process = CreateProcess(project, name=basename(program)) self.watch = WatchProcess(self.process) self.states = ("help", "stop") self.state = 0 self.help_arguments = ("--help", "-help", "-h") self.state_data = None
def setupProject(project): # project.session_timeout = 1.0 process = ProjectProcess(project, ['/bin/bash'], timeout=5.0) AttackProc(project) WatchProcess(process, timeout_score=0) WatchStdout(process) syslog = Syslog(project) for watch in syslog: watch.ignoreRegex('info="invalid command"') watch.show_not_matching = True
def setupProject(project): USE_STDOUT = True time = ProcessTimeWatch( project, too_slow=3.0, too_slow_score=0.10, too_fast=0.100, too_fast_score=-0.80, ) orig_filename = project.application().getInputFilename("PDF document") if AUTO_MANGLE: mangle = AutoMangle(project, orig_filename) mangle.hard_max_op = 1000 else: mangle = MangleFile(project, orig_filename) mangle.config.max_op = 1000 options = {'timeout': 5.0} if not USE_STDOUT: options['stdout'] = 'null' process = PopplerProcess(project, ['pdftotext'], **options) WatchProcess(process, exitcode_score=-0.10) if USE_STDOUT: stdout = WatchStdout(process) def cleanupLine(line): match = re.match(r"Error(?: \([0-9]+\))?: (.*)", line) if match: line = match.group(1) return line stdout.cleanup_func = cleanupLine del stdout.words['unknown'] # stdout.show_not_matching = True # stdout.ignoreRegex(r"Unknown operator 'allocate'$") # stdout.ignoreRegex(r" operator is wrong type \(error\)$") # stdout.ignoreRegex(r'^No current point in lineto$') # stdout.ignoreRegex(r'^No current point in lineto') # stdout.ignoreRegex(r'^Unknown operator ') # stdout.ignoreRegex(r"^Couldn't open 'nameToUnicode' file ") # stdout.ignoreRegex(r"^Illegal character ") # stdout.ignoreRegex(r"^No font in show$") # stdout.ignoreRegex(r"^Element of show/space array must be number or string$") # stdout.ignoreRegex(r"^No current point in curveto$") # stdout.ignoreRegex(r"^Badly formatted number$") # stdout.ignoreRegex(r"^Dictionary key must be a name object$") # stdout.ignoreRegex(r"^End of file inside array$") # stdout.ignoreRegex(r"^Too few \([0-9]+\) args to .* operator$") # stdout.ignoreRegex(r"Too many args in content stream") stdout.max_nb_line = (100, 0.20)
def setupProject(project): orig_filename = project.application().getInputFilename("RPM archive") mangle = MangleRPM(project, orig_filename) if True: mangle.config.max_op = 200 else: mangle.config.min_op = 0 mangle.config.max_op = 0 process = RpmProcess(project, ['/usr/bin/rpm', '-qpi', 'file.rpm'], timeout=10.0) WatchProcess(process) stdout = WatchStdout(process) stdout.patterns['memory allocation failed'] = 1.0
def setupProject(project): for filename in FILENAMES: if path_exists(filename): continue raise ValueError("File doesn't exist: %s! Fix FILENAMES constant" % filename) module_name = project.application().getInputFilename( 'Module name (use "ALL" to test all modules)') project.error("Use python interpreter: %s" % PYTHON) project.error("Use filenames: %s" % ', '.join(FILENAMES)) source = PythonSource(project, module_name) process = PythonProcess(project, [PYTHON, '-u', '<source.py>'], timeout=10.0, stdin='null') WatchProcess(process, exitcode_score=0) stdout = WatchStdout(process) stdout.max_nb_line = (1000, 1.0) # Disable dummy error messages stdout.words = { 'oops': 0.30, 'bug': 0.30, 'memory': 0.40, 'overflow': 0.40, 'fatal': 1.0, 'assert': 1.0, 'assertion': 1.0, 'critical': 1.0, 'panic': 1.0, 'glibc detected': 1.0, 'segfault': 1.0, 'segmentation fault': 1.0, } # PyPy messages stdout.addRegex("Fatal RPython error", 1.0) if DEBUG: stdout.show_matching = True stdout.show_not_matching = True
def setupProject(project): MAX_MEMORY = 200 * 1024 * 1024 if True: firefox = FirefoxProcess(project, ["firefox", '-safe-mode', HOMEPAGE_URL], timeout=None) setupX11Process(firefox) firefox.max_memory = MAX_MEMORY WatchProcess(firefox) else: fireboxbin = AttachProcess(project, 'firefox-bin') fireboxbin.max_memory = MAX_MEMORY orig_filename = project.application().getInputFilename( "JPEG image filename") filename_ext = filenameExtension(orig_filename) AutoMangle(project, orig_filename, nb_file=NB_FILES) FuzzyHttpServer(project, PORT, filename_ext, rows=ROWS) FirefoxWindow(project)
def setupProject(project): printf = GeneratePrintfProgram(project) printf.max_nb_arg = 10 # AVOID printf("%*d", 10000000, 42) crash # printf.max_width = 10*1000 # AVOID "%.10000000s" crash # printf.max_precision = 10*1000 # AVOID "%10000000hc" crash del printf.modifiers['char']['h'] # AVOID "%qp" and "%llC" crashes for size in ('char', 'wide char', 'pointer'): for key in ('ll', 'q', 'j'): del printf.modifiers[size][key] process = PrintfProcess(project, name="printf", stdout='null') WatchProcess(process)
def setupProject(self): project = self.project orig_filename = self.arguments[0] mangle = Mp3Mangle(project, orig_filename) mangle.max_size = 50*1024 if MANGLE == "auto": "nothing" #mangle.hard_min_op = 1 #mangle.hard_max_op = 100 elif MANGLE == "incr": from fusil.incr_mangle_op import InverseBit, Increment mangle.operations = (InverseBit, Increment) else: mangle.config.min_op = 0 #mangle.config.max_op = 10 process = MangleProcess(project, ['./fuzzer_client.rb', '<mp3>'], '<mp3>', timeout=60.0) #process.env.copy('HOME') WatchProcess(process) #, exitcode_score=0.50)
def setupProject(project): DEBUG_PROJECT = True php = PhpSource(project) # Don't kill any process! php.ignore_functions.add('posix_kill') # Avoid timeout php.ignore_functions.add('ftp_connect') php.ignore_functions.add('mysql_connect') php.ignore_functions.add('mysql_pconnect') php.ignore_functions.add('dns_get_mx') php.ignore_functions.add('getmxrr') php.ignore_functions.add('dns_check_record') php.ignore_functions.add('pfsockopen') php.ignore_functions.add('dns_get_record') php.ignore_functions.add('gethostbynamel') php.ignore_functions.add('ftp_ssl_connect') process = PhpProcess(project, ['php', '<source.php>'], timeout=10.0) watch = WatchProcess(process, exitcode_score=0.10) if watch.cpu: watch.cpu.score_weight = 0.3 stdout = WatchPhpStdout(process, php) stdout.max_nb_line = (5000, 1.0) del stdout.words['memory'] del stdout.words['exception'] stdout.addRegex('Call to undefined function', -1.0) if DEBUG_PROJECT: stdout.words['warning'] = 0.01 stdout.words['error'] = 0.01 stdout.words['fatal'] = 0.10 stdout.words['assert'] = 0.01 stdout.words['assertion'] = 0.01 stdout.ignoreRegex("Only variables can be passed by reference") stdout.ignoreRegex("^Fatal error: Can't use function return value in ") stdout.ignoreRegex("^Fatal error: Class .* not found") stdout.ignoreRegex("^Parse error:") stdout.ignoreRegex("sem_get.*Permission denied") else: stdout.score_weight = 0.3
def setupProject(project): # Some options DEBUG = False USE_STDOUT = DEBUG sql = GenerateSQL(project, "sql") if DEBUG: sql.max_nb_instr = 1 # Watch mysqld process mysqld = AttachProcess(project, 'mysqld') mysqld.max_memory = 300*1024*1024 if USE_STDOUT: stdout = 'file' else: stdout = 'null' # MySQL client used to send fuzzy SQL process = MysqlProcess(project, ['/usr/bin/mysql'], stdout) WatchProcess(process, exitcode_score=0.15, timeout_score=0.15) if USE_STDOUT: stdout = WatchStdout(process) stdout.ignoreRegex('You have an error in your SQL syntax; check the manual') if not DEBUG: stdout.words['error'] = 0.10 else: stdout.words['error'] = 1.0 # Watch logs syslog = Syslog(project) mysql_log = FileWatch(project, open('/var/log/mysql/mysql.log'), 'mysql.log', start="end") # FileWatch(project, open('/var/log/mysql/mysql.err'), 'mysql.err', start="end"), logs = [ syslog.syslog, syslog.messages, mysql_log, ] for log in logs: log.words['mysqld'] = 1.0
def setupProject(project): global CMDLINE_ARG_POS orig_filename = project.application().getInputFilename("Image") mangle = ImageMangle(project, orig_filename) if INCR_MANGLE: mangle.operation_per_version = 1 mangle.max_version = 50 else: mangle.fixed_size_factor = 0.5 options = {'timeout': 2.0} if USE_CONVERT: cmdline = ['convert', '<source>', '/tmp/output.bmp'] CMDLINE_ARG_POS = 1 else: cmdline = ['identify', '-verbose', '<source>'] CMDLINE_ARG_POS = -1 if not USE_STDOUT: options['stdout'] = 'null' process = IdentifyProcess(project, cmdline, **options) options = {'exitcode_score': -0.25} if orig_filename.endswith(".jpg"): # Don't care about libjpeg stdout flooding options['timeout_score'] = -0.25 WatchProcess(process, **options) if USE_STDOUT: stdout = WatchStdout(process) stdout.max_nb_line = (3000, 0.20) stdout.patterns['memory allocation failed'] = 1.0 stdout.patterns['no decode delegate for this image format'] = -1.0 stdout.addRegex('Corrupt', 0.05) stdout.addRegex('Unsupported', 0.05) stdout.addRegex('Not a JPEG file', -0.50) stdout.addRegex('JPEG datastream contains no image', -0.50) stdout.show_not_matching = False
def computeScore(self, status): if status in (4, 6, 7, 8): print('Change status', status, 'to 0.') status = 0 return WatchProcess.computeScore(self, status)
def setupProject(project): FileWatch(project, open('/var/log/Xorg.0.log'), "Xorg.log", start="end") GenerateCode(project, "x11.c") process = X11Process(project, name="x11") process.env.copy('DISPLAY') WatchProcess(process)
def setupProject(self): self.project.debugger.enabled = False self.config.use_cpu_probe = False self.config.process_max_user_process = 50 port = 8848 seed = random.randint(0, 60000) timeout = 60 * 60 server_process = ProjectProcess(self.project, [ 'python3', '-m', 'huhhttp', '--port', str(port), '--seed', str(seed), '--fuzz-period', '500', '--restart-interval', '250', ], timeout=timeout) WatchProcess(server_process) process = ProjectProcess(self.project, [ 'python3', '-X', 'faulthandler', '-m', 'wpull', '127.0.0.1:{0}'.format(port), '--timeout', '5', '--warc-file', 'fusil-test', '-r', '--debug', '--page-requisites', '--delete-after', '--tries', '2', '--retry-connrefused', '--database', 'wpull.db', '--span-hosts-allow', 'page-requisites,linked-pages', '--no-check-certificate', '--concurrent', str(random.randint(1, 10)), ], timeout=timeout) process.env.set( 'PYTHONPATH', os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', '..')) process.env.set('OBJGRAPH_DEBUG', '1') process.env.set('FILE_LEAK_DEBUG', '1') WatchProcessSpecificStatusCode(process) stdout_watcher = WatchStdout(process) stdout_watcher.max_nb_line = None stdout_watcher.ignoreRegex( r'WARNING Invalid content length: invalid literal for int') stdout_watcher.ignoreRegex(r'WARNING Unable to parse URL ') stdout_watcher.ignoreRegex(r'WARNING Failed to read document at ') stdout_watcher.ignoreRegex(r'WARNING Content overrun') stdout_watcher.ignoreRegex(r'ERROR Fetching ') stdout_watcher.ignoreRegex(r'DEBUG ') stdout_watcher.ignoreRegex(r'INFO Fetch(ed|ing) ') stdout_watcher.ignoreRegex(r'lsof: WARNING: ')
def setupProject(project): TIMEOUT = 4 GST_LAUNCH_BIN = 'gst-launch-0.10' USE_DECODEBIN = True NO_AUDIO = True NO_VIDEO = True # Profile parameters AUDIO_SINK = "alsasink" VIDEO_SINK = "xvimagesink" if NO_AUDIO: AUDIO_SINK = "fakesink" if NO_VIDEO: VIDEO_SINK = "fakesink" # Create buggy input file orig_filename = project.application().getInputFilename("Audio or video file") if INCR_MANGLE: mangle = IncrMangle(project, orig_filename) mangle.max_size = 50*1024 # OGG #mangle.operation_per_version = 10 #mangle.max_version = 100 # WAVE #mangle.operation_per_version = 100 #mangle.max_version = 30 # AVI mangle.operation_per_version = 500 mangle.max_version = 50 else: mangle = AutoMangle(project, orig_filename) mangle.hard_max_op = 500 mangle.max_size = 10*1024*1024 if USE_DECODEBIN: # -f option: Do not install a fault handler arguments = [GST_LAUNCH_BIN, '-f', "filesrc", "location=<filename>", "!", "decodebin", "name=decoder", "decoder.", "!", "queue", "!", "audioconvert", "!", "audioresample", "!", AUDIO_SINK] if isVideo(orig_filename): arguments.extend(["decoder.", "!", "ffmpegcolorspace", "!", VIDEO_SINK]) class GstreamerProcess(CreateProcess): def on_mangle_filenames(self, movie_filenames): self.cmdline.arguments[3] = 'location=' + movie_filenames[0] self.createProcess() else: arguments = [GST_LAUNCH_BIN, '-f', 'playbin', 'uri=file://<playbin_uri>'] class GstreamerProcess(CreateProcess): def on_mangle_filenames(self, movie_filenames): self.cmdline.arguments[3] = 'uri=file://%s' % movie_filenames[0] self.createProcess() process = GstreamerProcess(project, arguments, timeout=TIMEOUT) WatchProcess(process, exitcode_score=0.20, timeout_score=0.20) #, timeout_score=0) setupX11Process(process) stdout = WatchStdout(process) stdout.words['error'] = 0.10 stdout.words['critical'] = 0.30 del stdout.words['assertion'] stdout.addRegex(r'Could not decode stream\.$', -1.0) stdout.addRegex(r'Could not (?:decode stream|determine type of stream|demultiplex stream)\.$', -1.0) stdout.addRegex(r'The stream is of a different type than handled by this element\.$', -1.0) stdout.addRegex(r'You might need to install the necessary plugins', 1.0) stdout.score_weight = 0.40
def computeScore(self, status): if status in (4, 6, 7, 8): print('Change status', status, 'to 0.') status = 0 return WatchProcess.computeScore(self, status)
def setupProject(project): # Command line MAX_FILESIZE = 1 * 1024 * 1024 ARGUMENTS = ['-quiet'] MPLAYER_BIN = 'mplayer' NULL_VIDEO = True if NULL_VIDEO: ARGUMENTS.extend(['-vo', 'null', '-ao', 'null']) if True: SECONDS = 5 TIMEOUT = SECONDS + 1.0 ARGUMENTS.extend(['-endpos', str(SECONDS)]) else: TIMEOUT = 7.0 # Create buggy input file orig_filename = project.application().getInputFilename( "Audio or video file") mangle = AutoMangle(project, orig_filename) mangle.max_size = MAX_FILESIZE process = MplayerProcess(project, [MPLAYER_BIN] + ARGUMENTS + ["<movie_filename>"], timeout=TIMEOUT) if not NULL_VIDEO: setupX11Process(process) else: process.env.copy('HOME') watch = WatchProcess(process, timeout_score=0) if watch.cpu: watch.cpu.weight = 0.20 watch.cpu.max_load = 0.50 watch.cpu.max_duration = min(3, TIMEOUT - 0.5) watch.cpu.max_score = 0.50 stdout = WatchStdout(process) # Ignore input errors stdout.ignoreRegex('^Failed to open LIRC support') stdout.ignoreRegex("^Can't init input joystick$") stdout.ignoreRegex("^Can't open joystick device ") # Ignore codec loading errors stdout.ignoreRegex('^Failed to create DirectShow filter$') stdout.ignoreRegex('^Win32 LoadLibrary failed') stdout.ignoreRegex('^Error loading dll$') stdout.ignoreRegex('^ERROR: Could not open required DirectShow codec ') stdout.ignoreRegex("could not open DirectShow") # Ignore other errors stdout.ignoreRegex("^Terminal type `unknown' is not defined.$") stdout.ignoreRegex('^VDecoder init failed') stdout.ignoreRegex("Read error at pos\. [0-9]+") stdout.ignoreRegex("could not connect to socket") stdout.ignoreRegex('^ADecoder init failed') stdout.ignoreRegex('^error while decoding block:') stdout.ignoreRegex('^Error while decoding frame!$') stdout.ignoreRegex('^\[(mpeg4|msmpeg4|wmv1|h264|NULL) @ ') stdout.patterns['overflow'] = 0.10 # stdout.words['error'] = 0.10 # stdout.words["can't"] = 0 stdout.addRegex('MPlayer interrupted by signal', 1.0) stdout.addRegex('AVI: Missing video stream', -0.50) stdout.max_nb_line = None # Restore terminal state TerminalEcho(project)