Executive Summary

Over the past year or more we’ve observed infostealers deployed at record rates. They hit quick, grab sensitive credentials and other valuable data from their victims, and they’ll hang around for as long as you’ll let them. Threat actors (TAs) love them due to the ease of automating their code base, delivery methods which have proven trivial to persuade users to infect themselves, and high infection rates. In short, they grab what they want quickly and keep coming back for more.

In this piece we’re going to review an infostealer we observed attempting to infect a host and break down the attack chain including delivery, execution, several independent code functions, and a persistence technique gaining steam in the wild. Thanks to our SOC, the infection was short lived and client crisis averted. Meanwhile, our Threat Research team coaxed the malware into sending additional payloads. They found modules which deliver a PowerShell backdoor which used a unique persistence mechanism called TypeLib Hijacking; scanned files, crypto wallets, and browser extensions; took screen shots; keylogged; and compiled its own invisible browser extension for further harvesting.

Delivery Mechanism

In this case, a user was browsing with a popular search engine to look for important information for their day-to-day job responsibilities – indiscriminately grabbing information from as many sites as they could. One of the sites provided a .zip archive, which contained a file called “FULL DOCUMENT.js”, which was the initial payload stub for this infection.

Initial Access

The Threat Research team was provided with the sample above. We were able to put the initial payload stub in a sandbox and interact with it, coaxing the malware to expose its payloads and communication mechanisms.
It’s worth noting at this point that obfuscation is a tactic frequently deployed by TAs to impede analysis, evade EDR/XDR detections, potentially increase the longevity of a campaign, and confuse engines which detect by heuristics. There are multiple techniques obfuscate. However, what the team observed in this sample was largely character obfuscation, string slicing, and superfluous math functions.
By double clicking on the .js file, a victim launches wscript.exe executing the obfuscated contents of the .js file. Figure 2 displays the raw contents of the file:

The “GetObject” function is native to Visual Basic. It’s function here is to retrieve code. The code in parentheses is a little harder to understand. It’s a combination of obfuscation with unicode strings and hex encoding. Cleaning up the first portion reveals the VisualBasic “scriptlet” function. Painting a clearer picture: retrieve code and execute a script. For the final bit we need to convert the hex string “0x932d2d” and the Unicode “\u0061” from Figure 3.

This leaves us with the following the IP and path at the remote resource the .js file is reaching out to.

At a glance this appears to be a benign site, offering a blank page.

However, inspecting the page source (or curling it) reveals the malicious script.

The script is intended to combine the obfuscated PowerShell code from line 8, deposit it into a file, and execute it. The PowerShell is filled with superfluous math functions, but it ultimately constructs a URL and checks the host for other instances of itself running.
A cleaned version which has been stripped of execution properties is pictured below.

This snippet is effectively a launcher for the next stage, the main script. By checking / manipulating mutexes the threat actor can ensure only one process is contacting the control server. The while loop is checking for other instances (mutexes) and pulling the next stage from the control server.

Malware / Coms / Persistence

If there are no other instances of malware running on the host, the next stage is executed. It’s worth mentioning that when continuing execution, there was no anti-malware analysis before or after this point. We can’t say precisely why but traditionally it suggests the creator of this sample is not fully versed in the art, their intent was for speed and quantity over quality, they tested their wares with a limited number of sub-par detection software’s which did not flag this sample, it was a one-off campaign, or they intentionally avoided it altogether in an attempt to blend into normal activity.
The Threat Research team was able to substitute variables and get malicious code to step through execution and display output directly to the screen. Pictured in Figure 8 on line 62 is an artifact from the log which could potentially be used to correlate a malware builder moving forward. Displayed notable characters in the same format that iterates upon each communication cycle.

This is the final initial payload stub, or the “main” script delivered by the malware. A PowerShell backdoor which is comprised of several interesting functions (partially listed here for brevity):

Functions What They Do
Get-A Query for antivirus products
Send-Log Send data to control server
Add-Type -TypeDefinition @” ScreenGrabber written in C#
Send-Picture Send ScreenGrab
Get-Scr Take Screen shot
Dump-DB The Dump-DB function is a PowerShell, “raw-bytes” parser for a SQLite database file.
Get-ChromiumProfile Automates the extraction of saved logins (usernames, passwords, URLs, etc.) from a Chromium-based browser profile
Get-FFProfile Automates the extraction of saved logins (usernames, passwords, URLs, etc.) from FireFox
Get-Browsers Function browser-profile enumerator and credential exfiltration routine.
Get-And-Archive-BrowserExtensions Takes stock of extensions. + copies their files.
Get-And-Archive-DesktopWallets Takes stock of crypto wallets + copies their files.
Send-Archive Sends loot collected from the host if it was “archived”.
Send-PasswordArchive Examines files for keywords (passwords) and sends archived files to control.
Grab-Pictures Takes all ‘.jpg’, ‘.jpeg’, ‘.png’, ‘.gif’, ‘.bmp’, ‘.tiff’, ‘.webp’ less than 2MB in size
$computerInfoCode Another C# script for Domain discovery.
$cookies_grabber_code @” A malicious browser extension to steal cookies from the victim.

 

Also embedded in the code is a key-logger encoded in base64 in the variable “$kg_b64_bytes”. More on these in the Methods section below.

Finally, the last bit of the PowerShell script is loaded and run pictured below.

Persistence and Execution

During execution of the PowerShell script, the $url variable (the IP put together in Figures 2-4) is combined with an additional remote path, “/transform” to expose the final payload from control. This is yet another obfuscated PowerShell script.

Dynamically analyzed, this function does two things: generates a randomly named folder in the “C:\ProgramData\” directory (“ylceestb” shown below) and deposits a randomly named *.ps1 file in “C:\ProgramData\”.

The “vxeuepyl.sct” file contains elements of both execution and persistence.

The PS1VAR1 circles back to commands observed earlier during execution:

The two reg commands are consistent with a persistence mechanism that is well known in the offensive security community, but experiences relatively low use in the wild: TypeLib Hijacking.

For all intents and purposes in this scenario, the reader simply needs to know that “COM Objects” (Component Object Model) are necessary for Windows functionality. It’s a system where code can properly reference other bits of needed code. This makes life easier for developers, allows multiple operating system versions to play nice with each other, etc.

Some COM objects will require the use of a “TypeLib” class. You wouldn’t be blamed for thinking TypeLib is “fonts” at this point. But, it’s just code / programming which helps different code / programming languages interact with each other.

When executing this attack, threat actors look for COM objects which rely on a TypeLib class. The WindowsRegistry stores and points to a location on disk where necessary information or binaries are stored for all of the required COM and TypeLib objects. So, if an attacker can make a location in the registry, which they know will be used for a COM object that requires a TypeLib class, point at their malicious code – they’ll have gained persistence on the box.

In Figure 14, on line 3209, we see the attacker delete the entire registry key required for TypeLib Libraries to reference necessary code. They immediately add their malicious reference with the next command. The script executes a variable “script:$sctFilePath”, but that’s substituted at run time and just points to a PowerShell script on disk.

We were able to locate the file on disk, saved to “C:\ProgramData\”.

The script is unsurprisingly obfuscated, again with superfluous functions and random math:

This script decodes into an almost identical version of the PowerShell launcher that we dissected earlier which checks for mutexes and starts the main PowerShell script if it’s not already running (Figure 7).

Custom Methods

There’s simply too much to go through to break down the entire script in this posting. The Main PowerShell script was ~3k lines. However, as we mentioned earlier, there are a few items of note.

Firstly, the malware features a code function called “Get-A”. This function queries the WMI namespace for Antivirus products VIA native PowerShell modules. We observed obfuscation which decodes at run time to spell out “root\SecurityCenter2” and “SELECT * FROM AntiVirusProduct”.

There are several methods to send data back to control. “Send-Log”, “Send-Data”, “Send-Picture”, “Send-Archive”, and the list continues.

In each of these, the same $url variable is used to post data that is acquired from the host. However, the post method is generally going to a path like “?k=” or similar depending on each individual function in the script.

The “Dump-DB” function is interesting as well. Rather than loading SQLite databases through the SQLite engine, it opens the .db file as a binary stream, walks its records, and decodes each individually.

PowerShell, built to be the “one shell to rule them all”, was made to be as flexible as possible. With that, Microsoft added the ability to compile code on the fly. This is observed in the attackers “Add-Type -TypeDefinition @”” code. This method is a longwinded way of building an application which takes screen shots of the victim and saves them as .bmp files. The TA was also nice enough to leave comments in the code.

The TA uses the same built-in PowerShell method to create a malicious browser extension in the “$cookies_grabber_code = @”” variable. Code in the variable is again compiled on the fly to collect cookies and post them. Of note, the TA leaves code in this variable to post to “localhost:3000”.

But it’s changed near the end of the script prior to runtime so that posting is routed to the malicious URL, not localhost. This is a simple, interesting, and effective method of instantiating a variable which transfers from C2 to C2 deployment without re-basing code.

Lastly, the keylogger is interesting as well. The function contains a pre-compiled .dll binary encoded in base64 and stored in the “$kg_b64_bytes” variable. Meaning it went out of it’s way to avoid using the previously mentioned PowerShell Add-Type method. Once the function is loaded at runtime, we observed the same mutex checks (to make sure only one instance is running), and see it reflect into memory through frequently observed PowerShell methods deployed by malware.

Our team tested the code to make sure there was no other functionality built into the encoded .dll. When run, it posts keystrokes from a host to the previously mentioned URL variable using a new path: “/?keylog=”. Figure 21 illustrates our manipulation of the keylogger, sending our keystrokes to a local server, not the attackers.

Detection

There are several IOCs listed at the bottom of this post. At the time of writing, the IP is still active, so grabbing the malware and teasing methods out can be done by anyone who followed our cues in the post or just knows how to do so.
Early detection of execution is key to limiting impact. Analyzing WScript/CScript execution for short scripts containing encoding with Unicode or Hex is something some readers can do with their EDR deployment. CyberMaxx has multiple custom detections in place looking for this type of execution as well as ingress and egress methods mentioned and unmentioned in this post. Depending on the size/scale of an environment, administrators may be able block execution of binaries from Zone 3 through group policy.

A more authoritative and robust method of detection, but occurring later in the killchain, is monitoring registry mods surrounding TypeLib Hijacking. This would likely catch more than just “infostealers” and may alert you to a threat actors’ presence in more campaigns. The “HKEY_CURRENT_USER\Software\Classes\TypeLib” (which could also be observed in shorthand HKCU) Key in our case had its contents completely removed. Likewise, the “{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}” CLSID is a commonality that was mentioned in a blog from ReliaQuest in April 2025. Of note, based off codebase reuse, one may be quick to lump this activity in with Blackbasta. However, since the code was exposed, and known infrastructure similarities are tenuous at best, we are not assessing attribution with any degree of confidence at this time.
Lastly, if you’re interested in knowing more about how TypeLib hijacking works, Michael Zhmailo (AKA CICADA8), has posted a blog on the technique.

Closing

In this post we analyzed an infostealer from start to finish. Hopefully this provided insight on how threat actors deliver malware as well as their intent once they compromise a host. CyberMaxx is well armed and ready to defend against this type of attack because our offensive operators continue to inform the defense. We’ll continue our research and community collaboration which are essential to staying ahead of threats.