Commit 412ee36ae45e70f42123e835871bac956d958461

Authored by decalage2
1 parent d5b971e4

oleobj: added customUI.onLoad detection (issue #730)

Showing 2 changed files with 23 additions and 3 deletions
oletools/oleobj.py
@@ -14,7 +14,7 @@ http://www.decalage.info/python/oletools @@ -14,7 +14,7 @@ http://www.decalage.info/python/oletools
14 14
15 # === LICENSE ================================================================= 15 # === LICENSE =================================================================
16 16
17 -# oleobj is copyright (c) 2015-2021 Philippe Lagadec (http://www.decalage.info) 17 +# oleobj is copyright (c) 2015-2022 Philippe Lagadec (http://www.decalage.info)
18 # All rights reserved. 18 # All rights reserved.
19 # 19 #
20 # Redistribution and use in source and binary forms, with or without 20 # Redistribution and use in source and binary forms, with or without
@@ -87,8 +87,9 @@ from oletools.common.io_encoding import ensure_stdout_handles_unicode @@ -87,8 +87,9 @@ from oletools.common.io_encoding import ensure_stdout_handles_unicode
87 # 2018-09-11 v0.54 PL: - olefile is now a dependency 87 # 2018-09-11 v0.54 PL: - olefile is now a dependency
88 # 2018-10-30 SA: - added detection of external links (PR #317) 88 # 2018-10-30 SA: - added detection of external links (PR #317)
89 # 2020-03-03 v0.56 PL: - fixed bug #541, "Ole10Native" is case-insensitive 89 # 2020-03-03 v0.56 PL: - fixed bug #541, "Ole10Native" is case-insensitive
  90 +# 2022-01-28 v0.60 PL: - added detection of customUI tags
90 91
91 -__version__ = '0.56.1' 92 +__version__ = '0.60.1.dev5'
92 93
93 # ----------------------------------------------------------------------------- 94 # -----------------------------------------------------------------------------
94 # TODO: 95 # TODO:
@@ -182,6 +183,9 @@ else: @@ -182,6 +183,9 @@ else:
182 xrange = range # pylint: disable=redefined-builtin, invalid-name 183 xrange = range # pylint: disable=redefined-builtin, invalid-name
183 184
184 OOXML_RELATIONSHIP_TAG = '{http://schemas.openxmlformats.org/package/2006/relationships}Relationship' 185 OOXML_RELATIONSHIP_TAG = '{http://schemas.openxmlformats.org/package/2006/relationships}Relationship'
  186 +# There are several customUI tags for different versions of Office:
  187 +TAG_CUSTOMUI_2007 = "{http://schemas.microsoft.com/office/2006/01/customui}customUI"
  188 +TAG_CUSTOMUI_2010 = "{http://schemas.microsoft.com/office/2009/07/customui}customUI"
185 189
186 # === GLOBAL VARIABLES ======================================================== 190 # === GLOBAL VARIABLES ========================================================
187 191
@@ -721,6 +725,19 @@ def find_external_relationships(xml_parser): @@ -721,6 +725,19 @@ def find_external_relationships(xml_parser):
721 pass 725 pass
722 726
723 727
  728 +def find_customUI(xml_parser):
  729 + """
  730 + iterate XML files looking for customUI to external objects or VBA macros
  731 + Examples of malicious usage, to load an external document or trigger a VBA macro:
  732 + https://www.trellix.com/en-us/about/newsroom/stories/threat-labs/prime-ministers-office-compromised.html
  733 + https://www.netero1010-securitylab.com/evasion/execution-of-remote-vba-script-in-excel
  734 + """
  735 + for _, elem, _ in xml_parser.iter_xml(None, False, (TAG_CUSTOMUI_2007, TAG_CUSTOMUI_2010)):
  736 + customui_onload = elem.get('onLoad')
  737 + if customui_onload is not None:
  738 + yield customui_onload
  739 +
  740 +
724 def process_file(filename, data, output_dir=None): 741 def process_file(filename, data, output_dir=None):
725 """ find embedded objects in given file 742 """ find embedded objects in given file
726 743
@@ -763,6 +780,9 @@ def process_file(filename, data, output_dir=None): @@ -763,6 +780,9 @@ def process_file(filename, data, output_dir=None):
763 print("Found relationship '%s' with external link %s" % (relationship, target)) 780 print("Found relationship '%s' with external link %s" % (relationship, target))
764 if target.startswith('mhtml:'): 781 if target.startswith('mhtml:'):
765 print("Potential exploit for CVE-2021-40444") 782 print("Potential exploit for CVE-2021-40444")
  783 + for target in find_customUI(xml_parser):
  784 + did_dump = True
  785 + print("Found customUI tag with external link or VBA macro %s (possibly exploiting CVE-2021-42292)" % target)
766 786
767 # look for ole files inside file (e.g. unzip docx) 787 # look for ole files inside file (e.g. unzip docx)
768 # have to finish work on every ole stream inside iteration, since handles 788 # have to finish work on every ole stream inside iteration, since handles
setup.py
@@ -55,7 +55,7 @@ import os, fnmatch @@ -55,7 +55,7 @@ import os, fnmatch
55 #--- METADATA ----------------------------------------------------------------- 55 #--- METADATA -----------------------------------------------------------------
56 56
57 name = "oletools" 57 name = "oletools"
58 -version = '0.60.1.dev4' 58 +version = '0.60.1.dev5'
59 desc = "Python tools to analyze security characteristics of MS Office and OLE files (also called Structured Storage, Compound File Binary Format or Compound Document File Format), for Malware Analysis and Incident Response #DFIR" 59 desc = "Python tools to analyze security characteristics of MS Office and OLE files (also called Structured Storage, Compound File Binary Format or Compound Document File Format), for Malware Analysis and Incident Response #DFIR"
60 long_desc = open('oletools/README.rst').read() 60 long_desc = open('oletools/README.rst').read()
61 author = "Philippe Lagadec" 61 author = "Philippe Lagadec"