Robert Giczewski

Malware Analysis, Forensics, Threat Intelligence, Coding, Tech, Video Games

TrueBot Analysis Part I - A short glimpse into packed TrueBot samples

12 Feb 2023 » malware_analysis, reverse_engineering

In October 2022, Microsoft published a blog post about Raspberry Robin and it’s role in the current cyber crime ecosystem. Microsoft reported, among other things, that they have observed Raspberry Robin delivering the well-known malware families IcedID, Bumblebee and TrueBot besides the already known delivery of FakeUpdates/SocGholish. At this time I was not really aware of TrueBot or I simply had forgotten about it.

In December 2022, Cisco Talos published a blog post in which they reported increased activity from TrueBot and mentioned that TrueBot might be related to TA505. They have observed TrueBot delivering Grace (aka FlawedGrace and GraceWire) as a follow-up payload, which is known to be exclusive tooling of TA505.

Since I have already analyzed some TA505 campaigns a few years ago and anything related to Raspberry Robin is of interest to me, TrueBot now had my attention and I finally found some time to take a closer look and here we are.

I have decided to start a small blog series that will cover the following points:

  1. Analyzing different packed samples and identifying decryption/unpacking code
  2. How to statically unpack with Python using Malduck?
  3. Analyzing TrueBot Capabilities
  4. IOC/Config extraction with Python using Malduck
  5. C2/Bot Emulation
  6. Bonus (maybe): Infrastructure analysis

The blog series is structured so that we gain the knowledge step by step to be able to take the next step.

In this first post, we’ll look at some packed samples and gain enough knowledge to write a static unpacker in the next step.

Identifying decryption/unpacking code

We are primarily looking at the packed samples that Talos also mentioned in their blog post including one sample that I have found on VirusTotal. All of these files are 32 Bit samples, mostly DLLs except for one sample which is a regular executable.

092910024190a2521f21658be849c4ac9ae6fa4d5f2ecd44c9055cc353a26875 
1ef8cdbd3773bd82e5be25d4ba61e5e59371c6331726842107c0f1eb7d4d1f49 
2d50b03a92445ba53ae147d0b97c494858c86a56fe037c44bc0edabb902420f7 
31272235fcdce1d28542c0bc30c069cdb861ff34dd645fe5143ad911fdb1e8a9 
55d1480cd023b74f10692c689b56e7fd6cc8139fb6322762181daead55a62b9e 
58b671915e239e9682d50a026e46db0d775624a61a56199f7fd576b0cef4564d 
6210a9f5a5e1dc27e68ecd61c092d2667609e318a95b5dade3c28f5634a89727 
68a86858b4638b43d63e8e2aaec15a9ebd8fc14d460dd74463db42e59c4c6f89 
72813522a065e106ac10aa96e835c47aa9f34e981db20fa46a8f36c4543bb85d
7a64bc69b60e3cd3fd00d4424b411394465640f499e56563447fe70579ccdd00
7e39dcd15307e7de862b9b42bf556f2836bf7916faab0604a052c82c19e306ca
bf3c7f0ba324c96c9a9bff6cf21650a4b78edbc0076c68a9a125ebcba0e523c9
c3743a8c944f5c9b17528418bf49b153b978946838f56e5fca0a3f6914bee887
c3b3640ddf53b26f4ebd4eedf929540edb452c413ca54d0d21cc405c7263f490
c6c4f690f0d15b96034b4258bdfaf797432a3ec4f73fbc920384d27903143cb0

If you look at the binary, you will relatively quickly stumble upon a large binary blob that is referenced in only one function in the binary. The two loops in which the blob is referenced should give you a good indication that something might be decrypted here, see the screenshot below.

I have checked all available samples and the decryption algorithm is identical in each case, however, there are a few different variations, how the decryption function is called. In the most common variant there is an export, which calls a wrapper function, which in turn calls the decryption function. Sometimes there is only one wrapper function, sometimes several, and sometimes the decryption code is directly in the export of the DLL.



Regular executable where the call to decryption function is located in WinMain:



Decryption code directly in an exported function:



The decryption algorithm uses a hardcoded key and is XOR’ing through the entire binary blob, with incrementing the iterator by the length of the key. Additionally, another part of the decryption “formula” is a boolean and operation with a hardcoded value. By using a debugger, it’s pretty easy to get to the unpacked code. However, since we want a have static unpacker, I reimplemented the function in Python.

def decrypt(data_blob, key, param):
    result = list(data_blob)
    i = 0
    while i < len(key):
        x = i
        key_xor = key[i] ^ param
        while x <= len(result) - 1:
            result[x] = result[x] ^ key_xor ^ ((x & 0xff) & param)
            x += len(key)
        i += 1

    return result


Now, all we need to decrypt is the binary blob, the decryption key and the parameter for the and operation. In my next blog post, I will describe how to get these values with help of Python and Malduck.