def main(): """ Main function, called when vipermonkey is run from the command line """ # print banner with version print ('vmonkey %s - https://github.com/decalage2/ViperMonkey' % __version__) print ('THIS IS WORK IN PROGRESS - Check updates regularly!') print ('Please report any issue at https://github.com/decalage2/ViperMonkey/issues') print ('') DEFAULT_LOG_LEVEL = "info" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) # parser.add_option('-o', '--outfile', dest='outfile', # help='output file') # parser.add_option('-c', '--csv', dest='csv', # help='export results to a CSV file') parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option("-z", "--zip", dest='zip_password', type='str', default=None, help='if the file is a zip archive, open first file from it, using the provided password (requires Python 2.6+)') parser.add_option("-f", "--zipfname", dest='zip_fname', type='str', default='*', help='if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)') parser.add_option("-e", action="store_true", dest="scan_expressions", help='Extract and evaluate/deobfuscate constant expressions') parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help="logging level debug/info/warning/error/critical (default=%default)") parser.add_option("-a", action="store_true", dest="altparser", help='Use the alternate line parser (experimental)') (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print __doc__ parser.print_help() sys.exit() # setup logging to the console # logging.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(levelname)-8s %(message)s') colorlog.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(log_color)s%(levelname)-8s %(message)s') for container, filename, data in xglob.iter_files(args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue if options.scan_expressions: process_file_scanexpr(container, filename, data) else: process_file(container, filename, data, altparser=options.altparser)
def main(): # print banner with version print ('oleobj %s - http://decalage.info/oletools' % __version__) print ('THIS IS WORK IN PROGRESS - Check updates regularly!') print ('Please report any issue at https://github.com/decalage2/oletools/issues') print ('') DEFAULT_LOG_LEVEL = "warning" # Default log level LOG_LEVELS = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) # parser.add_option('-o', '--outfile', dest='outfile', # help='output file') # parser.add_option('-c', '--csv', dest='csv', # help='export results to a CSV file') parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option("-d", type="str", dest="output_dir", help='use specified directory to output files.', default=None) parser.add_option("-z", "--zip", dest='zip_password', type='str', default=None, help='if the file is a zip archive, open first file from it, using the provided password (requires Python 2.6+)') parser.add_option("-f", "--zipfname", dest='zip_fname', type='str', default='*', help='if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)') parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help="logging level debug/info/warning/error/critical (default=%default)") (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print (__doc__) parser.print_help() sys.exit() # Setup logging to the console: # here we use stdout instead of stderr by default, so that the output # can be redirected properly. logging.basicConfig(level=LOG_LEVELS[options.loglevel], stream=sys.stdout, format='%(levelname)-8s %(message)s') # enable logging in the modules: log.setLevel(logging.NOTSET) for container, filename, data in xglob.iter_files(args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue process_file(container, filename, data, options.output_dir)
def main(): """ Main function, called when olevba is run from the command line """ global log DEFAULT_LOG_LEVEL = "warning" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option( "-z", "--zip", dest='zip_password', type='str', default=None, help= 'if the file is a zip archive, open all files from it, using the provided password (requires Python 2.6+)' ) parser.add_option( "-f", "--zipfname", dest='zip_fname', type='str', default='*', help= 'if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)' ) parser.add_option( '-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help= "logging level debug/info/warning/error/critical (default=%default)") parser.add_option("-m", '--matches', action="store_true", dest="show_matches", help='Show matched strings.') # TODO: add logfile option (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print('MacroRaptor %s - http://decalage.info/python/oletools' % __version__) print('This is work in progress, please report issues at %s' % URL_ISSUES) print(__doc__) parser.print_help() print('\nAn exit code is returned based on the analysis result:') for result in (Result_NoMacro, Result_NotMSOffice, Result_MacroOK, Result_Error, Result_Suspicious): print(' - %d: %s' % (result.exit_code, result.name)) sys.exit() # print banner with version print('MacroRaptor %s - http://decalage.info/python/oletools' % __version__) print('This is work in progress, please report issues at %s' % URL_ISSUES) logging.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(levelname)-8s %(message)s') # enable logging in the modules: log.setLevel(logging.NOTSET) t = tablestream.TableStream(style=tablestream.TableStyleSlim, header_row=['Result', 'Flags', 'Type', 'File'], column_width=[10, 5, 4, 56]) exitcode = -1 global_result = None # TODO: handle errors in xglob, to continue processing the next files for container, filename, data in xglob.iter_files( args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue full_name = '%s in %s' % (filename, container) if container else filename # try: # # Open the file # if data is None: # data = open(filename, 'rb').read() # except: # log.exception('Error when opening file %r' % full_name) # continue if isinstance(data, Exception): result = Result_Error t.write_row([result.name, '', '', full_name], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(data)], colors=[None, None, None, result.color]) else: filetype = '???' try: vba_parser = olevba.VBA_Parser(filename=filename, data=data, container=container) filetype = TYPE2TAG[vba_parser.type] except Exception as e: # log.error('Error when parsing VBA macros from file %r' % full_name) # TODO: distinguish actual errors from non-MSOffice files result = Result_Error t.write_row([result.name, '', filetype, full_name], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(e)], colors=[None, None, None, result.color]) continue if vba_parser.detect_vba_macros(): vba_code_all_modules = '' try: for (subfilename, stream_path, vba_filename, vba_code) in vba_parser.extract_all_macros(): vba_code_all_modules += vba_code.decode( 'utf-8', 'replace') + '\n' except Exception as e: # log.error('Error when parsing VBA macros from file %r' % full_name) result = Result_Error t.write_row([ result.name, '', TYPE2TAG[vba_parser.type], full_name ], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(e)], colors=[None, None, None, result.color]) continue mraptor = MacroRaptor(vba_code_all_modules) mraptor.scan() if mraptor.suspicious: result = Result_Suspicious else: result = Result_MacroOK t.write_row( [result.name, mraptor.get_flags(), filetype, full_name], colors=[result.color, None, None, None]) if mraptor.matches and options.show_matches: t.write_row(['', '', '', 'Matches: %r' % mraptor.matches]) else: result = Result_NoMacro t.write_row([result.name, '', filetype, full_name], colors=[result.color, None, None, None]) if result.exit_code > exitcode: global_result = result exitcode = result.exit_code print('') print('Flags: A=AutoExec, W=Write, X=Execute') print('Exit code: %d - %s' % (exitcode, global_result.name)) sys.exit(exitcode)
def main(): usage = 'usage: olemap [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option( "-z", "--zip", dest='zip_password', type='str', default=None, help= 'if the file is a zip archive, open all files from it, using the provided password (requires Python 2.6+)' ) parser.add_option( "-f", "--zipfname", dest='zip_fname', type='str', default='*', help= 'if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)' ) # parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, # help="logging level debug/info/warning/error/critical (default=%default)") parser.add_option("--header", action="store_true", dest="header", help='Display the OLE header (default: yes)') parser.add_option("--fat", action="store_true", dest="fat", help='Display the FAT (default: no)') parser.add_option("--minifat", action="store_true", dest="minifat", help='Display the MiniFAT (default: no)') parser.add_option('-x', "--exdata", action="store_true", dest="extra_data", help='Display a hex dump of extra data at end of file') # TODO: add logfile option (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print(BANNER) print(__doc__) parser.print_help() sys.exit() # if no display option is provided, set defaults: default_options = False if not (options.header or options.fat or options.minifat): options.header = True # options.fat = True # options.minifat = True default_options = True # print banner with version print(BANNER) for container, filename, data in xglob.iter_files( args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # TODO: handle xglob errors # ignore directory names stored in zip files: if container and filename.endswith('/'): continue full_name = '%s in %s' % (filename, container) if container else filename print("-" * 79) print('FILE: %s\n' % full_name) if data is not None: # data extracted from zip file ole = olefile.OleFileIO(data) else: # normal filename ole = olefile.OleFileIO(filename) if options.header: show_header(ole, extra_data=options.extra_data) if options.fat: show_fat(ole) if options.minifat: show_minifat(ole) ole.close() # if no display option is provided, print a tip: if default_options: print( 'To display the FAT or MiniFAT structures, use options --fat or --minifat, and -h for help.' )
def main(): # print banner with version python_version = '%d.%d.%d' % sys.version_info[0:3] print('ftguess %s on Python %s - http://decalage.info/python/oletools' % (__version__, python_version)) print('THIS IS WORK IN PROGRESS - Check updates regularly!') print( 'Please report any issue at https://github.com/decalage2/oletools/issues' ) print('') DEFAULT_LOG_LEVEL = "warning" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) # parser.add_option('-c', '--csv', dest='csv', # help='export results to a CSV file') parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option( "-z", "--zip", dest='zip_password', type='str', default=None, help= 'if the file is a zip archive, open first file from it, using the provided password' ) parser.add_option( "-f", "--zipfname", dest='zip_fname', type='str', default='*', help= 'if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)' ) parser.add_option( '-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help= "logging level debug/info/warning/error/critical (default=%default)") (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print(__doc__) parser.print_help() sys.exit() # Setup logging to the console: # here we use stdout instead of stderr by default, so that the output # can be redirected properly. logging.basicConfig(level=LOG_LEVELS[options.loglevel], stream=sys.stdout, format='%(levelname)-8s %(message)s') # enable logging in the modules: enable_logging() for container, filename, data in xglob.iter_files( args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue process_file(container, filename, data)
def main(): # print banner with version print('rtfobj %s - http://decalage.info/python/oletools' % __version__) print('THIS IS WORK IN PROGRESS - Check updates regularly!') print( 'Please report any issue at https://github.com/decalage2/oletools/issues' ) print('') DEFAULT_LOG_LEVEL = "warning" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) # parser.add_option('-o', '--outfile', dest='outfile', # help='output file') # parser.add_option('-c', '--csv', dest='csv', # help='export results to a CSV file') parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option( "-z", "--zip", dest='zip_password', type='str', default=None, help= 'if the file is a zip archive, open first file from it, using the provided password (requires Python 2.6+)' ) parser.add_option( "-f", "--zipfname", dest='zip_fname', type='str', default='*', help= 'if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)' ) parser.add_option( '-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help= "logging level debug/info/warning/error/critical (default=%default)") parser.add_option( "-s", "--save", dest='save_object', type='str', default=None, help= 'Save the object corresponding to the provided number to a file, for example "-s 2". Use "-s all" to save all objects at once.' ) # parser.add_option("-o", "--outfile", dest='outfile', type='str', default=None, # help='Filename to be used when saving an object to a file.') parser.add_option("-d", type="str", dest="output_dir", help='use specified directory to save output files.', default=None) # parser.add_option("--pkg", action="store_true", dest="save_pkg", # help='Save OLE Package binary data of extracted objects (file embedded into an OLE Package).') # parser.add_option("--ole", action="store_true", dest="save_ole", # help='Save OLE binary data of extracted objects (object data without the OLE container).') # parser.add_option("--raw", action="store_true", dest="save_raw", # help='Save raw binary data of extracted objects (decoded from hex, including the OLE container).') # parser.add_option("--hex", action="store_true", dest="save_hex", # help='Save raw hexadecimal data of extracted objects (including the OLE container).') (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print(__doc__) parser.print_help() sys.exit() # Setup logging to the console: # here we use stdout instead of stderr by default, so that the output # can be redirected properly. logging.basicConfig(level=LOG_LEVELS[options.loglevel], stream=sys.stdout, format='%(levelname)-8s %(message)s') # enable logging in the modules: log.setLevel(logging.NOTSET) oleobj.enable_logging() for container, filename, data in xglob.iter_files( args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue process_file(container, filename, data, output_dir=options.output_dir, save_object=options.save_object)
def main(): """Main function, called when vipermonkey is run from the command line. """ # Increase recursion stack depth. sys.setrecursionlimit(13000) # print banner with version # Generated with http://www.patorjk.com/software/taag/#p=display&f=Slant&t=ViperMonkey safe_print(''' _ ___ __ ___ __ | | / (_)___ ___ _____/ |/ /___ ____ / /_____ __ __ | | / / / __ \/ _ \/ ___/ /|_/ / __ \/ __ \/ //_/ _ \/ / / / | |/ / / /_/ / __/ / / / / / /_/ / / / / ,< / __/ /_/ / |___/_/ .___/\___/_/ /_/ /_/\____/_/ /_/_/|_|\___/\__, / /_/ /____/ ''') safe_print('vmonkey %s - https://github.com/decalage2/ViperMonkey' % __version__) safe_print('THIS IS WORK IN PROGRESS - Check updates regularly!') safe_print('Please report any issue at https://github.com/decalage2/ViperMonkey/issues') safe_print('') DEFAULT_LOG_LEVEL = "info" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option("-z", "--zip", dest='zip_password', type='str', default=None, help='if the file is a zip archive, open first file from it, using the ' 'provided password (requires Python 2.6+)') parser.add_option("-f", "--zipfname", dest='zip_fname', type='str', default='*', help='if the file is a zip archive, file(s) to be opened within the zip. ' 'Wildcards * and ? are supported. (default:*)') parser.add_option("-e", action="store_true", dest="scan_expressions", help='Extract and evaluate/deobfuscate constant expressions') parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help="logging level debug/info/warning/error/critical (default=%default)") parser.add_option("-s", '--strip', action="store_true", dest="strip_useless_code", help='Strip useless VB code from macros prior to parsing.') parser.add_option("-j", '--jit', action="store_true", dest="do_jit", help='Speed up emulation by JIT compilation of VB loops to Python.') parser.add_option('-i', '--init', dest="entry_points", action="store", default=None, help="Emulate starting at the given function name(s). Use comma seperated " "list for multiple entries.") parser.add_option('-t', '--time-limit', dest="time_limit", action="store", default=None, type='int', help="Time limit (in minutes) for emulation.") parser.add_option("-c", '--iocs', action="store_true", dest="display_int_iocs", help='Display potential IOCs stored in intermediate VBA variables ' 'assigned during emulation (URLs and base64).') parser.add_option("-v", '--version', action="store_true", dest="print_version", help='Print version information of packages used by ViperMonkey.') parser.add_option("-o", "--out-file", action="store", default=None, type="str", help="JSON output file containing resulting IOCs, builtins, and actions") parser.add_option("-p", "--tee-log", action="store_true", default=False, help="output also to a file in addition to standard out") parser.add_option("-b", "--tee-bytes", action="store", default=0, type="int", help="number of bytes to limit the tee'd log to") (options, args) = parser.parse_args() # Print version information and exit? if (options.print_version): print_version() sys.exit(0) # Print help if no arguments are passed if len(args) == 0: safe_print(__doc__) parser.print_help() sys.exit(0) # setup logging to the console # logging.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(levelname)-8s %(message)s') colorlog.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(log_color)s%(levelname)-8s %(message)s') json_results = [] for container, filename, data in xglob.iter_files(args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue if options.scan_expressions: process_file_scanexpr(container, filename, data) else: entry_points = None if (options.entry_points is not None): entry_points = options.entry_points.split(",") process_file(container, filename, data, strip_useless=options.strip_useless_code, entry_points=entry_points, time_limit=options.time_limit, display_int_iocs=options.display_int_iocs, tee_log=options.tee_log, tee_bytes=options.tee_bytes, out_file_name=options.out_file, do_jit=options.do_jit) # add json results to list if (options.out_file): with open(options.out_file, 'r') as json_file: try: json_results.append(json.loads(json_file.read())) except ValueError: pass if (options.out_file): with open(options.out_file, 'w') as json_file: if (len(json_results) > 1): json_file.write(json.dumps(json_results, indent=2)) else: json_file.write(json.dumps(json_results[0], indent=2)) log.info("Saved results JSON to output file " + options.out_file)
def main(): usage = 'usage: oledir [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option("-z", "--zip", dest='zip_password', type='str', default=None, help='if the file is a zip archive, open all files from it, using the provided password (requires Python 2.6+)') parser.add_option("-f", "--zipfname", dest='zip_fname', type='str', default='*', help='if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)') # parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, # help="logging level debug/info/warning/error/critical (default=%default)") # TODO: add logfile option (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print(BANNER) print(__doc__) parser.print_help() sys.exit() # print banner with version print(BANNER) if os.name == 'nt': colorclass.Windows.enable(auto_colors=True, reset_atexit=True) for container, filename, data in xglob.iter_files(args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue full_name = '%s in %s' % (filename, container) if container else filename print('OLE directory entries in file %s:' % full_name) if data is not None: # data extracted from zip file ole = olefile.OleFileIO(data) else: # normal filename ole = olefile.OleFileIO(filename) # ole.dumpdirectory() # t = prettytable.PrettyTable(('id', 'Status', 'Type', 'Name', 'Left', 'Right', 'Child', '1st Sect', 'Size')) # t.align = 'l' # t.max_width['id'] = 4 # t.max_width['Status'] = 6 # t.max_width['Type'] = 10 # t.max_width['Name'] = 10 # t.max_width['Left'] = 5 # t.max_width['Right'] = 5 # t.max_width['Child'] = 5 # t.max_width['1st Sect'] = 8 # t.max_width['Size'] = 6 table = tablestream.TableStream(column_width=[4, 6, 7, 22, 5, 5, 5, 8, 6], header_row=('id', 'Status', 'Type', 'Name', 'Left', 'Right', 'Child', '1st Sect', 'Size'), style=tablestream.TableStyleSlim) # TODO: read ALL the actual directory entries from the directory stream, because olefile does not! # TODO: OR fix olefile! # TODO: olefile should store or give access to the raw direntry data on demand # TODO: oledir option to hexdump the raw direntries # TODO: olefile should be less picky about incorrect directory structures for id in range(len(ole.direntries)): d = ole.direntries[id] if d is None: # this direntry is not part of the tree: either unused or an orphan d = ole._load_direntry(id) #ole.direntries[id] # print('%03d: %s *** ORPHAN ***' % (id, d.name)) if d.entry_type == olefile.STGTY_EMPTY: status = 'unused' else: status = 'ORPHAN' else: # print('%03d: %s' % (id, d.name)) status = '<Used>' if d.name.startswith('\x00'): # this may happen with unused entries, the name may be filled with zeroes name = '' else: # handle non-printable chars using repr(), remove quotes: name = repr(d.name)[1:-1] left = sid_display(d.sid_left) right = sid_display(d.sid_right) child = sid_display(d.sid_child) entry_type = STORAGE_NAMES.get(d.entry_type, 'Unknown') etype_color = STORAGE_COLORS.get(d.entry_type, 'red') status_color = STATUS_COLORS.get(status, 'red') # print(' type=%7s sid_left=%s sid_right=%s sid_child=%s' # %(entry_type, left, right, child)) # t.add_row((id, status, entry_type, name, left, right, child, hex(d.isectStart), d.size)) table.write_row((id, status, entry_type, name, left, right, child, '%X' % d.isectStart, d.size), colors=(None, status_color, etype_color, None, None, None, None, None, None)) ole.close()
def main(): usage = 'usage: olemap [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option("-z", "--zip", dest='zip_password', type='str', default=None, help='if the file is a zip archive, open all files from it, using the provided password (requires Python 2.6+)') parser.add_option("-f", "--zipfname", dest='zip_fname', type='str', default='*', help='if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)') # parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, # help="logging level debug/info/warning/error/critical (default=%default)") parser.add_option("--header", action="store_true", dest="header", help='Display the OLE header (default: yes)') parser.add_option("--fat", action="store_true", dest="fat", help='Display the FAT (default: no)') parser.add_option("--minifat", action="store_true", dest="minifat", help='Display the MiniFAT (default: no)') parser.add_option('-x', "--exdata", action="store_true", dest="extra_data", help='Display a hex dump of extra data at end of file') # TODO: add logfile option (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print(BANNER) print(__doc__) parser.print_help() sys.exit() # if no display option is provided, set defaults: default_options = False if not (options.header or options.fat or options.minifat): options.header = True # options.fat = True # options.minifat = True default_options = True # print banner with version print(BANNER) for container, filename, data in xglob.iter_files(args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # TODO: handle xglob errors # ignore directory names stored in zip files: if container and filename.endswith('/'): continue full_name = '%s in %s' % (filename, container) if container else filename print("-" * 79) print('FILE: %s\n' % full_name) if data is not None: # data extracted from zip file ole = olefile.OleFileIO(data) else: # normal filename ole = olefile.OleFileIO(filename) if options.header: show_header(ole, extra_data=options.extra_data) if options.fat: show_fat(ole) if options.minifat: show_minifat(ole) ole.close() # if no display option is provided, print a tip: if default_options: print('To display the FAT or MiniFAT structures, use options --fat or --minifat, and -h for help.')
def main(): # print banner with version python_version = '%d.%d.%d' % sys.version_info[0:3] print ('rtfobj %s on Python %s - http://decalage.info/python/oletools' % (__version__, python_version)) print ('THIS IS WORK IN PROGRESS - Check updates regularly!') print ('Please report any issue at https://github.com/decalage2/oletools/issues') print ('') DEFAULT_LOG_LEVEL = "warning" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) # parser.add_option('-o', '--outfile', dest='outfile', # help='output file') # parser.add_option('-c', '--csv', dest='csv', # help='export results to a CSV file') parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option("-z", "--zip", dest='zip_password', type='str', default=None, help='if the file is a zip archive, open first file from it, using the provided password (requires Python 2.6+)') parser.add_option("-f", "--zipfname", dest='zip_fname', type='str', default='*', help='if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)') parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help="logging level debug/info/warning/error/critical (default=%default)") parser.add_option("-s", "--save", dest='save_object', type='str', default=None, help='Save the object corresponding to the provided number to a file, for example "-s 2". Use "-s all" to save all objects at once.') # parser.add_option("-o", "--outfile", dest='outfile', type='str', default=None, # help='Filename to be used when saving an object to a file.') parser.add_option("-d", type="str", dest="output_dir", help='use specified directory to save output files.', default=None) # parser.add_option("--pkg", action="store_true", dest="save_pkg", # help='Save OLE Package binary data of extracted objects (file embedded into an OLE Package).') # parser.add_option("--ole", action="store_true", dest="save_ole", # help='Save OLE binary data of extracted objects (object data without the OLE container).') # parser.add_option("--raw", action="store_true", dest="save_raw", # help='Save raw binary data of extracted objects (decoded from hex, including the OLE container).') # parser.add_option("--hex", action="store_true", dest="save_hex", # help='Save raw hexadecimal data of extracted objects (including the OLE container).') (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print (__doc__) parser.print_help() sys.exit() # Setup logging to the console: # here we use stdout instead of stderr by default, so that the output # can be redirected properly. logging.basicConfig(level=LOG_LEVELS[options.loglevel], stream=sys.stdout, format='%(levelname)-8s %(message)s') # enable logging in the modules: log.setLevel(logging.NOTSET) oleobj.enable_logging() for container, filename, data in xglob.iter_files(args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue process_file(container, filename, data, output_dir=options.output_dir, save_object=options.save_object)
def main(): """ Main function, called when olevba is run from the command line """ global log DEFAULT_LOG_LEVEL = "warning" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option("-z", "--zip", dest='zip_password', type='str', default=None, help='if the file is a zip archive, open all files from it, using the provided password (requires Python 2.6+)') parser.add_option("-f", "--zipfname", dest='zip_fname', type='str', default='*', help='if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)') parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help="logging level debug/info/warning/error/critical (default=%default)") parser.add_option("-m", '--matches', action="store_true", dest="show_matches", help='Show matched strings.') # TODO: add logfile option (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print('MacroRaptor %s - http://decalage.info/python/oletools' % __version__) print('This is work in progress, please report issues at %s' % URL_ISSUES) print(__doc__) parser.print_help() print('\nAn exit code is returned based on the analysis result:') for result in (Result_NoMacro, Result_NotMSOffice, Result_MacroOK, Result_Error, Result_Suspicious): print(' - %d: %s' % (result.exit_code, result.name)) sys.exit() # print banner with version print('MacroRaptor %s - http://decalage.info/python/oletools' % __version__) print('This is work in progress, please report issues at %s' % URL_ISSUES) logging.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(levelname)-8s %(message)s') # enable logging in the modules: log.setLevel(logging.NOTSET) t = tablestream.TableStream(style=tablestream.TableStyleSlim, header_row=['Result', 'Flags', 'Type', 'File'], column_width=[10, 5, 4, 56]) exitcode = -1 global_result = None # TODO: handle errors in xglob, to continue processing the next files for container, filename, data in xglob.iter_files(args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue full_name = '%s in %s' % (filename, container) if container else filename # try: # # Open the file # if data is None: # data = open(filename, 'rb').read() # except: # log.exception('Error when opening file %r' % full_name) # continue if isinstance(data, Exception): result = Result_Error t.write_row([result.name, '', '', full_name], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(data)], colors=[None, None, None, result.color]) else: filetype = '???' try: vba_parser = olevba.VBA_Parser(filename=filename, data=data, container=container) filetype = TYPE2TAG[vba_parser.type] except Exception as e: # log.error('Error when parsing VBA macros from file %r' % full_name) # TODO: distinguish actual errors from non-MSOffice files result = Result_Error t.write_row([result.name, '', filetype, full_name], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(e)], colors=[None, None, None, result.color]) continue if vba_parser.detect_vba_macros(): vba_code_all_modules = '' try: for (subfilename, stream_path, vba_filename, vba_code) in vba_parser.extract_all_macros(): vba_code_all_modules += vba_code.decode('utf-8','replace') + '\n' except Exception as e: # log.error('Error when parsing VBA macros from file %r' % full_name) result = Result_Error t.write_row([result.name, '', TYPE2TAG[vba_parser.type], full_name], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(e)], colors=[None, None, None, result.color]) continue mraptor = MacroRaptor(vba_code_all_modules) mraptor.scan() if mraptor.suspicious: result = Result_Suspicious else: result = Result_MacroOK t.write_row([result.name, mraptor.get_flags(), filetype, full_name], colors=[result.color, None, None, None]) if mraptor.matches and options.show_matches: t.write_row(['', '', '', 'Matches: %r' % mraptor.matches]) else: result = Result_NoMacro t.write_row([result.name, '', filetype, full_name], colors=[result.color, None, None, None]) if result.exit_code > exitcode: global_result = result exitcode = result.exit_code print('') print('Flags: A=AutoExec, W=Write, X=Execute') print('Exit code: %d - %s' % (exitcode, global_result.name)) sys.exit(exitcode)
def main(): """ Main function, called when vipermonkey is run from the command line """ # Increase recursion stack depth. sys.setrecursionlimit(13000) # print banner with version # Generated with http://www.patorjk.com/software/taag/#p=display&f=Slant&t=ViperMonkey print(''' _ ___ __ ___ __ | | / (_)___ ___ _____/ |/ /___ ____ / /_____ __ __ | | / / / __ \/ _ \/ ___/ /|_/ / __ \/ __ \/ //_/ _ \/ / / / | |/ / / /_/ / __/ / / / / / /_/ / / / / ,< / __/ /_/ / |___/_/ .___/\___/_/ /_/ /_/\____/_/ /_/_/|_|\___/\__, / /_/ /____/ ''') print('vmonkey %s - https://github.com/decalage2/ViperMonkey' % __version__) print('THIS IS WORK IN PROGRESS - Check updates regularly!') print( 'Please report any issue at https://github.com/decalage2/ViperMonkey/issues' ) print('') DEFAULT_LOG_LEVEL = "info" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) # parser.add_option('-o', '--outfile', dest='outfile', # help='output file') # parser.add_option('-c', '--csv', dest='csv', # help='export results to a CSV file') parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option( "-z", "--zip", dest='zip_password', type='str', default=None, help= 'if the file is a zip archive, open first file from it, using the provided password (requires Python 2.6+)' ) parser.add_option( "-f", "--zipfname", dest='zip_fname', type='str', default='*', help= 'if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)' ) parser.add_option( "-e", action="store_true", dest="scan_expressions", help='Extract and evaluate/deobfuscate constant expressions') parser.add_option( '-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help= "logging level debug/info/warning/error/critical (default=%default)") parser.add_option("-a", action="store_true", dest="altparser", help='Use the alternate line parser (experimental)') parser.add_option( "-s", '--strip', action="store_true", dest="strip_useless_code", help='Strip useless VB code from macros prior to parsing.') parser.add_option( '-i', '--init', dest="entry_points", action="store", default=None, help= "Emulate starting at the given function name(s). Use comma seperated list for multiple entries." ) parser.add_option('-t', '--time-limit', dest="time_limit", action="store", default=None, type='int', help="Time limit (in minutes) for emulation.") (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print __doc__ parser.print_help() sys.exit() # setup logging to the console # logging.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(levelname)-8s %(message)s') colorlog.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(log_color)s%(levelname)-8s %(message)s') for container, filename, data in xglob.iter_files( args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue if options.scan_expressions: process_file_scanexpr(container, filename, data) else: entry_points = None if (options.entry_points is not None): entry_points = options.entry_points.split(",") process_file(container, filename, data, altparser=options.altparser, strip_useless=options.strip_useless_code, entry_points=entry_points, time_limit=options.time_limit)
self.matches.append(m.group()) if self.autoexec and (self.execute or self.write): self.suspicious = True def get_flags(self): flags = '' flags += 'A' if self.autoexec else '-' flags += 'W' if self.write else '-' flags += 'X' if self.execute else '-' return flags args = ["4.docm"] for container, filename, data in xglob.iter_files(args, recursive=True, zip_password=None, zip_fname=None): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue full_name = '%s in %s' % (filename, container) if container else filename print(full_name) if isinstance(data, Exception): print("Error occured") else: filetype = '???' try: vba_parser = olevba.VBA_Parser(filename=filename, data=data, container=container) filetype = TYPE2TAG[vba_parser.type]