Commit 6b6210866156712d8f8391e563fa93936359a986
1 parent
66a9fd77
rtfobj: fixed issue #164 to handle linked OLE objects
Showing
2 changed files
with
25 additions
and
5 deletions
oletools/oleobj.py
| @@ -127,6 +127,14 @@ def get_logger(name, level=logging.CRITICAL+1): | @@ -127,6 +127,14 @@ def get_logger(name, level=logging.CRITICAL+1): | ||
| 127 | # a global logger object used for debugging: | 127 | # a global logger object used for debugging: |
| 128 | log = get_logger('oleobj') | 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 | # === CONSTANTS ============================================================== | 139 | # === CONSTANTS ============================================================== |
| 132 | 140 |
oletools/rtfobj.py
| @@ -70,8 +70,9 @@ http://www.decalage.info/python/oletools | @@ -70,8 +70,9 @@ http://www.decalage.info/python/oletools | ||
| 70 | # 2017-03-29 PL: - fixed RtfParser to handle issue #152 (control word with | 70 | # 2017-03-29 PL: - fixed RtfParser to handle issue #152 (control word with |
| 71 | # long parameter) | 71 | # long parameter) |
| 72 | # 2017-04-11 PL: - added detection of the OLE2Link vulnerability CVE-2017-0199 | 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 | # TODO: | 78 | # TODO: |
| @@ -696,9 +697,19 @@ def process_file(container, filename, data, output_dir=None, save_object=False): | @@ -696,9 +697,19 @@ def process_file(container, filename, data, output_dir=None, save_object=False): | ||
| 696 | ole_color = None | 697 | ole_color = None |
| 697 | pkg_color = None | 698 | pkg_color = None |
| 698 | if rtfobj.is_ole: | 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 | ole_column += 'class name: %r\n' % rtfobj.class_name | 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 | if rtfobj.is_package: | 713 | if rtfobj.is_package: |
| 703 | pkg_column = 'Filename: %r\n' % rtfobj.filename | 714 | pkg_column = 'Filename: %r\n' % rtfobj.filename |
| 704 | pkg_column += 'Source path: %r\n' % rtfobj.src_path | 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,7 +764,8 @@ def process_file(container, filename, data, output_dir=None, save_object=False): | ||
| 753 | fname = '%s_object_%08X.noname' % (fname_prefix, rtfobj.start) | 764 | fname = '%s_object_%08X.noname' % (fname_prefix, rtfobj.start) |
| 754 | print(' saving to file %s' % fname) | 765 | print(' saving to file %s' % fname) |
| 755 | open(fname, 'wb').write(rtfobj.olepkgdata) | 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 | print('Saving file embedded in OLE object #%d:' % i) | 769 | print('Saving file embedded in OLE object #%d:' % i) |
| 758 | print(' format_id = %d' % rtfobj.format_id) | 770 | print(' format_id = %d' % rtfobj.format_id) |
| 759 | print(' class name = %r' % rtfobj.class_name) | 771 | print(' class name = %r' % rtfobj.class_name) |
| @@ -839,7 +851,7 @@ def main(): | @@ -839,7 +851,7 @@ def main(): | ||
| 839 | format='%(levelname)-8s %(message)s') | 851 | format='%(levelname)-8s %(message)s') |
| 840 | # enable logging in the modules: | 852 | # enable logging in the modules: |
| 841 | log.setLevel(logging.NOTSET) | 853 | log.setLevel(logging.NOTSET) |
| 842 | - oleobj.log.setLevel(logging.NOTSET) | 854 | + oleobj.enable_logging() |
| 843 | 855 | ||
| 844 | for container, filename, data in xglob.iter_files(args, recursive=options.recursive, | 856 | for container, filename, data in xglob.iter_files(args, recursive=options.recursive, |
| 845 | zip_password=options.zip_password, zip_fname=options.zip_fname): | 857 | zip_password=options.zip_password, zip_fname=options.zip_fname): |