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