After fixing up the imports, the Reg32 path is retrieved. Default heap is accessed, and Socket / MAC addresses are retrieved. The MAC address is not used in the c2 packet but is used in exception handler and exception data is sent to c2. Here in this subroutine, c2 is notified about the crash:

A number of initialization calls are made after this event

call GetOSVersion mov OSVersion, eax call SetMaxUSerPort call SetMutex_AllocateChunks call AllocHugeBuffer test eax, eax GetOSVersion() reads the OS version from registry SOFTWAREMicrosoftOSVersion Configuration to the binary is set in SetConfig() function . It decodes a configuration from binary using a simple xor algorithm An IDC script can be used to statically recover decoded data #include <idc.idc> static GeneratedString( Offset_) { auto String1 = “”; auto i =0 ; auto String2 = “”; for (i = 0; i < 7416; i++) String1[i] = String1[i] + Byte(0x13158000 + i); for (i = 0; i < 2855; i++) String2[i] = String2[i] + Byte(0x13159CF8 + i); //Message(“First Byte = %sn”, String1); auto Salt1 = “gcguIgMY2yinkfEZPE9nXLpsYZ7X3CSp8“; //< 217 auto Salt2 =         “uCiG9Lw2V4hguufVQoHNkelYsI5iHN1Q8JFUOoTYDeakWgZKo1QOg7KoZxAQRWfqKc8rU“; auto len = Offset_; auto buff = “”; auto cur_len = 0; if (len < 217) { buff = String1[(len * 34) :(len * 34) + 34 ]; //Message(“%s”, buff); //memcpy(buff, String1 + (len * 34), 34);
cur_len = 34 –1; } else{ buff = String2[((len – 0x26) * 70) – 1: ((len – 0x26) * 70) – 1 +         70]; //memcpy(buff, String2 + ((len – 0x26) * 70), 70); cur_len = 70 –1; } i = 0; while (i < cur_len) { if (cur_len == 33) { buff[i] = ord(buff[i]) ^ ord(Salt1[i]); i++; } else{ buff[i] = ord(buff[i]) ^ ord(Salt2[i]); i++; } } return buff; } static main() { if (strstr(GetDisasm(ScreenEA()), “PUSH“)) { auto psDisasm = GetDisasm(ScreenEA()); auto num = long((psDisasm[strlen(“push “):strlen(psDisasm)] )); auto psChunk = GeneratedString(num); MakeComm( ScreenEA() , “Decoded String = “ + psChunk ); } }

The list is saved in following linked list format struct typeinfo { LPVOID Pointer DWORD Length; } It also sets a maxuserport constant to MAX_UNSIGNEDSHORT. Mutex’s are set, and a huge buffer is allocated. After the initialization, a call to a function is made which is responsible for creating few threads. The first thread is responsible for retrieving OSVersion from registry:

Another thread is responsible for making connections to some known hard coded mail servers alt4.gmail-smtp-in.l.google.com n1.smtp.messagingengine.com mail7.digitalwaves.co.nz and makes a connection to following domains on port 25 and wait till cmp Specifier_connection, bx is set which means the connection was successful, if not it will go into a timer state for 120 seconds till other thread functions are created.

There is one more dummy thread which is used to look up on thread ID of the same thread. It checks if it is zero or not Other two threads are responsible for email parsing and spamming and Querying Root DNS servers for COM and RU domains Connection to c2 is made in MainC2Subroutine First 7 DWORD;s from OS version are combined in a buffer and encoded using the following algorithm and offset 223 is used to get the encoding key, and 224 is used to decode the data. Following is the C representation of that algorithm: #include <stdio.h> // Encoding Key 223 == eto ochen prostoarelkioiqyrut unsigned char *EncodeKey = “eto ochen prostoarelkioiqyrut“; #define KEY_SIZE 29 void encode(unsigned char * input, int len ) { unsigned int i = 0; unsigned int j = 0; unsigned char tmp ; unsigned int total_len = 29; unsigned int index = 0; if (len > 29) { while (1) { for (i = 0; i < KEY_SIZE; i++) { input[i] ^= EncodeKey[i]; } for (j = 0; j < 14 ; j++) { tmp = input[j]; input[j] = input[i]; input[i] = tmp; // Swap bytes
i—; } // JA || JZ if ((index & 1)) { for (i =0; i < 29; i++) input[i] = !input[i]; } index = index + 29; total_len = total_len + 29; if (total_len >= len) break; } } if (total_len = total_len % 29) { for (i = index ; i < total_len; i++) { input[i] = !input[i]; } } } Communication synchronization Only first 8 bytes are retrieved first which has the following structure: DWORD len; // Length of packet
DWORD CommandType; // Command Type after receiving the 8 bytes, rest of the bytes are retrieved in a loop

Following are the commands types present in the binary: 8 – Spam Email retrieval 5 – DNS Change 4 – Update Binary 7 – Download and execute from HTTP