On Advanced Practices, we are always looking for new ways to find
malicious activity and track adversaries over time. Today we’re
sharing a technique we use to detect and cluster Microsoft Office
documents—specifically those in the href="https://www.ecma-international.org/publications-and-standards/standards/ecma-376/">Office
Open XML (OOXML) file format. Additionally, we’re releasing a
tool so analysts and defenders can automatically generate YARA rules
using this technique.
Beginning with Microsoft Office 2007, the default file format for
Excel, PowerPoint, and Word documents switched from an Object Linking
and Embedding (OLE) based format to OOXML. For now, the only part of
this that’s important to understand is OOXML documents are just a
bunch of folders and files packaged into a ZIP archive. Let’s look at
the Word document this blog post is being written in (Figure 1), for example:
➜ file example.docx
example.docx: Microsoft Word 2007+
➜ unzip -v example.docx
Archive: example.docx
Length Method Size Cmpr Date Time
CRC-32 Name
-------- ------ ------- ---- ---------- -----
-------- ----
1445 Defl:S 358 75% 01-01-1980 00:00
576f9132 [Content_Types].xml
590 Defl:S 239 60% 01-01-1980 00:00
b71a911e _rels/.rels
1559 Defl:S 407 74% 01-01-1980 00:00
33ce17ac word/_rels/document.xml.rels
10861 Defl:S 2480 77% 01-01-1980 00:00
f0af2147 word/document.xml
8393 Defl:S 1746 79% 01-01-1980 00:00
9867f4b6 word/theme/theme1.xml
4725 Defl:S 1416 70% 01-01-1980 00:00
718205c5 word/settings.xml
655 Defl:S 295 55% 01-01-1980 00:00
bf8dd4bd word/webSettings.xml
755 Defl:S 367 51% 01-01-1980 00:00
5bf1cf49 docProps/core.xml
991 Defl:S 476 52% 01-01-1980 00:00
bad67489 docProps/app.xml
30308 Defl:S 3104 90% 01-01-1980 00:00
ce0f21cd word/styles.xml
7781 Defl:S 952 88% 01-01-1980 00:00
9f45bf02 word/numbering.xml
2230 Defl:S 559 75% 01-01-1980 00:00
63baaf8c word/fontTable.xml
-------- -------
--- -------
70293 12399 82%
12 files
Figure 1: unzip -v output for example.docx
Now, even though we used the unzip
command, we didn’t actually unzip the archive. The output provided by
the -v option is derived from the ZIP
local file headers, which contain a wealth of information on the
compressed files. Of particular interest is the CRC-32 value.
A href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">cyclic
redundancy check (CRC) is an algorithm designed to detect errors
or unintended changes to data. The idea is a system can calculate a
CRC value before and after a transfer or transformation of data as a
simple way to ensure its integrity. For ZIP archives, the CRC-32
values confirm the decompressed files are the same as they were prior
to compression. Which is great and all, but they can serve other use
cases too.
Forget about error-detection. A ZIP CRC-32 value is essentially a
small hash of the uncompressed file, and what better way to identify a
file than by its hash? While the chance of a collision for CRC-32 is
significantly higher than other algorithms such as SHA-256 or even
MD5, it can be paired with additional metadata like the file name (or
extension) and size to reduce false positives.
Here’s a hex dump of the first local file header from the previous
example (Figure 2):
src="https://www.fireeye.com/content/dam/fireeye-www/blog/images/detecting-embedded/figure2.png" alt="" />
Figure 2: Hex dump of the first local
file header for example.docx
Using the
CRC-32,
uncompressed file size, and
file name fields, a YARA rule for this entry can be
written as follows:
|
NOTE: The numeric fields are stored in little-endian.
Advanced Practices uses this technique to find similar documents
that contain the same embedded file over time. Here are a couple
real-world examples:
Document: class="code">397ba1d0601558dfe34cd5aafaedd18e
File: class="code">0dc39af4899f6aa0a8d29426aba59314
(word\media\image1.png)
Groups: href="https://advantage.mandiant.com/actors/threat-actor--18909bad-5471-54df-a003-72e2cc234592">UNC1130,
UNC1837, UNC1965
|
This rule detects OOXML documents, which contain a specific PNG
image seen in Figure 3.
src="https://www.fireeye.com/content/dam/fireeye-www/blog/images/detecting-embedded/figure3.png" alt="" />
Figure 3: PNG embedded in phishing documents
Figure 3 is found in several documents dropping LATEOP, and has been
attributed to groups such as href="https://advantage.mandiant.com/actors/threat-actor--18909bad-5471-54df-a003-72e2cc234592">UNC1130,
a North Korean state-sponsored threat actor.
Document:
252227b8701d45deb0cc6b0edad98836
File:
3bdfaf98d820a1d8536625b9efd3bb14 ([Content_Types].xml)
Groups: FIN7
|
This rule detects a specific class="code">[Content_Types].xml file, which is shown
(formatted) in Figure 4.
src="https://www.fireeye.com/content/dam/fireeye-www/blog/images/detecting-embedded/figure4.png" alt="" />
Figure 4: Formatted [Content_Types].xml file
This file maps different parts of the OOXML package to their content
type. Given a unique enough combination of parts and types, the class="code">[Content_Types].xml file can be a great way to
find similar OOXML documents. This particular example is found in
multiple FIN7 GRIFFON samples.
Last but not least, it’s time to introduce href="https://github.com/mandiant/apooxml"> class="code">apooxml, a Python tool that can be used to
quickly and easily generate YARA rules just like these. Here’s how it works:
|
For more details, check out the href="https://github.com/mandiant/apooxml">repository on GitHub.