Trick Bot – Dyreza’s successor

Share this…

Recently, our analyst Jérôme Segura captured an interesting payload in the wild. It turned out to be a new bot, that, at the moment of the analysis, hadn’t been described yet. According to strings found inside the code, the authors named it TrickBot (or “TrickLoader”). Many links indicate, that this bot is another product of the people previously involved in Dyreza. It seems to be rewritten from scratch – however, it contains many similar features and solutions to those we encountered analyzing Dyreza (read more).

Analyzed samples

TrickBot’s modules:

Additional payload:

Distribution

The payload was spread via a malvertising campaign, involving Rig Exploit Kit:

malvertising_chain

Behavioral analysis

After being deployed, Trick Bot copy itself into %APPDATA% and deletes the original sample. It doesn’t change the initial name of the executable (in the given example the analyzed sample was named “trick.exe”)

installed

First, we can see it dropping two additional files: client_id and group_tag. They are generated locally and used to identify, appropriately: the individual bot and the campaign to which it belongs. Content of both files is not encrypted, it contains text in Unicode.

Example of the client_id – it consists of the name of the attacked machine, operating system version, and a randomly generated string:

client_id

Example of the group_tag:

gtag

Then, in the same location, we can see config.conf appearing. This file is downloaded from the C&C and stored in encrypted form.

config_fragment

After some time, we can see another folder being created in %APPDATA% – it is named Modules. The malware drops there additional modules downloaded from the C&C. They are also stored encrypted. In a particular session, TrickBot downloaded a module called injectDll32 and systeminfo32:

modules_folder

Particular module may also have a corresponding folder, where its configuration is stored. Pattern of the name is [module name]_configs.

modules_configs

When we observe the execution of the malware via monitoring tools, i.e. ProcessExplorer, we can find it deploying two instances of svchost:

svchost_deployes

The bot achieves persistence by adding itself as a task in Windows Task Scheduler. It doesn’t put any effort in hiding the task under a legitimate name, just calls it “Bot”.

bot_task

If the process is killed, it is being automatically restarted by the Task Scheduler Engine:

restarted

Network communication

The Trick Bot connects to the several servers, i.e.:

traffic1

First, it connects to a legitimate server myexternalip.com in order to fetch the IP visible from outside.

The interesting part is that it doesn’t try to disguise as a legitimate browser – instead, using it’s own User Agent: “BotLoader” or “TrickLoader”.

Most – but not all – of the communication with it’s main C&C is SSL encrypted. Below you can see an example of one of the commands sent to the C&C:

net_cmd60

Looking at the url of POST request, we can notice the group_id and the client_id, that are the same as in the files. After that, the command id follows. This format was typical for Dyreza.

The bot downloads also an additional payload (in the particular session it was: 47d9e7c464927052ca0d22af7ad61f5d) without encrypting the traffic:

download_exe

C&Cs are set up on hacked wireless routers, i. e. MikroTik. This way of setting up the infrastructure was previously also used by Dyreza.

router1

Example of used HTTPs certificate – as we can see, used data is fully random, and not even trying to imitate legitimate-looking names:

cert_unk

Inside

Trick Bot is composed of several layers. As usually, the first layer is used for the protection – it carries the encrypted payload and tries to hide it from AV software.

schema

Loader

The second layer is a main bot loader, that chooses whether to deploy 32-bit or 64-bit payload. New PE files are stored in resources – in encrypted form. However, authors didn’t try to hide the functionality of particular elements, and looking at the names of the resources, we can easily guess what their purpose is:

res_names

Selected modules are decrypted during execution.

At the beginning, the application fetches information about victim’s operating system, in order to choose the appropriate way to follow:

loader_path

Depending on the environment, suitable payload is picked from resources, decrypted by a simple algorithm and validated:

decypting_pe

Decrypting procedure is different than the one found in Dyreza – however, the general idea of organizing content (3 encrypted modules in resources) is analogical.

def decode(data):
    decoded = bytearray()
    key = 0x3039
    i = 0
    for i in range(0, len(data)):
        dec_val = data[i] ^ (key % 0x100)
        key *= 0x0AE529
        key += 0x24D69
        decoded.append(dec_val)
    return decoded

See full decoding script: https://github.com/hasherezade/malware_analysis/blob/master/trickbot/trick_decoder.py
Then, the unpacked bot is mapped to the memory by a dedicated function and deployed.

The 32-bit bot maps the new module inside its own memory (self-injection):

map_in_itself

and then redirects execution there:

call_loaded

Entry point of the new module (TrickBot core):

trick_bot_main

In case of 64-bit payload, first the additional executable – 64bit PE loader – is being unpacked and run, and then it loads the core, malicious bot.

In contrary to Dyreza – which main modules were DLLs – TrickBot uses EXEs.

The Trick Bot internals

The bot is written in C++. It comes with two resources with descriptive names: CONFIG – that stores encrypted configuration – and KEY – that stores Elliptic Curve key:

bot_resources

In general this malware is very verbose, meaningful names can be found on every stage.

The name “TrickBot” appears also in the name of global mutex (“Global\\TrickBot”), created by the application in order to ensure, that it is run only once:

checking_mutex_trickbot

At first execution, Trick Bot copy itself into a new location (in %APPDATA%) and deploy the new copy, giving as an argument path to the original one, that needs to be deleted:

deploy_dropped

Adding a task of running bot into the Task Scheduler:

adding_to_taskschd

Setting the triggering event:

setting_trigger

We can find the date pointing to the beginning of 2016, that may confirm the observation, that the bot is new, written in this year.

Trick Bot’s Commands

TrickBot communicates with its C&C and send there several commands – in format similar to the one used by Dyreza. Below – list of format strings used by TrickBot commands:

commands

compare with Dyreza’s commands’ format:

dyre_commands

Trick Bot’s commands’ IDs are hardcoded in the format strings. However, all of them they are deployed from inside the same function, that gets the command ID as a parameter, i.e.:

command_14

After filling the appropriate format string and sending it to the C&C, bot checks the HTTP response code. If the returned code is different than: 200 (OK), 403 (Forbidden), 404 (Not found) – then it tries again.

check_resp

Full list of implemented commands’ IDs:

0
1
5
10
14
23
25
63

Each command has the same prefix – that is a group id of the campaign and bot’s individual id (the same data that are stored in dropped files). Format:

/[group_id]/[client_id]/[command_id]/...

Sample url:

https://193.9.28.24/tmt2/TESTMACHINE_W617601.653EB63213B91453D28A68C80FCA3AC4/5/sinj/

Encryption

TrickBot uses alternatively two encryption algorithms: AES and ECC.

decrypt_chain

The downloaded modules and configuration are encrypted by AES in CBC mode. The AES key and initialization vector are derived from the data, by a custom, predefined algorithm. First, 32 bytes of input data is hashed, using SHA256. Then, the output of the hashing function is appended to the data buffer and hashed again. This step is repeated until the full size of data in buffer become 4096. So, the hashing operation repeats 128 times. Below you can see the responsible fragment of code:

hashing_rounds

First 32 byte long chunk of data is used as a initial value to derive AES key:

hash_first_chunk

And bytes from 16 to 48 are used as a initial value to derive AES initialization vector:

iv_chunk1

Compare with the content of CONFIG (mind the fact that the first DWORD is a size, and is not included in the data):

iv_chunk_dump

Full decoding script you can find here: https://github.com/hasherezade/malware_analysis/blob/master/trickbot/trick_config_decoder.py

Decrypting hardcoded configuration using AES:

decrypr_stored_config

In case if particular input could not be decrypted via AES, the attempt is made to decrypt it via ECC:

ecc_decrypt

Trick Bot’s configuration

Similarly to Dyreza, TrickBot uses configuration files, that are stored encrypted.

Trick Bot’s executable comes with a hardcoded configuration, that, during execution is substituted by it’s fresh version, downloaded from the C&C and saved in the file config.conf. Below you can see the decrypted content of the hardcoded one:

<mcconf>
<ver>1000002</ver>
<gtag>tmt2</gtag>
<servs>
<srv>91.219.28.77:443</srv>
<srv>193.9.28.24:443</srv>
<srv>37.1.209.51:443</srv>
<srv>138.201.44.28:443</srv>
<srv>188.116.23.98:443</srv>
<srv>104.250.138.194:443</srv>
<srv>46.22.211.34:443</srv>
<srv>68.179.234.69:443</srv>
<srv>5.12.28.0:443</srv>
<srv>36.37.176.6:443</srv>
<srv>37.109.52.75:443</srv>
<srv>27.208.131.97:443</srv>
</servs>
<autorun>
<modulename=systeminfo ctl=GetSystemInfo/>
<modulename=injectDll/>
</autorun>
</mcconf>
view rawmcconf.xml hosted with ❤ by GitHub

Compare it with a downloaded one – version number got incremented, and some C&Cs have changed:

<mcconf>
<ver>1000003</ver>
<gtag>tt0002</gtag>
<servs>
<srv>91.219.28.77:443</srv>
<srv>193.9.28.24:443</srv>
<srv>37.1.209.51:443</srv>
<srv>138.201.44.28:443</srv>
<srv>188.116.23.98:443</srv>
<srv>104.250.138.194:443</srv>
<srv>46.22.211.34:443</srv>
<srv>68.179.234.69:443</srv>
<srv>5.12.28.0:443</srv>
<srv>36.37.176.6:443</srv>
<srv>37.109.52.75:443</srv>
<srv>84.232.251.0:443</srv>
</servs>
<autorun>
<module name=systeminfo ctl=GetSystemInfo/>
<module name=injectDll/>
</autorun>
</mcconf>
view rawmcconf2.xml hosted with ❤ by GitHub

Notice that names of the listed modules (systeminfo, injectDll) are corresponding to those, that we found in the folder Modules during the behavioral analysis. It is due to the fact, that this configuration gives instructions to the bot, and orders it to download particular elements.

Some of the requests result in downloading additional pieces of configuration. Example of the response, after being decrypted by the bot:

<servconf>
<expir>1480550400</expir>
<plugins>
<psrv>80.79.114.179:443</psrv>
</plugins>
</servconf>
view rawservconf.xml hosted with ❤ by GitHub

Modules

TrickBot is a persistent botnet agent – but its main power lies in the modules, that are DLLs dynamically fetched from the C&C. During the analyzed session, the bot downloaded two modules.

  • getsysinfo – used for general system info gathering
  • injectDll – the banker module, injecting DLLs in target browsers in order to steal credentials

List of the attacked browser is hardcoded in the injectDll32.dll:

attecked_browsers

It case of the Dyreza, this attack was performed directly from the main bot, rather than from the added DLL.

Details of the attacked target are given in an additional configuration file, stored in the folder: Modules\injectDll32_config.  Below we can see it’s decrypted form revealing the attacked online-banking systems:

<igroup>
<dinj>
<lm>*/onlineserv/CM*</lm>
<hl>91.219.28.103/response.php</hl>
<pri>100</pri>
<sq>1</sq>
</dinj>
</igroup>
<igroup>
<dinj>
<lm>*ibanking.stgeorge.com.au/ibank/loginPage.action*</lm>
<hl>91.219.28.103/response.php</hl>
<pri>100</pri>
<sq>1</sq>
</dinj>
</igroup>
<igroup>
<dinj>
<lm>*ib.nab.com.au/nabib/index.jsp*</lm>
<hl>91.219.28.103/response.php</hl>
<pri>100</pri>
<sq>1</sq>
</dinj>
</igroup>
<igroup>
<dinj>
<lm>*banking.westpac.com.au/wbc/banking/handler*</lm>
<hl>91.219.28.103/response.php</hl>
<pri>100</pri>
<sq>1</sq>
</dinj>
</igroup>
<igroup>
<dinj>
<lm>*anz.com/IBAU/BANKAWAYTRAN*</lm>
<hl>91.219.28.103/response.php</hl>
<pri>100</pri>
<sq>1</sq>
</dinj>
<dinj>
<lm>*anz.com/INETBANK/login.asp*</lm>
<hl>91.219.28.103/response.php</hl>
<pri>100</pri>
<sq>1</sq>
</dinj>
</igroup>
<igroup>
<dinj>
<lm>*cibconline.cibc.com/olbtxn/authentication/*.cibc*</lm>
<hl>91.219.28.103/response.php</hl>
<pri>100</pri>
<sq>1</sq>
</dinj>
</igroup>
view rawdinj.xml hosted with ❤ by GitHub

The instances of svchost.exe, observed during the behavioral analysis, are used to deploy particular modules.

Below – the module injectDll (marked sinj) in memory of svchost:

enc_svchost_inject_sinj

and the module systeminfo (marked GetSystemInfo) in memory of the another instance of svchost:

inected_in_svchost1

Conclusion

Trick Bot have many similarities with Dyreza, that are visible at the code design level as well as the communication protocol level. However, comparing the code of both, shows, that it has been rewritten from scratch.

Source