Commit 6b6210866156712d8f8391e563fa93936359a986

Authored by decalage2
1 parent 66a9fd77

rtfobj: fixed issue #164 to handle linked OLE objects

oletools/oleobj.py
... ... @@ -127,6 +127,14 @@ def get_logger(name, level=logging.CRITICAL+1):
127 127 # a global logger object used for debugging:
128 128 log = get_logger('oleobj')
129 129  
  130 +def enable_logging():
  131 + """
  132 + Enable logging for this module (disabled by default).
  133 + This will set the module-specific logger level to NOTSET, which
  134 + means the main application controls the actual logging level.
  135 + """
  136 + log.setLevel(logging.NOTSET)
  137 +
130 138  
131 139 # === CONSTANTS ==============================================================
132 140  
... ...
oletools/rtfobj.py
... ... @@ -70,8 +70,9 @@ http://www.decalage.info/python/oletools
70 70 # 2017-03-29 PL: - fixed RtfParser to handle issue #152 (control word with
71 71 # long parameter)
72 72 # 2017-04-11 PL: - added detection of the OLE2Link vulnerability CVE-2017-0199
  73 +# 2017-05-04 PL: - fixed issue #164 to handle linked OLE objects
73 74  
74   -__version__ = '0.51dev5'
  75 +__version__ = '0.51dev7'
75 76  
76 77 # ------------------------------------------------------------------------------
77 78 # TODO:
... ... @@ -696,9 +697,19 @@ def process_file(container, filename, data, output_dir=None, save_object=False):
696 697 ole_color = None
697 698 pkg_color = None
698 699 if rtfobj.is_ole:
699   - ole_column = 'format_id: %d\n' % rtfobj.format_id
  700 + ole_column = 'format_id: %d ' % rtfobj.format_id
  701 + if rtfobj.format_id == oleobj.OleObject.TYPE_EMBEDDED:
  702 + ole_column += '(Embedded)\n'
  703 + elif rtfobj.format_id == oleobj.OleObject.TYPE_LINKED:
  704 + ole_column += '(Linked)\n'
  705 + else:
  706 + ole_column += '(Unknown)\n'
700 707 ole_column += 'class name: %r\n' % rtfobj.class_name
701   - ole_column += 'data size: %d' % rtfobj.oledata_size
  708 + # if the object is linked and not embedded, data_size=None:
  709 + if rtfobj.oledata_size is None:
  710 + ole_column += 'data size: N/A'
  711 + else:
  712 + ole_column += 'data size: %d' % rtfobj.oledata_size
702 713 if rtfobj.is_package:
703 714 pkg_column = 'Filename: %r\n' % rtfobj.filename
704 715 pkg_column += 'Source path: %r\n' % rtfobj.src_path
... ... @@ -753,7 +764,8 @@ def process_file(container, filename, data, output_dir=None, save_object=False):
753 764 fname = '%s_object_%08X.noname' % (fname_prefix, rtfobj.start)
754 765 print(' saving to file %s' % fname)
755 766 open(fname, 'wb').write(rtfobj.olepkgdata)
756   - elif rtfobj.is_ole:
  767 + # When format_id=TYPE_LINKED, oledata_size=None
  768 + elif rtfobj.is_ole and rtfobj.oledata_size is not None:
757 769 print('Saving file embedded in OLE object #%d:' % i)
758 770 print(' format_id = %d' % rtfobj.format_id)
759 771 print(' class name = %r' % rtfobj.class_name)
... ... @@ -839,7 +851,7 @@ def main():
839 851 format='%(levelname)-8s %(message)s')
840 852 # enable logging in the modules:
841 853 log.setLevel(logging.NOTSET)
842   - oleobj.log.setLevel(logging.NOTSET)
  854 + oleobj.enable_logging()
843 855  
844 856 for container, filename, data in xglob.iter_files(args, recursive=options.recursive,
845 857 zip_password=options.zip_password, zip_fname=options.zip_fname):
... ...