Flickr

Labels

Peering into Dyre's Traffic

Dyre (also known as Dyreza) is a banking trojan that has got quite a bit attention over the last few months. Nevertheless, it's always interesting to re-visit a known threat to see what has changed.

This post provides an insight into the traffic encryption used by Dyre and what additional components it relies on. The provided source code allows decryption of downloaded Dyre configurations and plugins from the known C&C hosts.
But let's start from the dropper.

The sample of Dyre (MD5:b7db8e9943ab39a60d8470fe2f859164) is delivered in form of a dropper that performs several stages of memory allocation and decryption operations until the actual payload code gets control.

The dropper first allocates memory, decrypts a decoder in it, and then passes control to it. Once the decoder gets control, it will reconstruct a PE-file back at the original virtual address. The PE file is then restored section-by-section. Next, its import table is fully reconstructed. These steps are well outlined in this post.

The restored PE file is a 2nd-stage dropper. It registers itself as a service "gupdate", and then injects a final payload DLL into the svchost.exe or explorer.exe process.

This 2nd-stage dropper carries the following randomly-named resources:

• uzgn23wmb - 256-byte key

• twry615nl - 32-bit resource DLL

• ysfh426g0 - 64-bit resource DLL

Depending on whether the target is running a 32-bit or 64-bit system, it will either inject a 32-bit payload DLL, or a 64-bit one.

The injection is achieved with the ZwQueueApcThread() API call. This injection method has already been used by Carberp, and its source code is available publicly.

The injected DLL

The DLL injected by the 2nd stage dropper into svchost.exe or explorer.exe contains the following 5 randomly named resources:

The most important resource is the encrypted configuration file. The encryption algorithm used to protect this file is based on standard AES 256-bit (ECB mode) and SHA-256 algorithms.

The algorithm has changed since its last known implementation described by Lexsi's researchers.

At the moment, the encrypted data starts from a 48-byte header. The header is used to calculate an AES key by hashing with SHA-256 and shuffling its bytes repeatedly. Once the key is calculated, it will be used to decrypt the rest of data - this time by decrypting it with AES 256-bit, also shuffling the data bytes repeatedly.

The decryption algorithm used by the attackers is best illustrated with the source code below:

The source code below illustrate the decryption algorithm used by the attackers:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

void build_complex_hash(int iterations,

unsignedchar *data,

int data_size,

unsignedchar *hash,

int hash_size)

{

unsignedchar block[48];

unsignedchar temp_hash[32];

sha256(data, data_size, temp_hash);

for (int i = 0; i < iterations; i++)

{

memcpy(block, temp_hash, 32);

for (int j = 0; j < 16; j++)

{

block[j + 32] = temp_hash[j] + 1;

}

sha256(block, 48, temp_hash);

}

memcpy(hash, temp_hash, hash_size);

}

void decrypt_data(unsignedchar *data, int data_size)

{

unsignedchar hash[0x30];

build_complex_hash(0x80, data, 0x20, hash + 0x10, 0x20);

build_complex_hash(0x40, data + 0x20, 0x10, hash, 0x10);

aes256_context ctx;

aes256_init(&ctx, hash + 0x10);

unsignedchar temp[16];

for (int i = 0; i < ((data_size - 0x31) >> 4) + 1; i++)

{

memcpy(temp, data + 0x30 + i * 0x10, 16);

aes256_decrypt_ecb(&ctx, data + 0x30 + i * 0x10);

for (int j = 0; j < 16; j++)

{

data[0x30 + i * 0x10 + j] ^= hash[j];

}

memcpy(hash, temp, 16);

}

}

In the code above, the sha256() function takes data, its size, and a digest pointer - the call matches standard SHA-256 implementations such as this one.

The AES-related calls/declarations above rely on this implementation of the AES algorithm.

The decrypted resource contains the list of hosts (IP and port), and is trailed with a digital signature, as shown below:

In order to check the integrity of decrypted host configuration data, Dyre does the following:

• loads its 8HRUV7NZJ resource

• decrypts it using SHA/AES-derived algorithm explained above - the decrypted key starts from BCRYPT_ECCKEY_BLOB structure that contains 'ECS3' token followed with 0x30 - the size of key (BCRYPT_ECDSA_PUBLIC_P384_MAGIC, 48-byte/384-bit)

• loads it with BCryptImportKeyPair(.."ECCPUBLICBLOB") function call

• hashes the decrypted configuration data with BCryptHashData()

• calls BCryptVerifySignature() to make sure the obtained hash matches the appended digital signature, which is the signed hash of the data

IPC

The activated DLL thus obtains the list of C&C servers.

As soon as the user launches a browser, the DLL will migrate into a running browser process to control online banking sessions. A code running under the browser cannot do high-privilege work (due to low integrity/sandbox restrictions) such as storing configuration data in the arbitrary files. Because of that, Dyre splits its functionality between the instances running under svchost.exe/explorer.exe and a browser process.

The instance running under svchost.exe/explorer.exe serves as a proxy for the browser instance, serving all its requests such as configuration data requests. All the requests and responses are wrapped into IPC (inter-process communication) messages over a named pipe (\\.\pipe\g2fabg5713).

For example, the following communication was logged by hooking the IPC communication between two instances of Dyre code. The first line shows commands received by the proxy instance from the browser. The second line shows its reponse written back into the pipe.

The communication above shows that at the start, there is no valid response for 'rpls' command - hence the answer is 'no'. However, as soon as a new online banking injection configuration is fetched by the proxy instance from C&C and decrypted, it is transferred via the pipe in clear text back to the browser instance, allowing it to apply the parsing/manipulation logic to the online banking sessions.

C&C Protocol

Using the list of C&C servers obtained from the decrypted resource, Dyre tries contacting them one-by-one until one of the live hosts responds.

The first thing the bot tries to do is to fetch a new public key that will be used to check the validity of digital signature appended to all received files.

The received data is then decrypted using the same SHA/AES-derived algorithm. The decrypted data starts from the 'Ok' marker. Within its body it contains a new 256-bit ECDSA public key that starts from 'ECS1' signature followed with 0x20 (BCRYPT_ECDSA_PUBLIC_P256_MAGIC, 32-byte/256-bit). The entire blob is trailed with a digital signature to be verified with the earlier obtained 384-bit ECDSA public key:

The downloaded files are decrypted with the SHA/AES-derived algorithm as before. The integrity of the files is secured with the attached digital signature.

The 'httprex' command fetches the configuration data that specifies web servers that will receive intercepted online banking sessions data. This file starts from 'srv_name' and 'werserv' aliases that are further used within the configuration. The intercepted data is submitted with a POST request to the specified servers, so that any data that the user enters during online banking is hijacked.

If the user navigates to one of the online banking sites targeted within the configuration file, the proxy instance of Dyre will request the content of a 'backconnect' configuration file. This file is requested with 'bccfg' command. Once received and decrypted, the 'backconnect' configuration file will specify the host IP and port numbers where the bot should back-connect to, to make remote VNC/RDP control possible behind NAT/firewall:

• 212.129.36.69:9900

• 46.165.245.223:9900

• 46.165.223.143:9900

• 193.111.140.185:9900

• 62.210.239.243:9900

• 62.210.108.155:9900

After that, the bot will fetch additional plug-ins that enable VNC/RDP remote control and data stealing capabilities, using the following commands (either 32-bit or 64-bit version, depending on the OS version):

Dyre contains code that allows adding a new user to the administrator group (having password "1qazxsw2"), logging that user on to the local computer, and loading its profile. Armed with the RDP/VNC plugins, Dyre establishes control over the victim's online banking session.

One of the nasty parameters found in the bot's configuration parser is called AUTOKILLOS. If it's set to TRUE, the bot will delete users from the local computer with NetUserDel() API call, including its own previously created user. Next, it will overwrite boot sectors of the drives C: and D: with random bytes, terminate itself, and shut the system down. These steps are designed to render the system unbootable. The AUTOKILLOS parameter was not found in the live configurations so far, but the bot is capable of executing it if the attackers decide to add it in the future.