PushDo Trojan is a downloader trojan responsible for downloading its spam counterpart and other malicious Trojans. Since its beginning, it has evolved into many different versions and in this blog post, we will make a deeper analysis of it.

The Packer

PushDo Trojan often comes along with a packer, which will unpack code in a separate process. As long as the malware is always injected in a separate process, the unpacked file begins with repairing all IAT entries needed for correcting Windows API resolution.

In addition, it sets up a handler for any Unhandled Exception occurrence. This filter, basically restarts the process on Unhandled Exception Raised. It also features and performs a kind of a packer integrity check based on which certain parameters in the binary are set. With the failure of the checks, it simply terminates itself.

These checks are based on a place holder and a systematic hashing of data.

If all the checks are passed correctly, it will then go on to set an internal information structure which consists of: OS version, Ffilename/parent process name, aA CLSID generated using sysinternals such as HWAddr, and system drive VolumeSerialNumber and crc32 hash of process file.

Installation, Persistence & Call back home

Then, it will call its installation subroutine, which copies the binary to a destination directory in %userprofile% and starts a thread to assure the persistence into the system.

There are 4 times at which the malware tries to connect to c2 in the following priority order:

Encoded Rc4 embedded buffer consisting of IP and Ports IP:PORT from a random registry key (32byte string key name) Default compressed block of domains DGA (as a fallback mechanism)

It generates a pseudo random 32byte String by XORing all 4 DWORDS from the CLSID and repeatedly hashing it with MD5. Such string will be the name of a registry key which will be used to store information related to payloads coming from C2 servers.

Default compressed block of domains

C2 domains are compressed and embedded inside the binary:

Binary might also consist of a chunk of RC4 encrypted data, which is formatted as IP:Port. It might also be taken from a registry key data which is retrieved from C2.

The data from RC4 encoded buffer and registry key is utilized first before connecting to the default embedded C2 domains list.

In the main communication routine, it creates two threads responsible for parsing and communicating to C2’s. These threads are synchronized to work together.

The request packet is generated out of some of the following items:

Domain Name and Mutex

FileName

CLSID and hardcoded constants;

SystemMetirc Information

Order table copy

OS information

Sysinfo mask

Crc32 hash

Parent process

Constants

Total Physical Memory

MutexName

The order to their placement is determined by a sorted byte array determining the order in which the information is to be copied into the request packet. A part of this byte array is also copied to the request packet.

The information is organized in the following way in each of the elements:

#pragma pack(1) struct {

WORD Identifier; //Type of data

WORD len; //length of data

BYTE data[]

}

This data is appended with some random DWORDs and crc32 hash of data chunk. Also, a randomly generated key is appended to the packet with a size DWORD specifier. This key is used to encrypt the data between the appended block. A partial block is encoded with LCG using a randomly generated DWORD. Furthermore, this whole Chunk of data is encoded using base64 and is sent to command and control server.

At the receiving end, it scans for an HTML comment placeholder and extracts the data enclosed in between. This data enclosed is base64encoded and once it is decoded a binary structure is revealed.

The offset 0x40 it consists of a SEED for LCG decoder with an identifier at 0x00 which has to satisfy the axiom DOWRD % 0x1ECB == 10.

DWORD at 0x08 offset is the crc32hash data chunk.

After decoding the data buffer (after offset 12 to 16) by LCG. The first DWORD is the total size of the payload, which will be decoded using LCG with the same initial seed.

After such LCG decoding, that binary block is decrypted using an embedded key in the binary.

After successfully decoding we obtain the following structure:

The first 28 bytes it provides information about payload size, the number of payloads and some constants about how the payload is supposed to be used. Based on these constants payload is used and stored in a certain way.

The first DWORD consists of a number of payload entries

The second is the size.

Based on constants after which are present after second DWORD Data is either compressed or plain text. Notice that if it is compressed by GZIP it is either injected into the current process or inside SVCHOST.exe. If it is text based then it contains updated C2 IP:port list which is stored in a the registry entry using the Random value generated using CLSID as mentioned earlier, allowing the Pushdo bot update the C2 list stored in registry key connects to these IP in the next run.

If new C2 list is updated, the time limit to next C2 connection is reduced to 1 second, so that it will immediately connect (instead of connecting after next 6 hrs frequency specified on certain constants) and it is decided whether to inject an embedded PE file.

Pushdo Binary also consists of an embedded PE File. This PE file is a very small and is injected in the target process as well.

This PE File consists of an encoded buffer and is decoded comparing buffers and inserting on certain offsets:

After successful decoding, some domain names are revealed. These domains are not malicious ones, but rather chosen randomly.

It creates two threads, which connect to randomly chosen domains among them and send random ASCII data on port 80 and 25.

This PE file is benign and we believe it’s used to trick AV Vendors and security malware analysts into believing that this file was responsible for infecting the system as it makes C2 request similar to that of PushDo structure.

PushDo also features a fallback mechanism using a DGA (Domain generation Algorithm) it generated domains prefixed with .kz using a combination of current date and hash.

Raashid Bhat

Malware Analyst