Peeking at Pkybot

September 22, 2015 Dennis Schwarz

For the past few months ASERT has been keeping an eye on a relatively new banking malware (“banker”) known as “Pkybot”. It is also being classified as a variant of “Bublik”, but the former is much more descriptive of the malware.

This post will take a peek at some of the bits and pieces of Pkybot and the campaign using it. The visibility provided can help organizations better understand, detect, and protect against this current threat.

Sample

One of the recent samples analyzed by ASERT has the following hashes:

MD5: 9028d9b64a226b750129b41fbc43ed5e

SHA256: 38eb7625caf209ca2eff3fa46b8528827b7289f1

At the time of this writing it has a VirusTotal detection ratio of 16/57 with just about all the detections being generic in nature. One positive for reverse engineers though is that this sample comes unpacked.

Pkybot

While there’s been some research into the malware already [1] [2], a review and fleshing out never hurts.

Encrypted Bits

Pkybot contains a number of interesting items that are encrypted with the XTEA encryption algorithm. The key used is generated at runtime from a hardcoded seed value (DWORD):

key_gen

It can also be generated using this Python code snippet. Along with the generated XTEA key, this IDA script can be used to decrypt:

  • Names of the Windows functions resolved/used at runtime
  • Various text strings
  • Configuration file

Executable Configuration File

Once decrypted, the configuration is a basic XML-like file that consists of command and control (C2) URLs:

exe_config

Command and Control – PKEY

The first C2 communication and the namesake of the malware is the “PKEY” request. It is an HTTP POST that looks like:

pkey_req

“PKEY” is short for RSA public key as that is what the C2 server returns:

pkey_resp

Besides the one shown in the above screenshot, the only other key that ASERT has seen is:

—–BEGIN PUBLIC KEY—–

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3CyhCm5olOqqYe5zDrdLzjoSS

g9Jv1pDObeN63sNFe3sXwyCCJCqzBtlGIAEP2VOgVLqdABsHjPV+ChHUGK9IMqyU

98Dw6Y5JLnrNssa9W1JDqdetNqNP7r5rt+PyzktcPGFrR5K8XWB4uJWXpwXKhFVy

iOr1XzfrEVS47mEE/QIDAQAB

—–END PUBLIC KEY—–

Command and Control – Commands

C2 commands are via HTTP POST requests with encrypted POST data:

c2_req

Command data can be separated into a couple of pieces. The first is a query string consisting of five name/value pairs. Each of the five names consists of 10 to 29 random letters and their values are:

  • Bot ID (based on MachineGuid registry value)
  • Command number (see below)
  • A time difference (based on QueryPerformanceCounter and QueryPerformanceFrequency API calls)
  • Filename (mixture of random letters and hardcoded words)
  • System information (see below)

Command numbers that have been identified are:

  • 1 – Return network configuration file (see below)
  • 2 – Return webinjects (see below)
  • 5 – Return updated 32-bit Pkybot executable
  • 6 – Return updated 64-bit Pkybot executable
  • 8 – Return 32-bit DLL (see below)
  • 9 – Return 64-bit DLL
  • 10 – Return 32-bit EXE (see below)
  • 11 – Return same as command 10

“System information” is a “\r\n” separated text file consisting of the infected machine’s Windows version and installed software. A partial example is:

Microsoft Windows XP Professional Service Pack 3 (build 2600)

Adobe AIR

Adobe Flash Player 10 Plugin

Acrobat.com

FileZilla Client 3.9.0

Google Chrome

Windows Internet Explorer 8

Update for Windows XP (KB2467659)

The text file is gzip compressed and then base64 encoded.

Putting everything together, an example plain text query string looks like this:

query_str

After the query string is generated, two random 16-byte XTEA keys are created. The first is used for encrypting the query string and the second is used to decrypt the response from the C2 server. These two keys themselves are encrypted with RSA (PKCS#1 v1.5) using the public key previously received from the C2. Finally, the two encrypted chunks are concatenated together into the final POST data (where yellow is RSA encrypted and green is XTEA encrypted):

enc_post_data

Command responses from the C2 are XTEA encrypted (using the randomly generated decryption key sent in the request) and are Zlib compressed as well.

Command 1 – Network Configuration File

The network configuration file is an extended version of the executable configuration file:

net_config

It tends to include additional C2 URLs and options for Pkybot’s man-in-the-browser (MitB) functionality.

Command 8/9 – Man-in-the-Browser DLL

Most of Pkybot’s MitB functionality is implemented in the DLL file received in response to commands 8 and 9. This paper will leave a deep dive of the DLL to future research, but in general it uses process injection and function hooking to implement the functionality.

An example DLL has the following hashes:

MD5: cb3d9850f7864489750c25b952d1bc25

SHA256: 9c9aaabb60ca27324da0cdfdd9715b6d0c9c6941217411ef5bf20930d0eadab0

At the time of writing, VirusTotal has a 4/56 detection ratio for the DLL.

Command 2 – Webinjects

Command 2 returns the other component used by the MitB implementation: webinjects. Pkybot uses Zeus’ webinject format consisting of set_url, data_before, data_inject, and data_after markers. An example is:

example_webinject

This example adds a basic JavaScript redirect to the targeted page. Within the browser the source code of the targeted site looks like this before injection:

before_inject

And like this after injection:

after_inject

Command 10/11 – 32-bit EXE

Commands 10 and 11 return the same 32-bit EXE file. An example has the following hashes:

MD5: 5759b592fba82f44bae0edfa862bf77b

SHA256: 864dff5cc930c259e34fd04840a5115f61236e6affbb6fed3af49c78e0aa1460

An analysis of the executable was left for future research, but it does have a low VirusTotal detection ratio (2/56 at the time of write) [8] and an interesting PDB string:

E:\WORK\Core\EXPLOITS\ExploitPack\Release\ExploitPack.pdb

Campaign

Using the configuration files extracted from Pkybot executeables and C2 servers allow for convenient grouping of C2 host data. The following is a rough timeline of when particular C2 groupings were first seen in ASERT’s malware zoo:

  • June 29
    • mukosoma.com
    • boblaktto.com
    • feredac.com
  • July 1
    • pallodare.com
    • potopland.com
    • koplodaro.com
  • July 2
    • bolobranca.com
    • nanoputanas.com
    • pannogen.com
  • July 6
    • manafasia.com
    • noisymemo.org
    • garbux.com
  • July 9
    • giga-flock.com
    • megakatana.com
    • monogera.com
  • July 11
    • fergerama.com
    • hirobakan.com
    • golokird.com
  • July 13a
    • bolobranca.com
    • fedorena.com
    • neyetta.com
    • votublist.com
  • July 13b
    • nanoputanas.com
    • bolobranca.com
    • fedorena.com
    • neyetta.com
    • votublist.com
  • July 16
    • monogera.com
    • claus-management.com
    • pannogen.com
  • July 20
    • fergerama.com
    • hirobakan.com
  • August 9
    • nuratrben.com
    • liopnret.com
    • superzhopper.com
    • xezikalanre.com
    • fanera-distribution.com
    • opilki-limited.com
    • duteraneh.com
    • becadogale.com
    • pannogen.com

At the time of this writing the group starting on August 9 is the one that’s currently active in the wild.

Based on data from ASERT’s malware zoo and VirusTotal’s passive DNS, the following is a grouping of the IPs used by the above 30 unique C2 domains (see Appendix 1 for text based indicators):

campaign_ips

While we have seen 32 unique IPs, there has not been a lot of domain overlap. Per the above two data sources, 12 of the domains have never resolved. Grouping the C2 domains by Whois data, specifically registration email address, is a bit more illustrative:

campaign_whois

Six domains (two of the clusters) are hidden behind privacy guard. The smallest cluster (two domains) is registered to:

joseph@cuvox.de

The largest cluster (17 domains) is registered to:

mant@teleworm.us

Finally, the last cluster (with five domains) isn’t registered at all. These five domains are particularly interesting because they are part of the most recent configuration group (as noted above).

Sinkhole

Taking advantage of this opportunity, ASERT registered one of the domains and sat up a sinkhole from August 11 to August 24. Along with the usual caveats of sinkhole data, it’s good to note that while our sinkhole was active, it was in contention with a live, malicious C2 server. This means the infection data is most likely an under estimate. During the roughly two-week period, the sinkhole received connections from 1879 unique IPs. Based on hostname resolution, the top-5 TLDs were:

tld_graph

Charting the IPs based on geo-IP got a world map that looked like:

geoip

Webinjects

Similarly to the C2 groupings above, a rough timeline of Pkybot’s webinject targets (TLD-wise) can be organized:

  • June 29 (44 total)
    • .gr – 1 bank, 18 webinjects
    • .co.uk – 4 banks, 23 webinjects
    • – *booking* , *air.com* , *amazon*
  • June 30 (49 total)
    • .gr – 1 bank, 18 webinjects
    • .co.uk – 4 banks, 23 webinjects
    • – *booking* , *air.com* , *amazon*
    • .es – 3 banks, 5 webinjects
  • July 2 (50 total)
    • .gr – 1 bank, 18 webinjects
    • .co.uk – 4 banks, 23 webinjects
    • – *booking* , *air.com* , *amazon*
    • .es – 4 banks, 6 webinjects
  • July 9 (13 total)
    • – *booking* , *air.com* , *amazon* , *travel* , *checkout* , *payment*, *paypal*
    • .es – 4 banks, 6 webinjects
  • July 16 ( total)
    • .es – 4 banks, 6 webinjects
  • July 21 ( 5 total)
    • .es – 3 banks, 5 webinjects
  • August 8 (6 total)
    • .es – 3 banks, 5 webinjects
    • – * (everything)
  • August 13 (5 total)
    • .es – 3 banks, 5 webinjects

The target focus has been on banks in Greece, United Kingdom, and Spain. An interesting observation is that the webinjects targeting Greek banks where removed during a peak in the Greek financial crisis—it seems that the threat actor was following current events. At the time of this writing, the focus is on three banks in Spain. This targeting lines up nicely with the sinkhole infection data where “.es” is second in TLD infections and there being a nice cluster of geo-IP pins over Spain.

Conclusion

This post has taken a peek at a relatively new banking malware known as Pkybot. The focus has been on dissecting its command and control protocol, categorizing its command and control domains, and analyzing its webinjects. At the time of this writing and based on webinject targeting and sinkhole infection data, the Pkybot campaign is relatively small and targeted. It is currently unclear whether this threat will expand and how, but the visibility provided here should help organizations better understand, detect, and protect against this threat.

Appendix 1 – C2 IPs

5.254.113.27

31.24.29.50

37.0.125.104

46.151.54.105

78.24.219.6

79.174.64.79

85.31.101.123

85.31.101.233

88.201.248.115

91.215.138.193

91.226.93.36

91.226.93.59

94.229.22.36

94.229.22.39

94.229.22.40

94.229.22.42

95.172.146.196

108.61.190.85

108.61.198.47

109.227.126.136

174.128.228.100

174.128.228.101

174.128.228.102

185.105.32.99

185.14.30.73

185.26.112.146

185.26.115.237

185.91.175.131

193.36.35.90

195.2.77.107

195.211.153.58

216.170.114.123

Read more...

Previous Article
Peeking at Pkybot
Peeking at Pkybot

For the past few months ASERT has been keeping an eye on a relatively new...

Next Article
Peeking at Pkybot
Peeking at Pkybot

For the past few months ASERT has been keeping an eye on a relatively new banking malware (“banker”) known ...