Malicious actors published seemingly legitimate packages to the npm registry that contained malicious code hidden within image files. The code was executed during installation and established communication with a command-and-control server.
The technique is similar to a previous attack on PyPI packages, where the attackers modified a legitimate library (aws-s3-object-multipart-copy) to execute a hidden script (loadformat.js) containing the malicious code.
It reveals a steganography attack that leverages image analysis for malicious code execution, as it first reads an image file and extracts printable characters (between ASCII values 32 and 126) that are then concatenated. If the extracted string length exceeds 2000 bytes, it’s considered a malicious payload.
The attacker then defines two benign-looking function bodies: one sends a POST request and the other checks the node version. A variable, convertertree, is set to true if the extracted string is long enough, which essentially acts as a switch.
Finally, a new function is created dynamically using the appropriate function body based on the value of the converter tree, and if the image embeds a malicious script, the new function will execute it, while a harmless action (like checking the node version) is performed if the image is clean.
According to Phylum, it examines three image files: logo1.jpg (Intel), logo2.jpg (Microsoft), and logo3.jpg (AMD), where the function named processImage is used to analyze these files.
It appears that processImage checks for the presence of “valid” bytes within the image data. Both logo1.jpg and logo3.jpg fail this check, most likely as a result of corruption or a lack of the precise byte patterns that the function requires.
Logo2.jpg (Microsoft) passes the check, suggesting it contains the necessary bytes and triggers further processing within processImage. The specific details of what constitutes “valid” bytes and the subsequent processing steps for valid images remain unclear from the provided information.
By establishing a connection with a Command and Control (C2) server and registering the client’s hostname and operating system details, it initiates a loop that fetches commands from the server at a predefined interval.
The loop parses the received command, and if the command is to change the loop interval, the code updates the interval and restarts the loop. If the command is a “cd” command, the code attempts to change the directory. Otherwise, the code executes the command and sends the output back to the server.