Some samples of this new version, as for the previous release, are debug releases. We could therefore identify the following debug strings:

d:\work\scontroller(2.0) (....)\shellcode\shellcode\

We could link all these new PlugX versions to the following internal version numbers:


The only sample with version 20130524 is the one with the scontroller(2.0) debug string. We’ll see later that this is an intermediate version between the most evolved “PlugX v1” samples and the new “PlugX v2” ones. The compilation dates range from July 2013 to December 2013.

As for the previous PlugX version, there is no direct relation between the debug strings and the internal versions (versions with debug strings 3.0 and 4.0 are the most advanced ones, but still have internal version number 20130810).

Encryption algorithm

The new PlugX uses a new, custom, cipher algorithm. While the previous one was a slightly modified version of the one used in Destory, this one has nothing in common with them:


Here is the basic implementation in Python:

while i<len(data):
      v1 = (((v1 << 7) - (v1 >> 3)) + i + 0x713a8fc1) & 0xffffffff
      v2 = ((v1 >> 24)&0xff) ^ ((v1 >> 16)&0xff) ^ ((v1 >> 8)&0xff) ^ (v1&0xff)
      out = out+chr(ord(data[i])^v2)
      i = i+1

This algorithm is used for configuration encryption, network communications encryption as well as for strings encryption, which is a new feature to slow down reverse engineering.

Communication protocols

Starting from scontroller(2.0) version, the ICMP protocol has been added as a method to join the C&C. The data is transmitted as a payload of Echo reply (ICMP Type 0) packets.

The HTTP protocol has also evolved. Data is transmitted in a POST request matching the following pattern:

POST /%p%p%p

where the %p are random hexadecimal dwords. The following quadruples of headers are used in the request:

HHV1 / HHV2 / HHV3 / HHV4
LZ-ID / LZ-Ver / LZ-Compress / LZ-Size
CC1 / CC2 / CC3 / CC4
ASH-1.0 / ASH-1.1 / ASH-1.2 / ASH-1.3
X-Session / X-Status / X-Size / X-Sn

The latest version, identified as scontroller(4.0), uses a new HTTP protocol. The request is no longer a POST but a GET, and data is transmitted base64 encoded in a “Cookie” header.

new http proto m



Once the base64 is decoded, we have a ciphered buffer which encryption key is the first dword, and ciphered data is the remaining.

This same sample also has a brand new module, XSoDNS.cpp, allowing the RAT to contact its C&C over DNS. The data is also base64 encoded, and sent as a subdomain of the C&C in the DNS segment (C&C has been faked as “” in the following screenshot):

dns proto m


Firefox proxy stealing

The version identified as scontroller(3.0) has a new module, identified as XFirefoxProxy.cpp in the debug strings.

This module parses the prefs.js file to grab information about the configured proxy servers.


The configuration file has a size of 0x2540 bytes, except for the scontroller(2.0) version (which has a size of 0x1d18 bytes, as for the latest “v1” samples). The growth of the configuration is due to new features in the RAT.

More process injection

The new version can inject itself in up to 4 different processes. The full path of the processes are specified in the configuration.


The RAT can be configured to take screen captures at regular intervals, and store them in a local folder, for later retrieval. The configuration parameters are:

  • Local storage path
  • Capture quality
  • Captures interval
  • # of days to keep the screenshots

Previously unused strings

The previously unused strings are now part of new features, and a third one has been added:

  • Online pass: a password is defined, and checked during the initial handshake with the C&C. If the password sent by the C&C is different than the one defined in the configuration, the RAT stops the connection. This can be used when a single C&C is used to receive connections from many infected systems. If a different password is used for different infected companies, the bot herder can filter the connections to the C&C to match a specific company at one time.
  • Memo: a free string sent to the C&C with the host information. This might be used to identifiy a specific sample of the malware.
  • Mutex

Volatility Plugin

Harlan Carvey regretted that our previous post about PlugX did not give more information for IR investigators to identify a PlugX infection, especially about the configuration parsing.

We thus decided to release our Volatility plugin to identify and parse PlugX configuration in a memory dump. The plugin works for all PlugX variants we identified so far, with various configuration lengths.

$ python plugxconfig -f mem.dmp
Volatility Foundation Volatility Framework 2.3.1
Process: svchost.exe (1864)

PlugX Config (0x2540 bytes):
	Flags: True True True True True True True True True True True
	Timer 1: 10 secs
	Timer 2: 0 secs
	C&C Address: (TCP / HTTP)
	C&C Address: (UDP / ICMP)
	C&C Address: (TCP / HTTP / UDP / ICMP)
	C&C Address: (UDP / ICMP)
	Persistence Type: Service + Run Key
	Install Dir: %AUTO%\RasTls
	Service Name: RasTls
	Service Disp: RasTls
	Service Desc: Symantec 802.1x Supplicant 
	Registry hive: 80000001
	Registry key: Software\Microsoft\Windows\CurrentVersion\Run
	Registry value: Supplicant
	Injection: True
	Injection process: %windir%\system32\svchost.exe
	Online Pass: TEST
	Memo: nsc
	Mutex: My_Name
	Screenshots: False
	Screenshots params: 10 sec / Zoom 100 / 16 bits / Quality 50 / Keep 3 days
	Screenshots path: %AUTO%\screen

The plugin can be found on our bitbucket repository. Feel free to give us your feedback and/or report any bug!