Thoughts on cyber threat intelligence, malware analysis, and other things

Tricky CVE-2017-11882 Trick Used to Deliver Trickbot

TL;DR: CVE-2017-11882 exploits work with either 0x00430C12 or 0x00630C12 as the target memory address because the input is converted to uppercase by the vulnerable Equation Editor binary before the exploit is triggered. 63=c, 43=C

I was recently doing some analysis of malicious documents and came across an example of a CVE-2017-11882 exploit that I thought was pretty interesting. At first glance, the exploit seemed pretty routine; an RTF file saved as a .doc exploiting CVE-2017-11882 to launch PowerShell commands that would download and run Trickbot. I had read about the vulnerability before, but I really wanted to understand how it worked, so I took the opportunity to dig a little deeper and found what I think is a pretty nifty little trick used to evade the common signatures and Yara rules I've seen for this exploit.

Sample: 06655c7225279845d2886758c18d7813

Embedded Objects

This document used a couple of different tricks to get to the final goal of downloading and launching Trickbot. First, it included several objects embedded in the OLE Packager format. Microsoft handles these objects by saving them to %TEMP% at run-time. You can read more about the Packager format and the associated behavior here and here.

This particular document actually included two .bat files and several malformed embedded objects. The first .bat file simply calls the second, which includes the necessary PowerShell to download the second stage malware. The malformed objects were most likely included to make analysis more difficult - Word and Wordpad are pretty forgiving of poorly formatted RTF content, lots of tools built to analyze malicious RTFs, however, adhere closely to the standard and don't fail gracefully.


Now that Microsoft's handling of packager content has saved some malicious content to disk, the exploit will be triggered to actually execute that content. The vulnerability we're dealing with in this case is a buffer overflow that exists in an old binary used to implement Equation Editor functionality in Office products - EQNEDT32.exe. Specifically, the vulnerability exists in the font name field of equation objects embedded in RTF documents. Equation objects are stored in the MTEF format which is documented here. Basically, the font record will include 08 followed by 2 bytes for typeface and style codes, and finally a null terminated font name string. There's a good general write-up of the vulnerability here, but essentially the font name buffer is 40 bytes long, however no checks are done to ensure the input adheres to that length. If a longer string is supplied, the return address of the executing function will be overwritten and execution can be redirected to an attacker defined location.

The binary, EQNEDT32.exe, includes a call to the deprecated Windows API function WinExec, which does exactly what it sounds like - executes a Windows command. Prior to Microsoft's patch, this binary did not include protections against buffer overflow exploits and the location of WinExec in memory would consistently be at 0x00430C12. The exploit, then, can supply any valid Windows command (padded to 44 bytes total), followed by that memory address, and WinExec will be called with the supplied command as a parameter.

Hang on a minute though Exploit Example Looking at the content in this document, we can see that the exploit string is 080000436D44202F432025746D70255C7461736B2E6261742020202020202020202020202026205555555555555555120C6300

It ends in 120C6300 or the memory address 0x00630C12. However, the exploit still executes the hex encoded command despite the correct memory address of WinExec being 0x00430C12.

After spending some time banging my head against a wall trying to figure out why the exploit still works, someone smarter than me pointed out that, in ASCII, 63 is a lowercase 'c', while 43 is an uppercase 'C'. And, after doing a little debugging of the equation editor binary, we found a routine that converts the entire supplied font name (regardless of length) to uppercase. Any valid ASCII characters from a-z are converted to uppercase A-Z. This all occurs prior to the triggering of the buffer overflow exploit.

Convert to Uppercase

Before Conversion

Before Conversion

So, by the time the exploit is triggered, the return address will have been converted to the correct memory location of 0x00430C12. I've included an updated Yara rule here that will target these exploits based on the inclusion of an equation object, the total length of the exploit string, and either of the two working addresses.

rule likely_cve_2017_11882
  author = "@malwaresoup"
  date = "20180515"
  reference = "bc9d434dee734f310de97c68312bd650b14d90105aad53e3e10b39659ccfe4fa"
  //Hex encoded Equation.3
  $equation = "4571756174696F6E2E33" nocase

  // MTEF Font header = 30 38 ?? ?? ?? ?? (080000)
  // Font buffer overflow = 44 ASCII characters - command to be executed
  // Overflowed return address for WinExec - 30 43 (36 | 34) 33 30 30 (120C6300 OR 120C4300)
  $font_exploit = { 30 38 [92] 31 32 30 43 (36 | 34) 33 30 30 }

  $equation and $font_exploit