Wednesday 24 June 2015

Some Notes on Identifying VB.Net Compiled Assemblies

I've been looking at .NET based keyloggers/infostealers lately as I've seen an increase in samples being delivered via phishing emails. One thing that I've noticed was that a lot of the samples shared similar functionality, looked to directly copy core functions or were simply re-factored versions being passed as 'new' keyloggers.

Looking at some analysis's online though would describe samples I would be tracking as VisualBasic as C# and vice versa. This was confusing with samples I was tracking as being copied from another variant as I expected them be the same source language.

I started looking at how VisualBasic and C# are compiled and if you could determine the source language of a .NET assembly. The following examples are simple 'Hello World' applications written in C# and VisualBasic.

With the exception of the string content we can see that the IL instruction set is identical in both the C# and VisualBasic assemblies.

If we expand this to include all of the sample assemblies instructions we do see a difference within the exception clause. In the VisualBasic IL there are two additional instructions that have been added.

  • Dup - (Duplicate the value on the top of the stack.)
  • Call SetProjectError

The setProjectError method is described as:

This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.The Visual Basic compiler uses this helper method to capture exceptions in the Err object.

Looking for information on the setProjectError method I came across a post on the microsoft.public.dotnet.languages.vb list where Niklas from the complier team replied "The extra two calls are there to support the 'On Error' language feature which was retained to make it easier to upgrade from VB6 to VB.NET..."

This gives an indicator when looking at IL if it was generated using the VisualBasic compiler (vbc.exe). Within the catch clause the compiler will emit setProjectError and depending on the logic ClearProjectError. We don't see the second call in the example as the exception is thrown.

To test this I decompiled the VisualBasic compiled application and exported the IL as C#. Looking at the generated C# code there is the call to SetProjectError and a reference to Microsoft.VisualBasic.CompilerServices. If the source code was generated from IL compiled using the C# compiler, we would see 'throw exception;' with no reference to the SetProjectData method.

Another potential indicator that can be used to identify a VisualBasic compiled assembly is the inclusion of the class StandardModuleAttribute which is documented as:

This class provides attributes that are applied to the standard module construct when it is emitted to Intermediate Language (IL). It is not intended to be called directly from your code.

VB.NET modules identical to a class with only shared members. When looking at emitted IL the module is compiled as a sealed class and that there is an additional reference to StandardModuleAttribute.

Generally determining the source language isn't needed when examining .NET malware as the assembly will have identical functionality. But it can be helpful when tracking evolution or variants of malware samples. The VisualBasic compiler (vbc.exe) will emit a number of instructions which are specific to VisualBasic compiled assemblies.

There are a number of other additional attributes which are generally specific to VisualBasic assemblies that can also be used as indicators such as the use of the My Feature and a number of other classes referenced within the CompilerServices Namespace.

Although these are specific to VisualBasic, C# applications could still reference functionality within VisualBasic namespaces. Obfuscation may also cloud the inclusion of these and isn't something I've looked into, but as they are references to the framework they should still be evident in samples. 



Wednesday 3 June 2015

A Look at Golroted/Hawkeye Keylogger

W32.Golroted/MSIL:Golroted/Hawkeye malware is a .Net keylogger which steals information and credentials from compromised systems. From the samples I've analyzed the malware can exfiltrate data using HTTP, FTP or SMTP. A number of AV vendors detect this threat under the definitions W32.Golroted or MSIL:Golroted.

Hawkeye is a version of the keylogger available on a 'subscription' base for $35/year, with cracked versions also available online. Most of the samples I've seen are all related with some minor variance in functionality which seem to be different versions or customized variants being used by attackers.

Hawkeye Products

Delivery and Infection

The malware is spread via phishing emails or infected USB drives. A number of the samples I've seen have used an attached Word document to download and execute the malicious payload.

The malware is contained within a MSIL packed executable and will launch an additional process of itself before unpacking and injecting into the launched process.  Using the volatility plugin malfind we can quickly find the the injected process and dump it for further analysis.

USB Worm

Once the malware is running on the compromised system and if the spreader option is set, it will periodically enumerate all of the connected drives. When a drive is detected of the type DriveType.Removable an Autorun.inf file is created and the malware is copied to the root of the drive as the file Sys.exe.

The files are then set with the attributes (Hidden, System & ReadOnly). The malware doesn't check if the removable device has already been infected, so the process will continue to write the above files until the devices is removed.


If the option 'startup' is set the malware will check if the file %appdata%\windowsupdate.exe exists. If it doesn't exist the malware will copy itself to the location and a new Run key value 'Windows Update' is created with the string %appdata%\windowsupdate.exe.

The malware will continue to monitor for the existence of the windowsupdate.exe file and if it detects the file doesn't exist, it will be recreated and the registry entry will be re-added. It will also write data to a number of text files on the infected system when it is started. The timestamps from these files can be used as an indicator for incident responders of when the malware was first and last executed.
  • %temp%\sysinfo.txt - Path to the malware
  • %appdata%\pid.txt       - PID of the malicious process
  • %appdata%\pidloc.txt  - Path to the malware

There are also a number of options that an attacker can set to make it harder for a user to search for the issue. An attacker can ensure that the following processes are killed if they are started.

  • taskmgr
  • cmd
  • msconfig
  • regedit
Beyond this simple functionality there isn't any additional anti-debugging or analysis functionality.


The malware includes a number of different methods to steal information from infected systems. From my analysis the malware targets the following: 
  • Embedded Credentials in Browsers
  • Embedded Credentials in Email Clients 
  • Bitcoin 
  • Gaming
    • Steam Credentials (forced logout/key logger)
    • Minecraft
  • Clipboard content 
  • Keylogging 

Credential Stealers 

The malware embeds two executable files as resources which are used to steal credentials from installed web browsers and e-mail clients.

[mailpv] is an embeded tool called Email Password Dump available from the website

[WebBrowserPassView] is a similar tool called Browser Password Dump also available from the website

To hide running these processes the malware will launch the process 'vbc.exe -f holdermail.exe' Looking at the available command line options for the VB compiler shows that -f is an invalid argument, so we  know something else is going on. 

Analyzing the decompiled code used to launch the vbc.exe process shows that it is injecting the embedded resources in the vbc.exe process to hide running the password recovery tools.  The following execution flow is used to inject and run the embedded tools.

1) Call CreateProcess() with the CREATE_SUSPENDED flag to launch vbc.exe in a suspended state.

2) Call NtUnmapViewOfSection() to unmap the virtual address space used by the launched process.

3) Call VirtualAllocEx() to re-allocate the memory in the launched processes address space.

4) Call WriteProcessMemory() to write the embedded binary into the process address space.

5) Call SetThreadContext() and ResumeThread() to execute the injected executable. 

Looking at the Browser and Email password tools shows that the -f switch is used to dump output to an output file. So we can see that passing '-f holdermail.txt' is actually for the injected processes as both tools support the -f argument to dump output to the passed file.

Each time the malware is launched it will spawn 2 vbc.exe processes, one to launch the Browser Password Dump and one to launch the Email Password Dump tools. Once the tool finishes running the malware will read the contents of the holdermail.txt file and delete it. 


If the setting logger is enabled the malware will run a thread where it will send captured data to the attacker at a scheduled interval. The interval is controlled by the timerstring setting and in the analyzed samples this looks to be set to 10 minutes.  

The following configuration options control what information is sent via sendlogs()
  • screeny - Include a screenshot of the desktop
  • clip      -  Include clipboard content
  • logger  -  Include captured key log data.


To capture keyboard events the malware calls SetWindowsHookEx to register a hook of type WH_KEYBOARD_LL (13) to monitor low level keyboard input events. 

After each call to Send logs captured keyboard input is cleared.

Clipboard Stealer 

The malware will register itself as a clipboard viewer using the SetClipboardViewer() function and listen for change events. When a change event occurs the malware calls the Clipboard.GetText() to retrieve any data in the Text or UnicodeText formats. If no text data exists the call will return String.Empty. The data is then added to the clip log which includes a timestamp appended to the entry.

[---- <TimeStamp> ----]
<Captured Data>

Note: This indicates that the malware will only retrieve text based data from the clipboard and not other objects such as images.

Screen Capture

If the communication method is set to FTP or SMTP the malware can be configured to take a screen shot of the infected systems desktop. The sceen shot occurs at the configured interval (10 minutes) for sending the log data. 

Captured images are stored in %temp%\screens\ directory and will have the following name. 

  • FTP: screenshot[counter]_[Computer.Name].jpeg
  • SMTP: screenshot[counter].jpeg.

The counter is initialized to 1 and is controlled by the screenynumber configuration option. There isn't persistent storage for the current incremented count value, so each time the malware is launched it will be reinitialized to the value defined in screenynumber and overwrite existing files. 


The malware can be configured to send captured data via FTP, SMTP or HTTP. The settings for these are encrypted using RijndaelManaged class and stored as Base64 encoded strings within the executable.

I've put together a quick script in Powershell that can be used to decrypt the configuration settings found in the unpacked malware. 

Although values for more than one of these methods could be set, the malware will use the following priority for the communication mechanism FTP, SMTP, HTTP.

If configured to use HTTP (PHP) the request will have the querystring of: log.php?username={username}&name={FileName}&data{Data}.

  • Username - Value within the encryptedphplink option
  • Filename  - Generated value includes Header, ComputerName & HWID 
  • Data         - Key log and clipboard content

The malware also has options to download files or interact with websites. Each of these settings takes a double pipe "||" separated list of urls.

  • downloadfiles - Download files and store them in %temp%\DFile_{num}.exe, where num is initialized as 0 and is incremented depending on the number of files to download.
  • websitevisitor - Loop through the list of websites calling Process.Start("http://{url") on each passed URL.
  • websiteblocker - For each of the passed strings and an entry to the hosts file mapping the host to


I haven't looked at all of the options that can be used by an attacker to customize the malware. The below list summarizes the options and should provide an overview of the available features and additional functionality.

encryptedemailstring encrypted string SMTP User
encryptedpassstring encrypted string Email server pass
encryptedsmtpstring encrypted string SMTP Server
portstring 587 Port used for email
timerstring 600000 Value used for sleep value 
encryptedftphost encrypted string FTP Host
encryptedftpuser Encrypted String FTP User
encryptedftppass Encrypted String FTP Password
encryptedphplink Encrypted String PHP Link to use
useemail true/false Use SMTP to send data
useftp true/false Use FTP to send data
usephp true/false
Use HTTP to send data
delaytime 0 Time in seconds to delay execution after launch.
clearie true/false Clear IE Cookies
downloadfiles url list (separator ||) Download and execute a file. The file is stored as %temp%\DFile_0.exe
websitevisitor url list (separator ||) Navigate the configured website
websiteblocker url list (separator ||) For each site add an entry to the hosts file directing it to
notify true/false Notify that the system is infected using the configured install
DisableSSL true/false Disable SSL for SMTP connection.
fakerror true/false Display a fake Error message when the malware is started.
fakemgrstring string String to display in the MessageBox.
fakemgrtitle string Title of the MessageBox.
fakeMSGholder MessageBoxIcon Specifies which icon to display in the MessageBox.
startup true/false Add entry to HKCU Run key
screeny true/false Controls if the malware takes a screenshot when it sends log data.
clip true/false Controls if the malware steals clipboard data
TaskManager true/false Controls if the malware kills taskmgr processes.
logger true/false Enable/disable keylogger and sendlogs
stealers true/false Enable/disable credential stealers
melt true/false Enable/disable if the malware validates it is running from the defined path (%appdata%).
reg true/false Enable/disable if the malware kills regedit processes.
cmd true/false Enable/disable if the malware kills cmd.exe processes.
misconfig true/false Enable/disable if the malware kills mconfig processes.
spreaders true/false Enable/disable infecting USB devices.
steam true/false Enable/disable if the malware kills existing steam processes and deletes saved configuration data.
screenynumber 1 Starting number to append to screenshots
minecraftt 120000 Timer to use for minecraft credential stealer.
pinsst 140000 Timer to use for jagex game data.
bitcoinst 180000 Timer to use for checking for wallet.dat file.
meltlocation %appdata%\WindowsUpdate.exe Location of persistence file. Although this is defined here, there are a number of places the value is hard-coded.

Incident Response

The malware leaves a number of host indicators incident responders can use to help identify or trace an infection.  
  • Existence of %temp%\screens directory with screenshots of the compromised system
  • Existence of the following text files:
    • %temp%\sysinfo.txt
    • %appdata%\pid.txt
    • %appdata%\pidlock.txt  
  • Entry in the HKCU Run Key for 'Windows Update' with the string data %appdata%\windowsupdate.exe 
  • Existence of 'Windows Update.exe' and windowsupdate.exe in %appdata%
  • Hidden Sys.exe file at the root of removable drives
Beaconing network communications via SMTP, FTP or HTTP will occur at a regular interval. The samples I've looked at were configured to use a 10 or 20 minute sleep. If the malware is configured to use HTTP communications it will be landing on a .php page with the format log.php?username={username}&name={FileName}&data{Key logger and clipboard data}.

Yara Rules

The following yara rules can be used to help identify samples of the malware.




  • c30ca528c0f22db5bb4aacb236cdb18c
  • 63ca2f8b1e580d07dddfb043e6bb805d
  • 47e241e3c44587889fc00cba210f4372
  • 8a5422c7d2514d7ad0ed912593547009
  • f51440eeac9dc43c37f75cd9d20b9cf4
  • 7a7e8863fce822388083e7c22944423a

Sunday 22 March 2015

AlienSpy Java Rat Overview

AlienSpy is a cross platform Java RAT with support for Windows, Linux and Mac systems. 
The samples I was able to analyze used a demo version of the Allatori Java Obfuscator (v5.3) which can be seen in the obfuscated method naming and Splash page shown when the malware is launched.

Allatori Name Obfuscation

Allatori Splash Screen

I won't dive into the Allatori obfuscation methods or the container in detail other than to understand how the malicious jar is encapsulated within the package.  The container has a simple structure containing two resource files (config.ini & password.ini) and four class files.

Jar Overview
Once executed the container follows a simple path to decrypt and execute the payload.
  • Init LoadStub Thread
  • Load config.ini contents
  • Spawn DecryptStub Thread
  • Create key -- Load password.ini contents and append static_key (set in LoadPassword.class)
  • Decrypt config.ini using created key 
  • Spawn LoadStubDecrypted
  • Initialize JarInputStream object from decoded config data
  • Spawn thread with decoded Jar

Unpacking the Payload

Analyzing the decryption method in the DecryptStub class shows the encryption has changed from previous versions. The payload stored in the config.ini file is encrypted using RC4 and the decrypt key is composed of the sha256 hash of a dynamic key stored in the password.ini file and a static key defined in the LoadPassword.class. 

Looking at the de-obfuscated strings in the LoadPassword class shows the static key as ALSKEOPQLFKJDUSIKSJAUIE. 

Appending Static Key
The sha256 hash is then created from the combined dynamic and static key.

key = sha256(dynamic_key + static_key)

For this sample the key is calculated using the following:


To extract the properties (config.xml) or the entire payload I've put  together a script to decode the latest version of the AlienSpy rat.

Once the rat is decoded we can decompile it and take a look at the layout and functionality. The decoded AlienSpy RAT has a simple layout containing a two resources config.xml & keystore.test and a collection of classes within three packages. 


When the malware is launched it checks the INSTALL property which is populated from the config.xml resource. If the property is set to True the installation method is triggered using the following properties to generate the directory and file on the host system. 

  • JAR_FOLDER       - Name of folder to copy malware into 
  • JAR_NAME          - Name of the file
  • JAR_EXTENSION  - Extension of the file
  • JAR_REGISTRY    - Name of persistence setting


On Windows systems the malware is copied to new directory with %appdata% and a new value under the Run key is created to launch the malware. The value name is the string defined within the JAR_REGISTRY config setting and the value is the command line to launch the malware 'java -jar <path-to-jar>'. The jar path and file name is defined by the JAR_ properties described above. 

Depending if the user is a local administrator or not the value is created under the Run key in HKLM or HKCU to either infect the system or only the current user. To check if the user is an administrator the file tem.txt is created within the Windows directory and deleted. If this succeeds the Administrator Property is set to true. 


On a Linux system the jar file is copied to the hidden directory <JAR_FOLDER>  within the user's home directory and renamed to <JAR_NAME>.<JAR_EXTENSION>. The malware then creates a .desktop file within the users autostart directory ~/.config/autostart/<JAR_REGISTRY>.desktop to launch the RAT when the desktop is started.


Like on Linux systems the malware creates a file under a new directory <JAR_FOLDER> in the user's home. It then creates a new job within the user's Library/LaunchAgents directory com.<JAR_REGISTRY>.plist

The generated configuration file has the optional key RunAtLoad set to true; this instructs launchd to run the job once when it is loaded.  

Once the job file is created, it then runs the command "chflags hidden <JAR_FOLDER>" to set the hidden flag and hide the directory from the UI. 

Sandbox Detection

When executed AlienSpy checks if it is running within either a VirtualBox or VMWare environment. If it detects that it is running within a VM the application exits. The detection technique isn't advanced and is done by detecting files installed as part of the VM host guest tools. 

For VirtualBox this is either the file "/etc/init.d/vboxadd" in Linux or the directory "Oracle\Virtualbox Guest Additions" in Windows. If the RAT is running within a Mac environment it returns false. 

VirtualBox Detection

Similarily for VMware  this is the directory "/etc/vmware-tools" in Linux "/Library/Application Support/VMware Tools" in Mac and "VMware\VMware Tools" in Windows.

VMWare Detection


AlienSpy uses SSL Sockets to communicate with the C2 server. The server and port are both defined within the config.xml file. 
  • DNS   - Hostname or IP address
  • PORT - TCP port 
The jar file contains a keystore resource keystore.test which is used to trust the C2 SSL certificate. Using keytool we can look at the contained certificates. 

Note: The password for the keystore is 'storepass' and is defined in utils\AlienSSLSocket.class

When examining the certificate details I was able to trace it back to a how-to post on SSLSockets and creating a keystore. 

The majority of settings for the certificate have just been directly copied from the examples in the article (keystore name, password and certificate properties). 

C2 Subscription

To subscribe to the C2 server the rat first creates and configures the SSL connection then sends 1 then sends the properties describing the host system. At this point the malware is in listening mode waiting for commands from the C2 server.  


Once connected to the C2 server the RAT waits for a command. Commands have a simple syntax of command_id [1..10] and an optional payload for the command. 

1 [0] - Message Type
[1] - Option Type
[2] - Title
[3] - Message
Display Message Box
2 [0] - URL
[1] - Number of times to open the URL
Open the URL the requested number of times. Hardcoded to sleep 2s every iteration.
3 N/A Shutdown
4 N/A Restart
5 N/A Uninstall
6 N/AUpdate Offline
7 URL for update. Update Online
8 [0] - URL for download.
[1] - Extension to append to file.
Download & Execute
9 Plugin Name Run Plugin
10N/AStart Heartbeat

From what I've observed the first command after subscription is generally '10' which instructs the infected host to begin sending a heartbeat every 60 seconds.  

  • Write 1 
  • Write PINGPONG
  • Sleep 60s

The heartbeat will continue running on a separate user thread while the malware waits for the next command from the server.


There are two commands the C2 server can send for updating infected hosts; an online update or an offline update. 

An offline update instructs the client to make another connection to the C2 server. Once the updated rat is downloaded it will call uninstall to remove the existing version then launch the updated one from the temp file. 

An online update includes a URL as the payload which instructs the RAT where to download the updated version from. A GET request is sent to the URL with the hardcoded UserAgent

Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36

The same process seen in the update offline is followed, the new version is downloaded into a temporary file and the client uninstalls the existing version and updates to the newly downloaded version.

Download & Execute

The server can issue the command Id 8 which instructs the client to download and execute the downloaded file. The payload for this command includes the URL to download the file from and the extension to append to the file once it is downloaded. 

Requests are made using the UserAgent: 

Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17

Once the file is downloaded the file is passed to an opener function where it determines how to launch the downloaded file. The opener first checks if the downloaded file ends in '.jar' if it does it will generate a string 'java -jar <downloaded jar>' and execute it. 

If the malware is running on MacOS it will also append the argument -Dapple.awt.UIElement=true

If the file doesn't end in .jar the opener will use the preferred method to open files for the host OS. For Windows systems this is cmd, for Linux this is either /usr/bin/open or /usr/bin/xdg-open and for MacOs this is java.awt.Desktop.getDesktop().open

Open URL

The server can instruct clients to open a URL. The payload to this command contains the URL to open and the number of iterations. The client will then open the URL the requested number of times sleeping for 2 seconds between iterations.  

  • For MacOS it will launch the URL using:  open -a Safari <URL>
  • For Windows it will launch the URL using: cmd.exe /c START iexplore.exe <URL>
  • For Linux it will launch the URL using: /usr/bin/xdg-open <URL>  


Incident Responders looking for systems compromised by AlienSpy can extract host and network indicators from the properties defined in the config.xml file. Additionally systems would also be beaconing to the C2 server every 60 seconds.

AlienSpy is used to deliver other malicious payloads to infected systems. Detecting the presence of AlienSpy should be considered to be only part of the compromise.

If you have any samples, would like to collaborate feel free to reach out to me on twitter @seanmw. I'm interested in looking at how AlienSpy is being used in phishing campaigns to deliver malware.


The samples I used for the post can be found using the hashes below:
  • Sample 1: f3366d437f9461f1486406972f52e7aab47174db 
  • Sample 2: c932064fe6a7dfc96fb2a3ffec2b7f4e5b7e048f