Pesky Old-Style Macro Popups — Advanced Maldoc Techniques

Author: Carrie Roberts (@OrOneEqualsOne)

Remember the old-style Enable Macros dialog? You can bring it back into action to potentially improve click through on a phishing campaign. The old-style dialog is shown below.

This is more “in your face” than the yellow notification we’ve grown accustomed to for enabling macros as shown below.

The old-style dialog box is shown when an Excel Workbook is set to hidden. The following steps will accomplish this for a macro enabled xlsm file.

  1. Rename the .xlsm to .zip and unzip
  2. Add the visibility=”hidden” attribute to the workbookView element in the xl/workbook.xml file.
  3. Zip all the files back up into one xlsm file again

So that’s a cool way to spice up a phishing campaign at least for Excel. Can we do the same with PowerPoint or Word? Unfortunately, these formats do not have the hidden visibility attribute.

However, we came across some pesky old-style macro popups in a Word document while reviewing malware samples from VirusTotal. These popups wouldn’t go away until you enabled macros and they didn’t use the visibility=”hidden” parameter as previously described. As an example, the VirusTotal file with hash of ffaa6e86c13b9bb1952b42d07d9c94882e27bc3b0cfe51e81b310a7fd0a5b29b would popup 5 dialog boxes before giving up. The document itself is a Word document saved in RTF format with an embedded macro-enabled Excel spreadsheet. The animated image below shows the user experience for this piece of malware.

A malware sample like the one shown above can be created with the following steps.

  1. Create a macro enabled Excel document with macros that run as soon as the document is opened. (e.g. using the Workbook_Open function). You can save this file as an xls or xlsm file.
  2. Create a Word document and embed the macro enabled Excel document in it. Use the Insert Menu, Select “Object…” from the dropdown in the Text area of the ribbon, select the “Create from File” tab and Browse to the Excel document. Do not click “Link to File” or “Display as Icon”. Dismiss the dialog box that appears by choosing “Disable Macros”.
  3. Repeat step two any number of times. The number of embedded items controls the number of popups the user will receive.
  4. Optionally hide the embedded objects by selecting them and pressing “Ctrl+Shift+H” or by moving them to later pages in the document.
  5. Save the Word document as an RTF file, then rename the .rtf extension to .doc
  6. Edit the .doc file in a text editor, replacing “\objemb” with “\objupdate\objemb”

This malware inspired us to look at other ways we might be able to accomplish the same thing without using the “objupdate” string in the RTF file. This led to the discovery of the following method. This second method may be less detectable as malware than the first.

  1. Create a macro enabled Excel document with macros that run as soon as the document is opened. (e.g. using the Workbook_Open function). You can save this file as an xls or xlsm file.
  2. Create a Word document and embed the macro enabled Excel document in it. Use the Insert Menu, Select “Object…” from the dropdown in the Text area of the ribbon, select the “Create from File” tab and Browse to the Excel document. Do not click “Link to File” or “Display as Icon”. Dismiss the dialog box that appears by choosing “Disable Macros”.
  3. Repeat step two any number of times. The number of embedded items controls the number of popups the user will receive.
  4. Optionally hide the embedded objects by selecting them and pressing “Ctrl+Shift+H” or by moving them to later pages in the document.
  5. Save the Word document as a .docx file. Close and reopen the .docx.
  6. Now save the .docx file as an RTF file.

Yes, you have to do step five! There is a magic thing that happens in the final RTF file when you do the steps as outlined. To understand the magic, we are going to extract the binary OLE object that represents the embedded Excel document in the RTF file. We will use the rtfobj.py script from oletools for the extraction. Use the version of oletools tagged as v0.53.1 if you run into errors during this step.

Run rtfobj.py on the RTF file:

Identify the stream number of your embedded Excel document. In this case the stream number is zero. Now extract this as an OLE object.

Our OLE file has been output to the same directory as indicated by the last line. Now open this extracted file in a Hex Editor that understands the OLE format, such as FileInsight by McAfee Labs.

The “magic” we are looking for is in the Objinfo stream shown highlighted in the image above. The magic number we need to see for the Objinfo stream is “000003000100”. If you skip step 5 in the document creation process you will end up with a “D” where the “1” should be and you will not get the enable macros popup.

So, what is this magic hex digit anyway? We can read more about the ObjInfo stream here. Specifically, this stream contains 2 bytes for the ODTPersist1 structure, 2 bytes for the cf structure and 2 bytes for the ODPerstist2 structure.

Keep in mind that these bytes are listed from “Least Significant Bit” (LSB) to “Most Significant Bit” (MSB) in the documentation, which is what you might refer to as backwards. Therefore, the cf value is 0x0003, indicating that the format of the embedded file is either “Metafile” or “Enhanced Metafile”. To decide whether it is an “Enhanced Metafile” or not, we need to look at the ODTPersist2 structure, the last two bytes. When ODTPersist2 is 0x000D the left 3 bytes are 1011. The chart below indicates that this means the file is an Enhanced Metafile and that the OLE object supports this format.

In our case, we want to open our RTF document and have it automatically launch Excel and prompt the user to enable macros. This will not happen when the fStoredAsEMF (D) bit is set in the ODTPersist2 structure. Really, we just need a value that sets the fEMF (A) bit and does not set the fStoredAsEMF (D) bit. Or in other words, we specify the OLE object is an Enhanced Metafile that does not support this file format. Therefore, we can set the ODTPersist2 value to 0x0001 to accomplish our designs.

Wow, we just walked you through the painful details of how you can programmatically force the old-style enable macro pop-up to display when opening the document. This will just happen automatically if you do step 5 (save your document as a docx file, close the file, re-open and as save as RTF). Why? I have no idea, but it beats doing all this backwards binary stuff.

Fun fact, you can combine document create methods 1 and 2 from this post and get two enable macro popups from only one embedded OLE object.

A word on detection: Are you interested in detecting RTF files with embedded macro enabled documents? Harold Ogden (@HaroldOgden) provided these two yara rules. The first rule detects RTF files with multiple embedded macro enabled documents, while the second is broad and more prone to false positives but good for hunting.