Commit f6155b35979027316095b617122e945b50e4318b
1 parent
3f0e4f5e
added detection of template injection on OpenXML files
Showing
1 changed file
with
23 additions
and
5 deletions
oletools/olevba.py
| @@ -2693,7 +2693,8 @@ class VBA_Parser(object): | @@ -2693,7 +2693,8 @@ class VBA_Parser(object): | ||
| 2693 | self.pcodedmp_output = None | 2693 | self.pcodedmp_output = None |
| 2694 | #: Flag set to True/False if VBA stomping detected | 2694 | #: Flag set to True/False if VBA stomping detected |
| 2695 | self.vba_stomping_detected = None | 2695 | self.vba_stomping_detected = None |
| 2696 | - self.is_encrypted = None # will be set to True or False by detect_is_encrypted | 2696 | + # will be set to True or False by detect_is_encrypted method |
| 2697 | + self.is_encrypted = None | ||
| 2697 | 2698 | ||
| 2698 | # if filename is None: | 2699 | # if filename is None: |
| 2699 | # if isinstance(_file, basestring): | 2700 | # if isinstance(_file, basestring): |
| @@ -2798,20 +2799,37 @@ class VBA_Parser(object): | @@ -2798,20 +2799,37 @@ class VBA_Parser(object): | ||
| 2798 | log.debug("subfile {}".format(subfile)) | 2799 | log.debug("subfile {}".format(subfile)) |
| 2799 | with z.open(subfile) as file_handle: | 2800 | with z.open(subfile) as file_handle: |
| 2800 | found_ole = False | 2801 | found_ole = False |
| 2802 | + template_injection_detected = False | ||
| 2801 | xml_macrosheet_found = False | 2803 | xml_macrosheet_found = False |
| 2802 | magic = file_handle.read(len(olefile.MAGIC)) | 2804 | magic = file_handle.read(len(olefile.MAGIC)) |
| 2803 | if magic == olefile.MAGIC: | 2805 | if magic == olefile.MAGIC: |
| 2804 | found_ole = True | 2806 | found_ole = True |
| 2805 | - # in case we did not find an OLE file, there could be a XLM macrosheet | 2807 | + # in case we did not find an OLE file, |
| 2808 | + # there could be a XLM macrosheet or a template injection attempt | ||
| 2806 | if not found_ole: | 2809 | if not found_ole: |
| 2810 | + read_all_file = file_handle.read() | ||
| 2811 | + # try to detect template injection attempt | ||
| 2812 | + # https://ired.team/offensive-security/initial-access/phishing-with-ms-office/inject-macros-from-a-remote-dotm-template-docx-with-macros | ||
| 2813 | + subfile_that_can_contain_templates = "word/_rels/settings.xml.rels" | ||
| 2814 | + if subfile == subfile_that_can_contain_templates: | ||
| 2815 | + regex_template = b"Type=\"http://schemas\.openxmlformats\.org/officeDocument/\d{4}/relationships/attachedTemplate\"\s+Target=\"(.+?)\"" | ||
| 2816 | + template_injection_found = re.search(regex_template, read_all_file) | ||
| 2817 | + if template_injection_found: | ||
| 2818 | + injected_template_url = template_injection_found.group(1).decode() | ||
| 2819 | + message = "Found injected template in subfile {}. Template URL: {}"\ | ||
| 2820 | + "".format(subfile_that_can_contain_templates, injected_template_url) | ||
| 2821 | + log.info(message) | ||
| 2822 | + template_injection_detected = True | ||
| 2823 | + # try to find a XML macrosheet | ||
| 2807 | macro_sheet_footer = b"</xm:macrosheet>" | 2824 | macro_sheet_footer = b"</xm:macrosheet>" |
| 2808 | len_macro_sheet_footer = len(macro_sheet_footer) | 2825 | len_macro_sheet_footer = len(macro_sheet_footer) |
| 2809 | - read_all_file = file_handle.read() | ||
| 2810 | last_bytes_to_check = read_all_file[-len_macro_sheet_footer:] | 2826 | last_bytes_to_check = read_all_file[-len_macro_sheet_footer:] |
| 2811 | if last_bytes_to_check == macro_sheet_footer: | 2827 | if last_bytes_to_check == macro_sheet_footer: |
| 2812 | - log.info("Found XLM Macro in subfile: {}".format(subfile)) | 2828 | + message = "Found XLM Macro in subfile: {}".format(subfile) |
| 2829 | + log.info(message) | ||
| 2813 | xml_macrosheet_found = True | 2830 | xml_macrosheet_found = True |
| 2814 | - if found_ole or xml_macrosheet_found: | 2831 | + |
| 2832 | + if found_ole or xml_macrosheet_found or template_injection_detected: | ||
| 2815 | log.debug('Opening OLE file %s within zip' % subfile) | 2833 | log.debug('Opening OLE file %s within zip' % subfile) |
| 2816 | with z.open(subfile) as file_handle: | 2834 | with z.open(subfile) as file_handle: |
| 2817 | ole_data = file_handle.read() | 2835 | ole_data = file_handle.read() |