Under Attack? Call (844) END.DDoS

Who Let the Pandas Out? Zeus, Zeus, Zeus, Zeus

Dennis Schwarz

A few months ago Proofpoint released a blog post about a new banking trojan called Panda Banker. They credit Fox-IT with the discovery and both companies indicate that it is another variant based on the Zeus banking trojan source code. Under the hood Panda Banker certainly feels Zeus-like, but it has plenty to distinguish itself from the other variants such as Citadel and ZeusVM. This post takes a closer look at Panda Banker’s command and control (C2) mechanism and what it takes to elicit the configuration and webinject rules from its C2 servers.

Samples

The following samples were used for this post:

Base Config

The base config is a variable length binary structure that is stored encrypted in the malware executable. Among other things it contains a crypto key, C2 URLs, and the botnet name. Throughout the code there will be references to the encrypted base config that look similar to this:

base_config_code

While it looks like a binary blob, the encrypted base config does have a structure to it that is used to decrypt it:

  • 32-byte SHA-256 hash of the remaining data
  • 32-byte AES key
  • 16-byte AES IV
  • Encrypted data using AES-256 in CBC mode

Once decrypted, the first piece that needs to be extracted from it is a crypto key. The offsets within the base config will vary from sample to sample, but here is an example:

crypto_key

The key is an RSA public key formatted as a X.509 subjectPublicKeyInfo DER SEQUENCE.

There can be multiple C2 URLs encrypted in the base config at various offsets. Each encrypted C2 chunk is 101 bytes in length. Despite being a RSA public key, the above key is used with RC4 to decrypt the URLs. Here are the URLs from one of the samples:

  • hXXps://eluidess[.]pw/1wicoyptaodnahyylixzo.dat
  • hXXps://aurmidh[.]pw/2enxofeuribfyynudkawa.dat
  • hXXps://bainloth[.]pw/3ehowupotunynvyytciuk.dat
  • hXXps://belegestel[.]pw/4bypuapsopunoobetqype.dat
  • hXXps://calengil[.]pw/5exathyihbyfyotufonek.dat
  • hXXps://cuinmalenel[.]pw/6iwluotucmexyacibhafu.dat

The final item to be extracted from the base config is an optional botnet name. If available it will be stored as an UTF-16 string, else it will be set to “not set”.

C2 Communications

Panda Banker uses HTTP POST requests for its C2 mechanism. An example request looks like:

http_request

An example response looks like:

http_response

(Note: newer versions (2.2.x) of Panda Banker encode the URI and POST data in base64. This will be detailed below.)

Requests

The plaintext data of a request is a JSON object that looks like this:

post_data

This object can be described as:

  • botnet: From the base config
  • id: 32 uppercase hex digits
  • process: The process that Panda Banker is injected into and communicates from
  • system: System time as a UNIX timestamp
  • user: Username
  • version: Panda Banker’s version
  • name: Filename portion of the C2 URL

For encryption, a random 32-byte key and 16-byte IV are generated. The data is then encrypted using AES-256 in CBC mode. If the plaintext needs to be padded, NULL bytes are used.

Next, the random 32-byte AES key is encrypted using RSA PKCS#1 v1.5 and the public key from the base config. After the crypto, the POST data is structured like this:

  • 32-byte SHA-256 hash of the remaining data
  • 256-byte RSA encrypted AES key
  • 16-byte AES IV
  • AES encrypted data

As mentioned above, newer versions (2.2.x) encode the final structure with base64 while older versions do not.

Before moving on to the C2 response, the funny URIs used in the POST request need to be addressed. While they look random, there is a structure behind them that needs to be correct. To generate a Panda Banker URI, follow these steps:

  1. Start with a “/”
  2. Generate a random number (rand_num) between 2 and 10
  3. Append rand_num random alphanumeric characters to the URI
  4. Append a “/”
  5. Get the computer name
  6. Get the InstallDate registry value from HKLM\software\microsoft\windows nt\currentversion
  7. Get the DigitalProductId registry value from HKLM\software\microsoft\windows nt\currentversion
  8. CRC32 the DigitalProductId value
  9. Get an OSVERSIONINFOEX structure using the GetVersionEx Windows API
  10. CRC32 the structure
  11. Pack together the computer name, InstallDate, DigitalProductId CRC32 value, and the OSVERSIONINFOEX CRC32 value together
  12. SHA-256 this chunk of data
  13. Use only the first 16 bytes of the hash
  14. XOR the bytes of the remaining hash with the generated URI like this:
for i in range(len(sysinfo_sha256)):
    sysinfo_sha256_xord.append(chr(ord(sysinfo_sha256[i]) ^ ord(uri[i % rand_num + 1])))

15a. If older version (< 2.2.x), encode the XOR’d data to uppercase hex digits

15b. If newer version (2.2.x), encode the XOR’d data to base64, replace the following characters:

  •  “+” -> “-“
  • “/” -> “_”
  • “=” -> “”

16a. Append the encoded data to the URI

16b. After every append, generate a random number from 0 to 99. If the value is less than 20, append a “/”

An example URI for version 2.2.x is:

/H6YZXXbdc/hvqU2o4/k2Dm/1Fjo/n/m/YLVEg

Here, the red part corresponds to steps 1-4 and the blue part to the output of the rest of the steps.

Responses

Data returned by the C2 is encrypted using a few layers. The first layer of newer versions (2.2.x) is base64 encoded:

layer1

Once decoded (or for older versions), the next layer looks like:

layer2

It is structured like:

  • 32-byte SHA-256 hash of the remaining data
  • 16-byte IV
  • Encrypted data using AES-256 in CBC mode

The same 32-byte key randomly generated and used in the C2 request is used to decrypt the response data. This results in a JSON object:

layer3

Focusing on the “data” key, its value is base64 encoded. Once decoded it returns another binary blob that is structured and can be decrypted like the embedded base config as described above. Once decrypted it returns another JSON object:

layer4

Inside the malware, the integrity of the data at this layer is verified using an embedded RSA key (separate from the base config key) and the “sign” value. This “data” value can be decrypted similarly to the previous layer and it returns a final JSON object: Panda Banker’s configuration:

layer5

Webinjects

There are a number of interesting items in Panda Banker’s config, but one that stands out is “url_webinjects”. Substituting that configured URL into the above C2 request and response protocol results in a different JSON object. The keys of the webinject JSON object look like this:

webinjects1

To make sense of this object, start with the “webinjects” key/value. Its value is base64 encoded and decodes to a structure containing URLs:

webinjects2

A 16-byte header prepends each URL entry. The size of the entry is located at header offset 2 (2 bytes). Once split up into individual entries, the URL’s index (1-based) can be used to retrieve the corresponding webinject data:

webinjects3

This webinject data is made up of a number of pieces. Each piece begins (4 bytes) with its size. Using Zeus’ webinject terminology here is an example Panda Banker webinject in JSON format:

webinjects4

“set_url” is the targeted financial institution. “data_before” and “data_after” control where on the financial institution’s website that Panda Banker should inject code at. “data_inject” contains the malicious (usually obfuscated) code to inject.

In this particular example the malicious code sets up a “grabber” software known as “Tables” that is capable of steal banking credentials, account details, and money:

tables

Conclusion

This post took a closer look at the command and control mechanism of a new banking trojan known as Panda Banker. While it is difficult to assess how active and widespread a new malware will become at the beginning of its lifecycle, Panda Banker is definitely one to keep an eye on. Not only is it built on a proven banking malware platform (Zeus), there are already a number of samples and botnets in the wild. In addition, Panda Banker is actively being developed with 9 distinct versions known to ASERT at the time of this writing–the latest version, 2.2.5, started appearing in the wild (per VirusTotal) on July 7, 2016.

The Mad Max DGA

Jeff Edwards

This post describes a domain generation algorithm (DGA) used by the “Mad Max” malware family. Mad Max is a targeted trojan, and we plan to post a follow-up article that documents our findings regarding the features of the Mad Max malware itself. But for now we will focus on the reversing of its DGA, since […]

The Lizard Brain of LizardStresser

Matthew Bing

LizardStresser is a botnet originally written by the infamous Lizard Squad DDoS group. The source code was released publicly in early 2015, an act that encouraged aspiring DDoS actors to build their own botnets. Arbor Networks’ ASERT group has been tracking LizardStresser activity and observed two disturbing trends: The number of unique LizardStresser command-and-control (C2) […]

Communications of the Bolek Trojan

Dennis Schwarz

A few weeks ago CERT Polska released a short blog post introducing a new malware family now known as Bolek. PhishMe and Dr.Web have since added some additional insight into the family. Browsing through a memory dump of the malware, a Webinjects section sticks out. Webinjects usually imply banking malware, so it seems Bolek picks […]

New Poison Ivy Activity Targeting Myanmar, Asian Countries

The infamous Remote Access Trojan (RAT) Poison Ivy (hereafter referred to as PIVY) has resurfaced recently, and exhibits some new behaviors. PIVY has been observed targeting a number of Asian countries for various purposes over the past year. Palo Alto Networks’ Unit 42 recently blogged about a new Poison Ivy variant targeting Hong Kong activists […]

The Four Element Sword Engagement

Curt Wilson

Ongoing APT activity against Tibetans, Hong Kong and Taiwanese interests In “The Four Element Sword Engagement (Full Report)”, Arbor ASERT reveals recent ongoing APT activity likely associated with long-running threat campaigns against Tibetans, Hong Kong, Taiwanese interests and human rights workers. We presume the existence of associated malcode, dubbed the Four Element Sword Builder, which […]

Alpha Testing the AlphaLeon HTTP Bot

Dennis Schwarz

ASERT was initially alerted about an emerging threat called AlphaLeon by Deep & Dark Web intelligence provider Flashpoint in August 2015. It caught and kept our interest because it sounded like it could be a new “banker” malware family. While it took some time to find samples of the malware in the wild, this post […]

Estimating the Revenue of a Russian DDoS Booter

Dennis Schwarz

At the end of 2014, ASERT presented research where we mapped some DDoS booter advertisements on Russian language forums to their behind-the-scenes DDoS botnet infrastructures. For this post, we will follow up on that research a bit by looking at another one of these mappings and trying to estimate the revenue generated by the DDoS […]

Dumping Core: Analytical Findings on Trojan.Corebot

ASERT team

Download the full report here. The Corebot banking trojan was initially discovered and documented last year by researchers at Security Intelligence. Since then, it has evolved rapidly and, in terms of capabilities such as browser-based web injections, it is now similar to the dominant banking malware such as Zeus, Neverquest, and Dyreza although its actual impact to date is […]

The Big Bong Theory: Conjectures on a Korean Banking Trojan

ASERT team

Download the full report here. ASERT has been analyzing samples of a banking trojan targeting South Korean financial institutions. We call the banker “Big Bong” and provide, in this threat intelligence report, an in-depth behavioral analysis of the malware from builder to bot and from installation to exfiltration including obfuscation techniques, certificate use, and VPN-based […]