Reverse Engineering Analysis Lab

Overview

Part 1: STRRAT Dropper and STRRAT Deobfuscation

Let’s take a look at a recent sample of the Java-based malware known as STRRAT. We will cover some techniques on how to identify the malware and reverse engineer it. We will start with a malicious JAR file being distributed through email malspam campaigns, and in this instance the file had the name INQUIRY______535262623.jpg.jar

First off we obtain a sample with a particular SHA256 hash:

Starting Host IOC: ec48d708eb393d94b995eb7d0194bded701c456c666c7bb967ced016d9f1eff5

Given this is a Java-based RAT we can start by opening it using JD-GUI, a Java Decompiler.

If we expand out the only class this contains, we immediately begin to see references to its resource section, wscript, and “user.home”. Given these references, and the lack of classes, this is a good indicator that the Java Archive will likely function as a dropper, placing a script with the name “loorqhustq.js” in the users home directory.

Trojan Dropper Decompiled

To understand the script being dropped to “loorqhustq.js”, we can take a look at the resource section by extracting the Java Archive using 7-Zip.

Trojan Dropper Resource Section

At a glance this isn’t too large; however, it does have a Base64 blob which looks to be present and some data manipulation to ensure this can’t easily be decoded. One way to tackle this is to replace references of “eval” (which is essentially telling JavaScript to execute and evaluate what it is being passed, and instead make this “console.log”. By doing this the malicious JavaScript will instead log what it is being presented, rather than processing and evaluating it.

To do this we still need a way to interpret the JavaScript in a safe setting. By opening up Google Chrome and pressing “F12” we can view the console. At this point we can copy in our modified JavaScript and have Chrome interpret it for us.

Modified JavaScript

The end result is a variable being defined containing an object called lmao$$$_. This is an ActiveXObject storing a Base64 encoded string; however, because we ran this inside of a browser and replaced the eval statements, we get an Uncaught ReferenceError. This is expected as we didn’t want the dropper to progress, and only wanted to extract this Base64 string.

Reassembled JavaScript

By copying solely the string into CyberChef, we’re able to begin extracting what will be dropped.

CyberChef Decoded Base64

Examining this decoded string reveals a variable which is being defined as “longText”, before being manipulated to make a valid Base64 string which is once again decoded to disk, this time in the user’s application data directory to a file called r.txt

Decoding Base64 String

Before we look into extracting ‘r.txt’, we can continue to look at what is happening when the dropper triggers. Examining the first part of the dropper, we find it is enumerating if the Java Runtime Environment is present, and where it is, it will attempt to execute the dropped “r.txt” as a Java Archive, if not, it will run a function called “GrabJreFromNet”.

Enumerate JRE

Looking at the function GrabJreFromNet, we can see that it attempts to reach out to hxxp[://]wshsoft[.]company/jre7[.]zip to pull down a version of JRE. This is then saved to a zip file in the user’s application data directory before it is extracted to disk, used to run r.txt, and a run key is setup for persistence to ensure it always runs whenever that user logs on.

Download JRE and Persist

Network IOC: hxxp[://]wshsoft[.]company/jre7[.]zip
Registry Run Key Persistence (Host IOC): HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ntfsmgr

At this point we can go ahead and take the first 4 lines of this second stage dropper, and add an entry to once again log to the console the contents of “longText” which will be decoded to r.txt as a Java Archive and run.

Decond LongText

The output is a “PKZIP” archive, which we can identify through the presence of a MANIFEST.MF as a Java Archive.

Reveal Java Archive - CyberChef

We’re able to download this file to disk and retrieve the new hash of this Java Archive using PowerShell.

get-filehash .\STRRAT.jar
0A6D2526077276F4D0141E9B4D94F373CC1AE9D6437A02887BE96A16E2D864CF

Download JRE and Persist

Host IOC: 0A6D2526077276F4D0141E9B4D94F373CC1AE9D6437A02887BE96A16E2D864CF

By checking the hash against VirusTotal we can see it hasn’t been analysed and shared publicly yet.

VirusTotal Lookup

To help ensure AV vendors are aware of this STRRAT sample, we can submit it to VirusTotal for scanning.

VirusTotal Submission

27/60, not a bad rate of detection, noting this doesn’t represent all detection capabilities by vendors, and just because a vendor doesn’t flag it here, doesn’t mean they won’t detect or prevent it in production.

Opening STRRAT in JD-GUI, we can take a look at the manifest file to find the ‘Main’ class which will be executed when the archive is run.

STRRAT Main Class

By examining the main class we get a lot of obfuscated classes, and references to “StringBuilder” being leveraged which (as far as I know) is one of the underlying reasons this malware was named STRRAT during its initial discovery and reporting. The string ‘STRRAT” is also present once we deobfuscate this sample.

Obfuscated String Class

At this stage deobfuscating the code manually would be a bit of a challenge. Luckily we have java-deobfuscator available to us which can perform a lot of the heavy lifting.

To use this we will first create a yaml file called detect.yml which will be used to detect what obfuscator is in use.

input: C:\Users\User\Desktop\STRRAT\Stage 2\STRRAT.jar
detect: true

From here we can pass this as the configuration to deobfuscator, and find that this looks to be using “Allatori’s Java Obfuscator - String Encryption”.

java -jar deobfuscator.jar --config detect.yml

Detect Obfuscator Used

The irony is that the website providing this tool is calling us a “hacker” for reverse engineering the Java Archive.

Obfuscating Software for Purchase

From here we can create another file set to deobfuscate the Java Archive in question using the first recommended transformer.

input: C:\Users\User\Desktop\STRRAT\Stage 2\STRRAT.jar
output: C:\Users\User\Desktop\STRRAT\Stage 2\STRRAT-Deobfuscated.jar
transformers:
	- com.javadeobfuscator.deobfuscator.transformers.allatori.StringEncryptionTransformer

After executing the transformer in question we’re presented with a number of “decryption methods”, and “encrypted strings” being rectified. In this instance there’s some output errors also, but this isn’t of concern.

java -jar deobfuscator.jar --config config.yml

Deobfuscating STRRAT

At this point we can see a number of Java Archive files being referenced:

Plugin Modules

Of these referenced includes a project “system-hook” which is essentially being used here as a Java-based key-logger.

System Hook

Examining the Main Class further we can now find reference to a pastebin URL being contacted. This gives us some potential C2 infrastructure leveraged by this malware. It should be noted this can be modified by the Pastebin user to point elsewhere.

Adversary Infrastructure

Dynamic Infrastructure (Network IOC): hxxps[://]pastebin[.]com/raw/Jdnx8jdg
Pastebin Actor Account (Network IOC): hxxps[://]pastebin[.]com/u/wshsoft

At the time of writeup this page had been visited 32,736 times, and pointed to the domain pluginserver[.]duckdns[.]org

Current Infrastructure (Network IOC): pluginserver[.]duckdns[.]org

In addition there’s a hardcoded URL mentioned which looks to contact the below:

Network IOC: hxxp[://]str-master[.]pw/strigoi/server/ping[.]php?lid=

Taking a look at the class cbnfdhn.class, we can get a feel for some potential functionality of STRRAT including shutting down an operating system, uploading and downloading files…

STRRAT Features

Enumerating the OS, processes, key-logging, stealing saved credentials.

STRRAT Features

In addition there’s a reference to “crimson_info.txt” which has been publicly reported as a fake ransomware module.

STRRAT Features

Part 2: Extracting and Ddecrypting STRRAT Configuration

To perform more thorough analysis on the deobfuscated STRRAT, we’re going to leverage a tool called ‘Recaf’. This will allow us to decompile Java classes in a more user-friendly way given the malware authors have reused class and method names. Upon decompiling this we’re going to take a look at the primary entry point of the program in the “Main” class.

An easy way to find this class is to search for “void main” because the main class method isn’t intended to return any output. In the below we see a watermark added to the malware to show that “Allatori Obfuscator 7.3 DEMO” was used to obfuscate it. In addition we can see it is checking for the number of arguments provided, and where this isn’t provided it will run the Main.bsgshsbs method (which is returning an object to be created from the ‘dfghrth’ class). Further to this we can see a message of “This PC is not supported” being returned after this if a string isn’t able to be assigned from the output of Main.sdfsldf. To find the right method definition here we can search for “String sdfsldf()” given we know it is returning a string, and here we can see that it is simply looking for the path the running JAR file is running from (likely taken from this StackOverflow post).

STRRAT RE

Examining the object created from the “dfghrth” class reveals this is a file lock being created in the user’s home directory. If there are command-line arguments added this will create a file lock with the name “64578lock.file” in the user’s home directory given this number is passed as a parameter when creating this lock object.

STRRAT RE

Host IOC: 64578lock.file

In the case where no command-line arguments are provided, this will first create an object called “object2” from the Main class method “bsgshsbs”. To make finding these references easier, we’ll begin right clicking them and using “Goto definition”.

STRRAT RE

We can also reveal references to this particular method by instead clicking “Search references”.

STRRAT RE

Examining this method we can see that it looks to be taking in a stream from a file within its resources called ‘config.txt’, Base64 decoding it, and then it passes this and the string “strigoi” to another method, this time within the sabretb class called “dfhttegd”.

STRRAT RE

Within this class and method we can see that STRRAT is performing an AES decryption routine based on the provided AES encrypted stream from config.txt, and a “password” of “strigoi”.

STRRAT RE

Although I’m no crypto expert, in short, the password is being used to derive a secret key via the “password-based key derivation function 2” (PBKDF2), 65536 SHA1 hashing iterations, a key size of 128, using CBC mode, and a salt which is the ‘nonce’ extracted from our AES encrypted string. In this instance the “salt” (nonce) functions as the Initialisation Vector used with the AES Key to decrypt the string.

  • More reading around AES Encryption and Decryption in Java can be found created by baeldung

To decrypt this using CyberChef we would have to first get the salt (nonce) used, derive the PBKDF2 key, and then use this with the appropriate IV to decrypt our content.

STRRAT RE

This is a bit of work, and can quickly get confusing. Because STRRAT is implementing a decryption method, we can go ahead and take the relevant parts of the decryption method to decrypt the config file ourselves. If we copy “sabretb” and “dfhttegd” from “sabretb”, and also “bsgshsbs” from Main, we’ve got the start of a decryption program (noting we will need to import the appropriate libraries in use).

STRRAT RE

In the above we’ve copied the core content in; however, there’s still some issues based on duplicate named variable declarations, classes which aren’t throwing an exception, and an issue based on how it is reading the file input. I’ve gone ahead and rectified this with the end result being a Decrypter which takes 2 arguments, (input file, output file). Note: At present during our analysis there’s some unknown configuration values as we haven’t completely reveresed the malware.

STRRAT RE

The decrypter as it stands so far can be found below:

import java.nio.ByteBuffer;
import java.io.File;
import java.nio.file.StandardOpenOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class STRRATConfigDecrypt {

    public static void main(String[] args) throws Exception {
        System.out.println("###################################################");
        System.out.println("# STRRAT Malware (v.1.4) Decrypter by @CyberRaiju #");
        System.out.println("###################################################");
        if (args.length < 1) {
            System.out.println();
            System.out.println("PEBCAK - Use this with 2 arguments, an input and output file");
            System.out.println("Example:");
            System.out.println(
                    "java -jar STRRATConfigDecrypt.jar \'C:\\Users\\User\\config.txt\' \'C:\\Users\\User\\decrypted_config.txt'");
        } else {
            String inputdirectory = args[0].replace("\\", "\\\\");
            String outputdirectory = args[1].replace("\\", "\\\\");
            File configfile = new File(inputdirectory);
            byte[] config = Files.readAllBytes(configfile.toPath());
            byte[] parsedBytes = Base64.getDecoder().decode(config);
            byte[] decryptedConfig = DecryptAES("strigoi", parsedBytes);
            String string[] = new String(decryptedConfig, StandardCharsets.UTF_8).split("\\|");
            System.out.println("Network IOC: " + string[0]);
            System.out.println("File Lock: " + string[1] + "lock.file");
            System.out.println("Network IOC: " + string[2]);
            System.out.println("Network IOC: " + string[3]);
            System.out.println("Unknown Parameter: " + string[4]);
            System.out.println("Unknown Parameter: " + string[5]);
            System.out.println("Unknown Parameter: " + string[6]);
            System.out.println("Unknown Parameter: " + string[7]);
            System.out.println("Possible License/Campaign ID: " + string[8]);
            Path output = Paths.get(outputdirectory);
            Files.write(output, "# STRRAT Malware (v.1.4) Decrypter by @CyberRaiju #\r\n".getBytes());
            for (String str : string) {
                str = str+"\r\n";
                Files.write(output, str.getBytes(),StandardOpenOption.APPEND);
            }
            
        }
    }

    public static SecretKey SecretKey(String password, byte[] data) throws Exception {
        PBEKeySpec a = new PBEKeySpec(password.toCharArray(), data, 65536, 128);
        byte[] b = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(a).getEncoded();
        return new SecretKeySpec(b, "AES");
    }

    public static byte[] DecryptAES(String password, byte[] bytes) throws Exception {
        ByteBuffer byteBuffer;
        int n;
        byteBuffer = ByteBuffer.wrap(bytes);
        n = byteBuffer.getInt();
        if (n < 12 || n > 16) {
            throw new IllegalArgumentException(
                    "Nonce size is incorrect. Make sure that the incoming data is an AES encrypted file.");
        }
        byte[] object3 = new byte[n];
        byteBuffer.get(object3);
        SecretKey key = SecretKey(password, object3);
        byte[] byArray2 = new byte[byteBuffer.remaining()];
        bytes = byArray2;
        byteBuffer.get(byArray2);
        Cipher crypto = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        IvParameterSpec IVSpec = new IvParameterSpec(object3);
        crypto.init(2, key, IVSpec);
        return crypto.doFinal(bytes);
    }
}

After ensuring the config file has been extracted, by running this using Visual Studio Code and the following command line:

cd 'c:\Users\User\Desktop\STRRAT\Stage 2\STRRAT-Deobfuscated\carLambo\resources\Decrypter\STRRATConfigDecrypt'; & 'c:\Users\User\.vscode\extensions\vscjava.vscode-java-debug-0.31.0\scripts\launcher.bat' 'C:\Program Files\OpenJDK\openjdk-11.0.9_11\bin\java.exe' '-Dfile.encoding=UTF-8' '-cp' 'C:\Users\User\AppData\Roaming\Code\User\workspaceStorage\ed67bcda7ebbfaeaf8f2ea3a04d08723\redhat.java\jdt_ws\STRRATConfigDecrypt_7776d08d\bin' 'STRRATConfigDecrypt' "C:\Users\User\Desktop\STRRAT\Stage 2\STRRAT-Deobfuscated\carLambo\resources\config.txt" "C:\Users\User\Desktop\STRRAT\Stage 2\STRRAT-Deobfuscated\carLambo\resources\decrypted.txt"

We’re presented with a decrypted configuration output which has also been stored in a file called “decrypted.txt”.

STRRAT RE

Network IOC: moregrace[.]duckdns[.]org
Host IOC: 3219lock.file
Network IOC: hxxp[://]jbfrost[.]live/strigoi/server/?hwid=1&lid=m&ht=5
Network IOC: palaintermine[.]duckdns[.]org

Although the config parameters have been extracted, it’s not clear on exactly what they’re used for. By looking back into the method “sdfsldf” in the Main class we can see it is checking arguments provided, and if an argument was provided, it would only use the 3rd configuration parameter from the file (the jbfrost[.]live URL) in a call to “cbnfdhn.sabretb”.

STRRAT RE

In addition to this, the above mentioned method is all about making a GET request to the server and retrieving the response to return as a string.

STRRAT RE

We know that this string is being returned to cbnfdhn.dfhttegd which if we look into is holding a public string that can be referenced from multiple classes, so we know it is being stored for later usage.

STRRAT RE

By viewing references to this, we can see the different methods which either “PUT” a value into this variable, or “GET” the value from the variable.

STRRAT RE

At this point we know that the variable is written to within 5 methods, and read from 5 methods. If we examine where it is being read from by right clicking and selecting “Edit with Assembler”, we can see that all of these methods are creating sockets and using this as the callback address. In addition we can see reference to what appears to be “Reverse Proxy” and “HDRDP” debug/response messages.

STRRAT RE

By performing some OSINT using urlscan.io we find that this URL used to just return ‘pluginserver[.]duckdns[.]org’, which is the same domain we found linked to our pastebin URL.

STRRAT RE

It’s very likely that this domain was being used to fetch plugins for STRRAT. To tie most of this back together we can return to method “sdfsldf” within the Main class and examine more closely what it is doing here.

STRRAT RE

In the above we see it is defining a couple of variables, one for the primary plugins URL which is extracted from the config file, and one which is pointing to the pastebin URL containing the same domain. We then see it is using this to download the appropriate Java Archive files (plugins), before a request is made to a master server which looks to have been registered to take a license ID. In this case the license ID would be “khonsari”.

We can also confirm that after this a file lock is being created in the user home directory by examining the object defined within object9 which in this case is an instance of “dfghrth”.

STRRAT RE

At this stage we can begin to update our decrypter to refine what we’re pulling in from the config file.

STRRAT RE

It should be noted that we’ve inferred this is STRRAT version 1.4 by examining the method “shshnfdn” within “cbnfdhn” which looks to be a check to see if STRRAT has been installed on this host or not.

STRRAT RE

If we move back to examining the main method which will continue to run, we can see that one of the parameters passed as “True” is used to determine if persistence will be setup using a scheduled task called “Skype”, with another being used to determine if the configuration will be passed to a new array. This new array is then used within sstydgn.sdfsldf, where the stringArray3 7th parameter is also set to true.

Host IOC: Scheduled Task - "Skype"

STRRAT RE

If we once again examine references to this, it appears as if these values are also being used to determine if persistence is installed, only this time it is writing to the user’s startup directory.

STRRAT RE

At this stage we have enough information and context to complete our STRRAT configuration decrypter and can compile a Java Archive to extract the configuration from a given config.txt file.

"C:\Program Files\OpenJDK\openjdk-11.0.9_11\bin\java.exe" -jar STRRATConfigDecrypt.jar "C:\Users\User\Desktop\STRRAT\Stage 2\STRRAT-Deobfuscated\carLambo\resources\config.txt" "C:\Users\User\Desktop\STRRAT\Stage 2\STRRAT-Deobfuscated\carLambo\resources\decrypted.txt"

STRRAT RE

The completed STRRAT Config Decrypter has been made available for use here

Part 3: Examining RAT Flow and Functionality

To drill into this a bit more, we need to know what Java classes are going to be most interesting. One way of doing this is to extract the classes and filter based on their size, because a larger class may often be indicative of more code making up more interesting functionality.

STRRAT RE

The easiest way to view this code is to view it in Decompiler view rather than viewing them in the ‘Edit with Assembler’ view we used above.

STRRAT RE

If we’re having issues with using the Decompiler, it can often be useful to revisit previous steps. For example if we’re unable to decompile a class, perhaps we should try to deobfuscate the malware using the second transformer recommended by java-deobfuscator, or we could try a different decompiler within Recaf.

In this instance there doesn’t appear to be any issues, so let’s first look back at the references to our public static string object ‘cbnfdhn.dfhttegd’ which is essentially holding the value “pluginserver[.]duckdns[.]org”. Within the fgfnbnc class we find this is referenced 3 times. In the first instance we see it is the method cbnfdhn.dfhttegd being run rather than the public string being accessed.

STRRAT RE

Because this is a method, we disregard this hit, but make note that whenever the method fgfnbnc.dfhttegd is run, it will attempt to run the method cbnfdhn.dfhttegd. Looking at the next method we can see the reference to HRDP-MGR we saw previously with a little more context.

STRRAT RE

In this instance we can see a new registry key being created which ensures that User Names are not shown at the login screen.

Host IOC: HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v dontdisplaylastusername = 1

This is interesting as it immediately follows what looks to be ensuring that Terminal Services are enabled, and a call to add a user account. To determine if there’s a hardcoded user account we can look out for we will need to examine ‘object2’ which is being cast to a string here; however, before we do we’ll begin to rename some of these variables to help keep track of what we’re looking at. To do this we will need to ensure we’ve highlighted the correct class reference, and right click > rename. Using Recafe all associated class references will be updated.

STRRAT RE

In this instance I’ve renamed it to PluginsServerURL, and also renamed the other reference in this socket connection to PluginsServerPort. Moving back to ‘object2’, we can see this is being assigned by fgfnbnc3.dfhttegd. By viewing the definition of this variable, we find it is defined in the same class we’re currently in.

STRRAT RE

Renaming this variable and revisiting the call, we see that there’s an object definition of fgfnbnc3 from the class fgfnbnc which is why we didn’t see a class with the name fgfnbnc3.

STRRAT RE

The benefit of renaming the String is that now we can find all references to that easily. If we continue to examine this class we find that there’s a definition of this variable within fgfnbnc’s fgsbdfgsb method.

STRRAT RE

Examining this method reveals it is a small function used to build a random string to be used as a Username.

STRRAT RE

It’s important to remember that because we’ve managed to get some decompiled code, string builders like this can be replicated using VS Code to confirm what we’re reading. Although this is a basic method, we can still recreate it by making a class that spits out the output of this method.

STRRAT RE

From this we can see this will create a random string with 5 characters.

STRRAT RE

To get some structure behind analysing this malware flow, we’ll return to the main class that we know will be run as soon as this malware kicks off. First we’ll begin to rename any methods or variables we’ve found so far and give them more descriptive names based on their perceived functionality. I won’t walk through all of the analysis before renaming the variables to assist with analysing the malware in a more meaningful way. We’ll continue to rename more as we determine their purpose; however to start off the following have been renamed:

  • cbnfdhn.sabretb (Method) = cbnfdhn.MakeGetRetResponse
  • Main.sdfsldf (Method) = Main.ObjMakeGetRetResponse
  • Main.sdfsldf (Static String) = Main.STRPluginLocations
  • Main.sabretb (Static String) = Main.STRFileSeparate
  • Main.bsgshsbs (Object) = Main.ObjFileLock1
  • Main.dfhttegd (Object) = Main.ObjFileLock2
  • dfghrth (Class) = FileLock
  • Main.sdfsldf (Method, no input) = Main.GetJarRunPath
  • cbnfdhn.sdfsldf (Method, inputs) = cbnfdhn.C2ConnectAndRun
  • cbnfdhn.mdgghtdsh (Static InputStream) = cbnfdhn.InStream1
  • cbnfdhn.sgsfghhg (Static OutputStream) = cbnfdhn.OutStream1
  • cbnfdhn.hghteerd (Method, no input) = cbnfdhn.ConnectToC2
  • cbnfdhn.gsbthstgb (Static String) = cbnfdhn.Port1
  • xbxcv (Class) = UserIdleObject
  • Main.bsgshsbs (Method, no inputs) = Main.ExtractConfig
  • sabretb.dfhttegd (Method, inputs) = sabretb.DecryptConfig
  • sabretb.sdfsldf (Method, inputs) = sabretb.DeriveIV
  • sabretb.sabretb (Method, inputs) = sabretb.CreateSecKey
  • Main.dfhttegd (Method, no inputs) = Main.ConnectUnknownURL
  • cbnfdhn.sdfsldf (Method, one int input) = cbnfdhn.GetFolderPath
  • cbnfdhn.sdfsldf (Method, one string array input) = cbnfdhn.Uninstall
  • cbnfdhn.bsgshsbs (Static String) = cbnfdhn.FolderPath
  • cbnfdhn.sfsrgsbd (Static String) = cbnfdhn.STRLogsLocation
  • cbnfdhn.sabretb (Static String) = cbnfdhn.STRBackupC2
  • cbnfdhn.sdfsldf (Static Boolean) = cbnfdhn.ActiveConToC2
  • cbnfdhn.thtyrths (Method, no input) = cbnfdhn.ParseNumOfCommands
  • cbnfdhn.sabretb (Method, one int input) = cbnfdhn.ReceiveCommands

If we now examine the main method again we find the below:

STRRAT RE

If the malware is able to get the current malware run path and place dependency files in a folder called ‘lib’, it will then attempt to get the AppData directory based on CSIDL 26. The malware will continue to extract/decrypt its config file and make requests to get any plugins from the URL configured. Finally after this we see it connect to the C2 ready to execute commands received. It should be noted that our defined variables PluginsServerURL and PluginsServerPort are both being reused here as the C2 configuration from within the decrypted config file.

STRRAT RE

In the above we see the start of our C2ConnectAndRun method. In this instance it will check if a directory already exists called strlogs in the malware working directory, if not it will create one. It will also create an object containing information on whether the infected user is idle, and how long they’ve been idle for, before it inevitably connects to the C2.

STRRAT RE

The ConnectToC2 method is pretty straight forward, based on the decrypted configuration file it will first close off any sockets if they already exist with the C2, next it will attempt to connect to the C2 server, and where that fails it will fallback to its backup C2.

STRRAT RE

At this point we can begin to see the different commands taken by this malware as they’re received into the array ‘stringArray2’ from the designated C2, which is also placed into stringArray3.

STRRAT RE

STRRAT RE

STRRAT RE

Based on this we know that STRRAT 1.4 has the following commands available.

  • reboot
  • shutdown
  • uninstall
  • disconnect
  • down-n-exec
  • update
  • up-n-exec
  • remote-cmd
  • power-shell
  • file-manager
  • keylogger
  • o-keylogger
  • processes
  • h-browser
  • startup-list
  • remote-screen
  • rev-proxy
  • hrdp-new
  • hrdp-res
  • chrome-pass
  • foxmail-pass
  • outlook-pass
  • fox-pass
  • tb-pass
  • ie-pass
  • all-pass
  • save-all-pass
  • chk-priv
  • req-priv
  • rw-encrypt
  • rw-decrypt
  • show-msg
  • screen-on

Let’s examine these commands more in depth:

Command Functionality: reboot

This command simply runs the following:

Runtime.getRuntime().exec("cmd.exe /c shutdown /r /t 0");

Command Functionality: shutdown

This command simply runs the following:

Runtime.getRuntime().exec("cmd.exe /c shutdown /s /t 0");

Command Functionality: uninstall

This command runs the following (Noting we’ve renamed the method to “Uninstall”):

cbnfdhn.Uninstall(stringArray);

The uninstall method will then proceed to delete the scheduled task persistence called skype regardless of if it exists, get the directory the malware is running from, delete it from the directory specified by CLSID 7 and 24 Listings can be found here, ping localhost to delay execution for a moment, and then delete the object passed to it, before what appears to be deletion of run keys.

STRRAT RE

It should be noted that the CLSID values are being passed as an integer (Decimal) rather than Hex and would need to be converted to get that 26 = AppData, and 7 = Users Startup Folder.

Command Functionality: disconnect

TBA

Command Functionality: down-n-exec

TBA

Command Functionality: update

TBA

Command Functionality: up-n-exec

TBA

Command Functionality: remote-cmd

TBA

Command Functionality: power-shell

TBA

Command Functionality: file-manager

TBA

Command Functionality: keylogger

TBA

Command Functionality: o-keylogger

TBA

Command Functionality: processes

TBA

Command Functionality: h-browser

TBA

Command Functionality: startup-list

TBA

Command Functionality: remote-screen

TBA

Command Functionality: rev-proxy

TBA

Command Functionality: hrdp-new

TBA

Command Functionality: hrdp-res

TBA

Command Functionality: chrome-pass

TBA

Command Functionality: foxmail-pass

TBA

Command Functionality: outlook-pass

TBA

Command Functionality: fox-pass

TBA

Command Functionality: tb-pass

TBA

Command Functionality: ie-pass

TBA

Command Functionality: all-pass

TBA

Command Functionality: save-all-pass

TBA

Command Functionality: chk-priv

TBA

Command Functionality: req-priv

TBA

Command Functionality: rw-encrypt

TBA

Command Functionality: rw-decrypt

TBA

Command Functionality: show-msg

TBA

Command Functionality: screen-on

TBA

More Parts TBA..