/usr/share/fusil/fusil-gimp is in fusil 1.5-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | #! /usr/bin/python
"""
Gimp fuzzer.
"""
from __future__ import print_function, with_statement
from fusil.application import Application
from optparse import OptionGroup
from fusil.process.create import CreateProcess
from fusil.process.watch import WatchProcess
from fusil.process.stdout import WatchStdout
from fusil.auto_mangle import AutoMangle
from fusil.dummy_mangle import DummyMangle
from os.path import basename
PROGRAM = 'gimp'
NB_FILES = 25
MAX_FILESIZE = 1024*1024
class Fuzzer(Application):
NAME = "gimp"
USAGE = "%prog [options] image1 [image2 ...]"
NB_ARGUMENTS = (1, None)
def createFuzzerOptions(self, parser):
options = OptionGroup(parser, "Gimp")
options.add_option("--nb-files", help="Number of generated files (default: %s)" % NB_FILES,
type="int", default=NB_FILES)
options.add_option("--program", help="Gimp program path (default: %s)" % PROGRAM,
type="str", default=PROGRAM)
options.add_option("--filesize", help="Maximum file size in bytes (default: %s)" % MAX_FILESIZE,
type="int", default=MAX_FILESIZE)
options.add_option("--test", help="Test mode (no fuzzing, just make sure that the fuzzer works)",
action="store_true")
return options
def setupProject(self):
if self.options.test:
DummyMangle(self.project, self.arguments)
else:
mangle = AutoMangle(self.project, self.arguments, self.options.nb_files)
mangle.max_size = self.options.filesize
# Create the process
arguments = [self.options.program,
'--no-interface',
# '--verbose',
'--batch-interpreter', 'plug-in-script-fu-eval',
'--batch', '-']
process = GimpProcess(self.project, arguments)
WatchProcess(process)
stdout = WatchStdout(process)
stdout.ignoreRegex('fatal parse error')
# > Error: Procedure execution of gimp-file-load failed: This XCF file is corrupt!
# I could not even salvage any partial image data from it.
stdout.ignoreRegex('file is corrupt')
stdout.max_nb_line = None
del stdout.words['warning']
del stdout.words['error']
class GimpProcess(CreateProcess):
def init(self):
CreateProcess.init(self)
self.script_filename = None
def on_mangle_filenames(self, filenames):
self.script_filename = self.session().createFilename("script")
filenames_str = ' '.join('"%s"' % basename(filename) for filename in filenames)
with open(self.script_filename, "w") as fp:
print('(gimp-message "Start Gimp fuzzer")', file=fp)
print('(define (fuzzfiles n f)', file=fp)
print(' (let* (', file=fp)
print(' (fname (car f))', file=fp)
print(' (img 0)', file=fp)
print(' )', file=fp)
print(' (gimp-message fname)', file=fp)
print(' (set! img (car (gimp-file-load RUN-NONINTERACTIVE fname fname)))', file=fp)
print(' (gimp-image-delete img)', file=fp)
print(' (if (= n 1) 1 (fuzzfiles (- n 1) (cdr f)))', file=fp)
print(' )', file=fp)
print(')', file=fp)
print("(fuzzfiles %s '(%s))" % (len(filenames), filenames_str), file=fp)
print('(gimp-quit 0)', file=fp)
self.createProcess()
def createStdin(self):
return open(self.script_filename, 'rb')
if __name__ == "__main__":
Fuzzer().main()
|