💀
0xTriboulet
  • Introduction
  • Achieving Access
    • achieving access: implantv1
    • achieving access: implantv2
    • achieving access: implantv3
  • Deceiving Defender
    • Deceiving Defender: Making nc.exe viable again
    • Deceiving Defender: Classic Bypass
    • Deceiving Defender: Name Bypass
    • Deceiving Defender: The Texas Two Step
    • Deceiving Defender: The Big Stack Bypass
      • Making Meterpreter Viable Again
    • Deceiving Defender: Meterpreter
  • Making Malware
    • making malware #0
    • making malware #1
    • making malware #2
  • Just Malicious
    • Advanced String Obfuscation
    • From C, with inline assembly, to shellcode
    • Thnks4RWX
  • TTPs
    • TTPs: Embedding Payloads with MSFVenom (x86)
    • TTPs: Embedding Payloads with MSFVenom (x64)
    • TTPs: Rust vs C++
    • TTPs: JmpNoCall
    • TTPs: BadAsm
    • TTPs: BadStrings
  • Unholy Unhooking
    • Unholy Unhooking: byoDLL
    • Unholy Unhooking: FrByoDLL
    • Unholy Unhooking: Rusty Fart
  • Weird Windows
    • Command Hijacking with .COM
    • Non-Existent File Paths
  • ZeroTotal
    • ZeroTotal: Msfvenom Calc
    • ZeroTotal: Self-Injecting Calc
    • ZeroTotal: Rusty Calc
  • Disclaimers
Powered by GitBook
On this page
  • Part One: Introduction
  • Part Two: Getting Started
  • Part Three: Fighting FLOSS
  • Part Four: More Obfuscation
  • Part Five: Improved Utility
  • Part Six: Conclusion
  • References:
  1. TTPs

TTPs: BadStrings

In this writeup we discuss a mutli-step methodology for beating string detection by Mandiant's FLOSS string deobfuscator

PreviousTTPs: BadAsmNextUnholy Unhooking

Last updated 1 year ago

Part One: Introduction

Strings are reasonably common in executables, and any reverse engineering class will cover the utility of dumping an executable's strings to discover critical features of the executable's functionality. To mitigate the discovery of capabilities by analysts, malware authors will often encode, encrypt, or hash strings to obfuscate critical functionality. Most commonly, malware will implement XOR encryption to hide strings from basic analysis.

However, modern tools allow for emulating the decryption function and consequently discovering those key strings. One of these tools is Mandiant's FLOSS.

This tool is a powerful utility for analysts. FLOSS can deobfuscate the key strings encrypted by malware authors and help analysts unmask key executable functionality using advanced static analysis. In this writeup, we'll be closely examining the effect this can have and one way to bypass this analysis.

Part Two: Getting Started

Below we have a pretty basic program that prints out our "secret".

We can quickly compile this program, and run the "strings" utility on it and discover that our secret is indeed exposed.

Now, we can use an online utility, python script, or additional C program to encrypt our secret string with the XOR algorithm. We'll be using CyberChef in this writeup, but any approach to obtaining an XOR'd string would work.

If we write the appropriate code to decode our secret, we'll end up with something like the picture below.

On the left, you can see the source code of our program. We take the encrypted secret, hardcode the key and length into our program, initialize our decrypted buffer, and then call our xor_func(). This function will then take our encrypted string, decrypt it with our key, and store it in our decrypted buffer. Once that decryption is complete, our program will print our secret.

On the right, you see that our program functions as expected, and we can no longer find the secret using the "strings" utility.

Part Three: Fighting FLOSS

But what happens if we run FLOSS on our program?

Here we see that FLOSS can decode our string, which is unfortunate for our malware development. However, we can notice something interesting by combing through FLOSS' recent updates.

It looks like we can trick FLOSS into overlooking our secret but referencing the string with another function. Lets check out how we might do that.

Part Four: More Obfuscation

If we go back to CyberChef, lets add one easy manipulation. Lets add one to our output values in our array like so.

Now that we've done that, we can quickly implement a decrement function in our C program that will allow us to have a second reference to our obfuscated string and trick FLOSS into overlooking our shenanigans.

Here we can see that this simple trick has in fact allowed us to retain our program's functionality, the strings function still can't find our secret, and our secret string is unobtainable with FLOSS.

Part Five: Improved Utility

It would be pretty cumbersome to write and maintain two functions every time we wanted to unobfuscate a string in our C code. Thankfully, C provides us macros that we can use to automate this process a little bit and maintain clarity in our code.

In the above picture we see that at the top of main.c we declare the DECRYPT_STRING macro. This macro is processed by the compiler, so that the substitution we defined occurs before compilation. In this way we can more clearly see and maintain our code without having to find every pair of function calls and modifying them individually. In this proof of concept the change is largely cosmetic, but in larger projects like Revenant it's important to leverage this capability for clarity.

Part Six: Conclusion

In this writeup, we saw that it's possible to bypass FLOSS' analysis by executing multiple manipulations on our obfuscated strings, and we saw that it's possible to consolidate these manipulations into a single C macro for clarity in our code. Revenant leverages a similar implementation of this functionality to similarly bypass FLOSS analysis and maintain the obfuscation of crucial information like IP addresses, UserAgent, and dlls that would facilitate the development of signatures for our implant.

References:

https://gchq.github.io/CyberChef/
https://github.com/mandiant/flare-floss
Page cover image
https://github.com/mandiant/flare-floss