Auteur Sujet: [FireEye]Detecting Embedded Content in OOXML Documents  (Lu 3566 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne igor51

  • Admin
  • Mega Power Members
  • *****
  • Messages: 10419
[FireEye]Detecting Embedded Content in OOXML Documents
« le: août 19, 2021, 00:00:34 »
Detecting Embedded Content in OOXML Documents

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.


 

OOXML File Format


 

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.


 

Detection


 

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:


 
   
     


          rule content_types {
      meta:

                    author = "Aaron Stephens
            <aaron.stephens@mandiant.com>"
         
            description = "Example OOXML rule."


              strings:
          $crc = { 32 91
            6f 57 }
          $name =
            "[Content_Types].xml"
          $size = { a5
            05 00 00 }


              condition:
          $size at
            @crc[1] + 8 and $name at @crc[1] + 16
  }


     

 


  NOTE: The numeric fields are stored in little-endian.


 

Examples


 

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


 
   
     


          rule png_397ba1d0601558dfe34cd5aafaedd18e
            {
      meta:
          author = "Aaron
            Stephens <aaron.stephens@mandiant.com>"
   
                  description = "PNG in OOXML
        document."


              strings:
          $crc =
            {f8158b40}
          $ext = ".png"
     
                $ufs = {b42c0000}


              condition:
          $ufs at
            @crc[1] + 8 and $ext at @crc[1] + uint16(@crc[1] + 12) + 16
            - 4
  }


 

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


 
   
     


          rule xml_252227b8701d45deb0cc6b0edad98836
            {
      meta:
          author = "Aaron
            Stephens <aaron.stephens@mandiant.com>"
   
                  description = "[Content_Types].xml in OOXML
        document."


              strings:
          $crc =
            {8cf0d220}
          $name =
            "[Content_Types].xml"
          $ufs =
        {9b060000}


              condition:
          $ufs at
            @crc[1] + 8 and $name at @crc[1] + 16
  }


     

 

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.


 

Tooling


 

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:


 
   
     


          ➜ python3 apooxml.py -h

           
usage: apooxml.py [-h] [-a AUTHOR] [-n NAME] [-o OUT]
        sample


          Generate YARA rules for OOXML
        documents.


          positional arguments:
   
            sample                OOXML document to generate YARA rule
        from.


          optional arguments:
    -h,
            --help            show this help message and exit
   
            -a AUTHOR, --author AUTHOR
                         
            YARA rule author.
    -n NAME, --name NAME  YARA rule
            name.
    -o OUT, --out OUT     YARA rule file
        name.


         
            ➜ python3 apooxml.py -o 'example.yara'
              397ba1d0601558dfe34cd5aafaedd18e
 
 1.
            [Content_Types].xml             1980-01-01 00:00:00 
            14506c9d  1613
   2. _rels/.rels                    
            1980-01-01 00:00:00  b71a911e  590
   3.
            word/_rels/document.xml.rels    1980-01-01 00:00:00 
            ab5e83b7  1207
   4. word/document.xml              
            1980-01-01 00:00:00  44c9bf93  2692
   5.
            word/_rels/vbaProject.bin.rels  1980-01-01 00:00:00 
            ef601408  277
   6. word/vbaProject.bin            
            1980-01-01 00:00:00  ab54dacf  10752
   7.
            word/media/image1.png           1980-01-01 00:00:00 
            408b15f8  11444
   8. word/theme/theme1.xml          
            1980-01-01 00:00:00  4276c88b  7088
   9.
            word/settings.xml               1980-01-01 00:00:00 
            17044d98  2750
  10. word/vbaData.xml               
            1980-01-01 00:00:00  9209afe1  1292
  11.
            word/fontTable.xml              1980-01-01 00:00:00 
            37e3715b  960
  12. word/stylesWithEffects.xml     
            1980-01-01 00:00:00  c883d0b1  16755
  13.
            docProps/app.xml                1980-01-01 00:00:00 
            3cc6382c  982
  14. word/webSettings.xml           
            1980-01-01 00:00:00  4e16a017  428
  15.
            docProps/core.xml               1980-01-01 00:00:00 
            8cef183c  643
  16. word/styles.xml                
            1980-01-01 00:00:00  1f9b9145  16002


          Enter a number corresponding to the desired
        entry: 7


          Wrote YARA rule to example.yara.


          ➜ cat example.yara
 
rule
            ooxml_png_crc_397ba1d0601558dfe34cd5aafaedd18e {
     
            meta:
          author = "apooxml"
     
                description = "Generated by apooxml."
   
                  reference_md5 =
        "397ba1d0601558dfe34cd5aafaedd18e"


              strings:
          $crc =
            {f8158b40}
          $ext = ".png"
     
                $ufs = {b42c0000}


              condition:
          $ufs at
            @crc[1] + 8 and $ext at @crc[1] + uint16(@crc[1] + 12) + 16
            - 4
  }


 

For more details, check out the     href="https://github.com/mandiant/apooxml">repository on GitHub.


 

 


Source: Detecting Embedded Content in OOXML Documents

Tags: