reversing stories….

TeamPCP Malware Analysis: PNG Payload, Donut Loader, and AdaptixC2 RAT

June 18, 2026

Introduction

An autonomous bot first exploited a pull_request_target misconfiguration in the AquaSecurity/Trivy scanner GitHub repository to steal an access token. TeamPCP subsequently used the stolen credentials to push malicious commits to the Trivy repository.


These commits triggered the automated release pipeline, resulting in the distribution of backdoored binaries. The embedded malware was designed to harvest credentials and other sensitive tokens from infected victim machines. The attackers then leveraged a worm component to propagate the infection to additional NPM packages.


TeamPCP later compromised the following packages: LiteLLM, KICS, and Telynx. The LiteLLM infection primarily focused on credential theft, while the Telynx package was weaponized to deliver a Remote Access Trojan (RAT).
My article primarily examines the Telynx attack chain and provides a detailed malware analysis.

Objective

In this article, rather than detailing the full attack flow, I have focused primarily on how the malware operates. I dive deep into the evasion techniques it employs to bypass EDR solutions and interfere with defender telemetry. I specifically investigated the techniques the malware uses to drop and execute the final RAT payload.

Let’s dive into the analysis.

Attack Flow

The attackers injected malicious code into _client.py and released it as part of a existing version of the Telnyx package.

When executed, the malicious code in _client.py connects to the attacker’s Command-and-Control (C2) server and downloads a WAV file. This WAV file then drops msbuild.exe and attempts to execute it.

The dropped msbuild.exe contains an embedded PNG image used to conceal an obfuscated payload. Once deobfuscated, the payload reveals a multi-stage shellcode. The Donut loader component of the shellcode performs reflective loading to execute the final payload entirely in memory.

The final payload is a Remote Access Trojan (RAT) that establishes a connection back to the attacker’s C2 server.

Msbuild.exe Analysis

The malware incorporates multiple anti-debugging and defense evasion techniques. It also embeds a PNG image that contains an obfuscated payload. The PNG image conceals a shellcode, which is obfuscated using a repeating 0xFF pattern.

Stage 1: Evasion The malware employs multiple anti-debugging and defense evasion techniques, which I have shared in the article. Please check it out for more information.

TeamPCP Malware Analysis: Sophisticated EDR Evasion Using Bouncy Gate, ETW Patching, and Donut Loader

Stage 2: Process Creation The executable spawns a child process using the COM surrogate (DLLHost.exe). It then allocates memory in the DLLHost.exe process, changes the memory protection to executable, and prepares the region to receive the payload. The shellcode responsible for evasion and anti-debugging is also copied into the child process.

Stage 3: Writing the PNG Image Payload

The embedded PNG payload is obfuscated with padding 0xFF bytes. The malware first removes this padding to obtain the clean payload.

It then copies the decoded payload to the current process stack and uses NtWriteVirtualMemory to write it into the allocated memory region within the DLLHost.exe child process.

Next, the malware calls NtProtectVirtualMemory to change the memory protection flags, granting execute permissions to the newly written region.

To ensure the target thread can execute the queued APC, the malware first calls NtDelayExecution to place the thread into an alertable wait state. It then uses NtQueueApcThread to queue a user-mode Asynchronous Procedure Call (APC) containing the payload. Finally, it resumes the thread via NtResumeThread, transferring execution control to the next stage inside the DLLHost.exe process.

Stage 4: Donut Loader

The PNG payload actually consists of two parts: the Donut shellcode loader and the final RAT payload (a DLL). The Donut loader assumes control and carries out a highly sophisticated in-memory reflective loading sequence to inject and execute the RAT.

Stage 5: RAT Analysis

The final Remote Access Trojan (RAT) is fully import-less. It dynamically resolves both API imports and strings at runtime. The core of the RAT consists of a large dispatcher function that utilizes jump tables to handle commands based on input received from the attacker.

This RAT is a variant of AdaptixC2. The AdaptixC2 framework identifies its C2 traffic through the custom HTTP header X-Content-ID, which is part of its default communication profile.

Upon execution, the RAT creates a local Windows Named Pipe for inter-process communication (IPC). It then gathers comprehensive machine and user telemetry before sending the collected data to the Command-and-Control (C2) server via an HTTP POST request, using the following headers:

POST Request:
https://83.142.209[.]11:8443/telemetry/checkmarx.json
User Agent: Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20121202 Firefox/20.0
X-Content-ID: CodSL33W3XPMuokpWSq+DBuBaygg2h1CQENUbWZ5G3yb8/7SIW3/Dsd3Su4+j4dRaiiLjOwVGX1eIbARth7lHAXraxdBeGqh443OCDaeqo2frUcaRICCHMqKsZvDOoQBm7/qXb37DQbzLXX7xIPSzp0=

Conclusion

This threat actor’s malware places a strong emphasis on advanced evasion techniques. To counter such threats effectively, security solutions must be capable of quickly detecting tampering with core system components (such as NTDLL hooks and ETW) and preventing the malware from executing at the earliest opportunity.