[QuickNote] Decrypting the C2 configuration of Warzone RAT

Posted: March 25, 2023 in My Tutorials, [QuickNote] Decrypting the C2 configuration of Warzone RAT
Tags: , , , ,

1. Introduction

Warzone RAT is a type of malware that is capable of infiltrating a victim’s computer and giving attackers remote access and control over the system. The malware has gained notoriety for its advanced capabilities and ability to evade detection, making it a serious threat to computer security.

Warzone RAT is typically spread through phishing emails or other social engineering techniques, where attackers trick victims into downloading and installing the malware on their systems. Once the malware is installed, it can perform a variety of malicious actions, including stealing passwords, taking screenshots, and logging keystrokes. It can also download and execute additional malware, giving attackers even more control over the victim’s system.

One of the key features of Warzone RAT is its ability to encrypt its configuration data, making it difficult for security experts to analyze and understand how the malware operates. Currently, there are two variants of the malware in circulation, each using a different method to decode its configuration. The first variant uses standard RC4 encryption, while the second variant uses a modified version of RC4. This modification makes it even more challenging to decrypt and analyze the malware’s configuration data.

2. Analysis

Sample1: 00930cccd81e184577b1ffeebf08ee6a32dd0ef416435f551c64d2bcb61d46cf (use standard RC4)

Sample2: 61f8bf26e80b6d6a7126d6732b072223dfc94203bb7ae07f493aad93de5fa342 (use modified RC4)

In Warzone RAT, the configuration info is stored in the .bss PE section of the malware’s code. The .bss section is typically used for storing uninitialized data. The format of the configuration is as follows: [Key length] [RC4 key] [Encrypted data]. Below is an illustration of the configuration stored in the .bss section in both samples.

The steps to perform the process of retrieving information and copying data from the .bss section to memory are the same in both samples. The pseudo-code is shown below:

The pseudo code in function wzr_decrypt_config in both samples is the same, which involves extracting the RC4 Key and Encrypted data, and then using RC4 to decrypt the configuration. The difference lies in function wzr_perform_rc4.

The function wzr_perform_rc4 in sample 1 uses standard RC4 to decrypt the configuration. Its pseudocode is shown below:

Thus, we can easily use CyberChef to perform configuration decoding or write a Python script to automate for similar samples.

The pseudocode for function wzr_perform_rc4 in sample 2 as shown below. Prior to decryption, it allocates an array of 250 bytes, filled with zero values. Then, it copies the extracted rc4_key into this array. Finally, it calls the wzr_rc4_crypt function, which uses the modified RC4 algorithm to decrypt the configuration.

The complete pseudocode of the wzr_rc4_crypt function is as follows:

void __thiscall wzr_rc4_crypt(wzr_rc4_data *rc4_info, _BYTE *data)
  idx = 0;
  if ( rc4_info->rc4Sbox )
    if ( rc4_info->rc4_key_250b )
      rc4_info->counter2 = 0;
      LOBYTE(i) = 0;
      rc4_info->counter1 = 0;

        rc4_info->rc4Sbox[i] = rc4_info->counter1;
        i = rc4_info->counter1 + 1;
        rc4_info->counter1 = i;
      while ( i < 256 );
      rc4_info->counter1 = 0;
      for ( i = 0; i < 256; rc4_info->counter1 = i )
        rc4Sbox = rc4_info->rc4Sbox;
        rc4_info->counter2 += rc4Sbox[i] + rc4_info->rc4_key_250b[i % 250];
        rc4Sbox[i] ^= rc4Sbox[rc4_info->counter2];
        // swap values
        rc4_info->rc4Sbox[LOBYTE(rc4_info->counter2)] ^= rc4_info->rc4Sbox[LOBYTE(rc4_info->counter1)];
        rc4_info->rc4Sbox[LOBYTE(rc4_info->counter1)] ^= rc4_info->rc4Sbox[LOBYTE(rc4_info->counter2)];
        i = rc4_info->counter1 + 1;
      rc4_info->counter1 = 0;
      rc4_info->counter2 = 0;
      // Decrypt data
      if ( rc4_info->data_length )
        j = 0;
          rc4_info->counter1 = j + 1;
          rc4Sbox = rc4_info->rc4Sbox;
          k = (j + 1);
          rc4Sbox_value1 = rc4Sbox[k];
          rc4_info->counter2 += rc4Sbox_value1;
          rc4Sbox_value1_ = rc4Sbox_value1;
          rc4Sbox_value2 = rc4Sbox[rc4_info->counter2];
          rc4Sbox[k] = rc4Sbox_value2;
          rc4_info->rc4Sbox[LOBYTE(rc4_info->counter2)] = rc4Sbox_value1;
          rc4Sbox_ = rc4_info->rc4Sbox;
          data[idx] ^= rc4Sbox_[(rc4_info->counter2 + rc4Sbox_value2)] ^ (rc4Sbox_[(rc4Sbox_value2 + rc4Sbox_value1_)]
                                                                        + rc4Sbox_[(rc4Sbox_[((0x20 * rc4_info->counter2) ^ (rc4_info->counter1 >> 3))]
                                                                                  + rc4Sbox_[((0x20 * rc4_info->counter1) ^ (rc4_info->counter2 >> 3))]) ^ 0xAA]);
          j = ++rc4_info->counter1;
        while ( idx < rc4_info->data_length );

With the pseudocode above, we can rewrite the decoding code in Python as follows. This is the code I wrote, and you can write it in your own way as long as it performs the task correctly.

# Refs: https://stackoverflow.com/questions/9433541/movsx-in-python
def SIGNEXT(x, b):
    m = (1 << (b -1))
    x = x & ((1 << b) -1)
    return ((x ^ m) - m)

# This routine is responsible for decrypting the stored C2.
def rc4_customized_decryptor(data, key):
    idx = 0
    counter1 = 0
    counter2 = 0
    # Initialize RC4 S-box
    rc4Sbox = list(range(256))
    # Modify RC4 S-box
    for i in range(256):
        counter2 += (rc4Sbox[i] + key[i%250])
        counter2 = counter2 & 0x000000FF
        rc4Sbox[i] ^= rc4Sbox[counter2]
        rc4Sbox[counter2 & 0xFF] ^= rc4Sbox[counter1 & 0xFF]
        rc4Sbox[counter1 & 0xFF] ^= rc4Sbox[counter2 & 0xFF]
        counter1 = i+1        
    # Decrypt data
    counter1 = 0
    counter2 = 0
    j = 0
    decrypted = []
    while(idx < len(data)):
        counter1 = j + 1
        k = (j+1)
        rc4Sbox_value1 = rc4Sbox[k]
        counter2 += (SIGNEXT(rc4Sbox_value1, 8) & 0xFFFFFFFF)
        rc4Sbox_value1_ = (SIGNEXT(rc4Sbox_value1, 8) & 0xFFFFFFFF)
        rc4Sbox_value2 = rc4Sbox[counter2 & 0x000000FF]
        rc4Sbox[k] = rc4Sbox_value2
        rc4Sbox[(counter2 & 0x000000FF)] = rc4Sbox_value1
        tmp1 = rc4Sbox[((0x20 * counter1) ^ (counter2 >> 3)) & 0x000000FF]
        tmp2 = rc4Sbox[((0x20 * counter2) ^ (counter1 >> 3)) & 0x000000FF]
        tmp3 = rc4Sbox[((tmp1 + tmp2) & 0x000000FF) ^ 0xAA]
        tmp4 = rc4Sbox[(rc4Sbox_value2 + rc4Sbox_value1_) & 0x000000FF]
        tmp5 = (tmp3 + tmp4) & 0x000000FF
        tmp6 = rc4Sbox[(counter2 + rc4Sbox_value2) & 0x000000FF]
        decrypted.append(data[idx] ^ (tmp5 ^ tmp6))
        counter1 += 1
        j = counter1
        idx += 1
    return bytes(decrypted)

Below are the results of using a Python script to extract the configuration of Warzone RAT from the samples used in the article.

3. End

The article would like to conclude here. I hope that it provides useful information for you during the process of analyzing the Warzone RAT malware. To protect against Warzone RAT and other types of malware, users should take precautions such as being cautious when opening email attachments, using strong passwords, and keeping their software up to date. It is also important to use antivirus software and to keep it updated regularly. By taking these steps, users can help to protect themselves against the threat of Warzone RAT and other types of malware.

4. Refs



  1. […] Article Link: [QuickNote] Decrypting the C2 configuration of Warzone RAT | 0day in {REA_TEAM} […]

  2. […] 0day in {REA_TEAM}[QuickNote] Decrypting the C2 configuration of Warzone RAT […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.