Part 3 of 3

As we mentioned in our previous overview of Geodo, the documents used to deliver Geodo are all quite similar. Each document comes weaponised with a hostile macro. The macros are always heavily obfuscated, with junk functions and string substitutions prevalent throughout the code. The obfuscation uses three languages or dialects as part of the obfuscation process: Visual Basic, PowerShell, and Batch.

Figures 1 and 2: A side-by-side comparison of two randomly chosen macros. Clear similarities can be seen across the obfuscated code.

Figures 1 and 2: A side-by-side comparison of two randomly chosen macros. Clear similarities can be seen across the obfuscated code.

Even before de-obfuscation occurs, we can identify a few key features of these macros:

  • They run as soon as the document is opened, by hooking AutoOpen
  • Both use the TypeName method as junk code obfuscation
  • Some plaintext strings are evident, amongst the obfuscation
    • CStr(“c”) + CStr(“m”)
    • “d” + ” /V:/C”
    • “md ” + ” /V” + “:O ” + ” ” + “/”

Figure 3 shows the code after stripping away the first layer of obfuscation. Removing the junk code drops the macro to a very reasonable 46 lines, including whitespace.

Figure 3: First layer de-obfuscation of a Geodo-serving macro.

By allowing a Visual Basic interpreter to do the heavy lifting for us, we are able to quickly strip away this layer of obfuscation, revealing a batch script, as seen in Figure 4.

Figure 4: An obfuscated batch script revealed after deobfuscating layer one.

Despite looking trivial, the batch script is actually quite brilliant, and the obscure dialect that is Batch makes interpreting the script initially cumbersome.

The goal of this script is to decode and execute the PowerShell script seen in Figure 6. The initial impulse is that the code is simply building an array of decimal characters that simply need to be converted to their ASCII equivalent. However, this quickly fails scrutiny when we observe characters below 32. Clearly the obfuscation requires more careful attention to detail.

Ordering the code, a bit more elegantly, as seen in Figure 5, we get a better idea of what is going on.

Figure 5: The formatted batch script.

The second line sets a variable called ‘vNdr’ to a long and nonsensical string. Line 4-7 then loops through a long array of integers and updates the variable nXt with…something? The syntax looks a little confusing, but with a little explanation it becomes clear:

  • !nXt! – modifies the existing variable, including a copy of itself
  • vNdr – is the long variable set on line two
  • :~ – means slice the string at a given index (0 indexed)
  • %t – this is the current variable from the for loop
  • ,1 – defines how many characters to extract from the offset specified by %t, in this case: 1

Putting it all together: Loop through the array of numbers; during each loop, assign the current number to the variable t; get the character at index t+1 from the string assigned to variable vNdr; update the variable nXt with the character.

Manually, we see this in action in Figure 6:

Figure 6: Manually decoding the obfuscation. The string PowerShell is visible.

Figure 7 shows what allowing this process to run to completion yields.

Figure 7: The decoded PowerShell script, both verbatim (top) and formatted (bottom).

The PowerShell script uses the distinctive ‘Split-on-@’ structure that has become synonymous with Geodo-serving macro code. The Macro loops through the URLs, showing in Table 1, and attempts to execute a successfully retrieved file.

Table 1: The URLs from which the macro will attempt to download a Geodo Binary

To stay on top of the latest malware and phishing threats, sign up for free Cofense™ Threats Alerts.


All third-party trademarks referenced by Cofense whether in logo form, name form or product form, or otherwise, remain the property of their respective holders, and use of these trademarks in no way indicates any relationship between Cofense and the holders of the trademarks.