Sitemap

Malware analysis/Digital forensic: Strela Stealer

9 min readDec 19, 2023

One of my previous posts tackle the topic of JS debugging (which I encourage to read). Here I will analyze another JS, but this time different and more advanced due to JS dropping malicious DLL.

JavaScript debugging

The JS debugging steps are same as in the mentioned post. After preparing x64dbg and setting the breakpoint on ShellExecuteExW, we can start the analysis. Look below for the parameters pushed to Stack after breaking on this function: the JS is copying itself and changes extension to .bat which indicates that this was a batch file from the beginning. The file is executing immediately after dropping, but it can be patched by deleting the execution command and leaving only copy action:

Press enter or click to view image in full size
Original command vs patched command

It can be done by highlighting the script from “&&” to second “ignorepumped.bat” > right click on it > “Binary” > “Edit” > replace hex values with a bunch of zeroes:

Patching

Thanks to that little cheat the malicious offer.js will copy itself, but won’t execute.

Now we can take a sneak peek of what the .bat file has to offer. The script starts with very well known “TVqQAAMAAAAEAAAA” — it’s an MZ file signature encoded with base64, which means that batch will probably decode and drop another file:

Encoded MZ signature

The ending of the script seems obfuscated so we can quickly deobfuscate it with tool like batch_interpreter.py:

Press enter or click to view image in full size
Obfuscated commands
Deobfuscated commands

So, the batch script first searches for lines that doesn’t contain “stupidtwig” (hence the “/V”) and saves them in the file called “drumcannon”. Then certutil decodes “drumcannon” and saves it as “orangesterrific.dll”; at last, regsvr32.exe is being used to load this DLL. As we now know what the batch file is doing after execution, we can do it manually.

Static analysis: DLL

We can extract DLL by mimicking the malware and executing above commands manually:

Manual execution of malicious commands

Now we have malicious DLL file without executing JS first.

In normal EXE file, the IAT (Import Address Table) has specific functions that are imported from specific DLL (eg. CreateProcess from kernel32.dll). If the EXE is importing something from DLL, then DLL should export something from itself, i.e. kernel32.dll would export CreateProcess. In that case, one of the first thing to look for in malicious DLL would be an Export table; below is output from DetectItEasy tool. We can see some interesting functions like memcpy which we will tackle later during debugging of DLL:

DLL export table

The Entropy (5.77) of the DLL says that it is Not packed, but same can’t be said about the .data section where Entropy is 7.7 (and that indicates randomness):

Press enter or click to view image in full size
.data high entropy

DiE is giving the opportunity to see what’s inside the specific section. In .data we can see suspicious, random chars and more randomness starting from address 002cc400 which is probably reason why the entropy got so high:

inside of .data section

Besides that, the static analysis of DLL showed nothing more important. It helped us find suspicious section with encrypted data, so now we can try to debug the DLL and see if it can be decoded.

Reverse engineering: debugging DLL

DLL can be debugged in simmiliar way as the JS, by attaching debugger to rundll32.exe and changing cmdline so that it points to malicious DLL + it’s export function — I choose #1 (ordinal number for 1st function which is DllRegisterServer, as you can see above in Export table), cause in this case it doesn’t matter which function will be chosen as the breakpoint will be set on “memcpy” as it is used to copy memory from one location to another:

Command line pointing to malicious DLL

After running debugger, breaking on memcpy function and executing till return, in the stack panel we can see same random chars that were also discovered during static analysis. After executing the debugger again, it breaks again on memcpy function, but this time, after following random chars in dump panel, there is no random data anymore, but decrypted signature of EXE file (MZ):

Decrypted .data section

Below is the comparison between DiE strings from .data section and dumped .data section memory from x64dbg:

encoded .data vs decoded .data

Static analysis: dumped EXE

We can now delete everything prior to MZ signature and load it into PE file analyzer to check it statically. There are suspicious strings related to Outlook (registry key) and Thunderbird (logins.json and key4.db) as well as malicious URL address: 193.109.85.77/server.php. There is also “strela” string present, which immediately gives an idea what family the malware is from, which is Strela Stealer:

Press enter or click to view image in full size
Dumped EXE strings

It is also using a couple of functions, where the most suspicious ones would be those related to making connections (wininet.dll) and registry (advapi32.dll):

Suspicious functions from dumped EXE

Reverse engineering: disassembling dumped EXE

The file is not encrypted, so we can take a sneak peek into those functions and its parameters by disassembling malware using IDA. We can start from RegEnumValueA API which is referenced in: sub_140001240:

RegEnumValueA

sub_140001240 is querying registry key which had been found during strings analysis:

Press enter or click to view image in full size
Outlook registry key query

References to sub_140001240 gives us an address where this function is called from (sub_140001B10):

Reference to sub_140001240

After going to that address, we can see two calls: sub_140001740 (unknown at this moment) and sub_140001240 (responsible for querying the registry):

sub_140001B10 calls

Now let’s see what is in the other address (sub_140001740):

Thunderbird folder query

So, sub_140001740 queries the Thunderbird files and sub_140001240 registry for Outlook. Both these function at some time calls sub_140001000, which has APIs responsible for making internet connection:

Internet connection API + C2 address

After renaming these 3 functions, we have Thunderbird (sub_140001740), Outlook (sub_140001240) and InternetConnection (sub_140001000); below you can see that InternetConnection function is referenced in Outlook and Thunderbird, which indicates that the stolen data is going to be sent to previously identified malicious address:

Final APIs

Quick dynamic analysis: DLL

Before ending this section, let’s see what happens after executing DLL with the intended way, using regsvr32.exe; I wil use SysInternals’ procdump.exe to dump the process immediately after execution, before it exits. After analyzing strings from dumped regsvr32, we can see that DLL is indeed loaded by regsvr32.exe as the IOCs extracted during static analysis of dumped EXE are present in regsvr32 memory:

Press enter or click to view image in full size
Dumping regsvr32.exe
Strings dumped EXE vs strings regsvr32.exe memory

In summary: offer.js copies itself to %TEMP/ignorepumped.bat -> executes ignorepumped.bat -> creates drumcannon > creates orangesterrific.dll > load it via regsvr32.exe > decodes data from .data section > becomes Strela Stealer > steals data.

Forensic analysis:

Now let’s execute JS like a regular user. Below are the artifacts that could help in this kind of investigation, so the presence, execution of malicious file can be proved.

Existence artifacts:

To see what files were created after execution of malicious file, we can filter tables $MFT and $J for the events after creation of offer.js. After filtering out some legitimate system data, there are couple of suspicious filenames. It can be assumed that the batch script after execution is creating three files which presence can be proved by $MFT and $J:

Press enter or click to view image in full size
Evidence of existence ($MFT + $J): malicious files

Execution artifacts:

The execution of JS could be proved by prefetch or RecentDocs, but there is also another artifact. After execution, an “LNK” file (shortcut) is created and saved in: “*user*\AppData\Roaming\Microsoft\Windows\Recent”, so the presence of “offer.lnk” proves the execution of file with that name. As the LNK files are created after execution of original file, the creation time of LNK means the time when the original file has been executed. It has also two sets of MAC times: one for original file and 2nd for LNK file. Below you can see parsed LNK file — look at the amount of information extracted from only one file. We have original file path, creation, access and also MFT number (83112 in hex). Besides that it gives us also hostname, MAC address and even volume name + serial number as well as the type of the drive:

Press enter or click to view image in full size
Evidence of offer.js execution: LNK file

The batch file execution can be proved by prefetch/logs (Modified time of prefetch file proves last execution of CMD.exe, not specific batch file, so the absence of batch file is possible as it could be overwritten by another script):

Evidence of ignorepumped.bat execution: CMD prefetch file

JS after execution is copying itself as a batch file, then proceeds to extract part of the script with use of “findstr” and saves it into “drumcannon” which is then decoded by “certutil” and saved as “orangesterrific.dll” file; lastly, the DLL is loaded via “regsvr32.exe”. The usage of all of these commands can be proved by Security log along with time correlation of initial script’s execution (“offer.js”); below is the path of execution command after command, starting from wscript.exe:

Press enter or click to view image in full size
Evidence of malicious commands execution: Security log, 4688 ID

The most important is the usage of regsvr32.exe, so let’s find another artifact that proves execution of it along with time correlation. Below is parsed prefetch file for regsvr32.exe along with last times of execution:

Press enter or click to view image in full size
Evidence of regsvr32.exe execution: regsvr32 prefetch file

One of the time (15:42:20) correlates really well with creation of malicious DLL (15:42:19), so we can safely assume that the malicious DLL has been properly loaded via regsvr32.
Below a quick summary of artifacts (not exhaustive as there are more artifacts in different places):
Forensic existence artifacts: $MFT and $J table
Forensic execution artifacts: LNK, Prefetch, Security.evtx

Summary

Malware analysis + reverse engineering helped in extracting vital IOCs for this malware. Forensic analysis of regular user’s system proved the execution of malicious JS which run in intended way. And that would be all for today. Quick recap:
JS debuging steps: open wscript.exe in debugger > change cmdline to point to JS > add shell32.dll breakpoint > Run until break > set breakpoint on ShellExecute* from shell32.dll > disable shell32.dll > Run until break
DLL debugging steps: open rundll32.exe in debugger > change cmdline to point to DLL > set breakpoint on chosen exported function > run until break.
Tools used: x64dbg (debugger), batch_interpreter.py (bat script beautifier), DetectItEasy (static analysis), IDA (dissassembler), procdump, strings, MFTECmd ($MFT/$J parser), TimelineExplorer (CSV interpreter), LECmd (LNK parser), WinPrefetchView/PECmd (prefetch parser), EventViewer (logs). This list is not exhaustive and there are a lot of other tools used in the same purpose.

I encourage you to read my other posts:

--

--

Dawid Bolkowski
Dawid Bolkowski

Written by Dawid Bolkowski

cybersec, forensics, malware analysis