Skip to main content
Live Webinar with SANS (June 25)— Agentic CTI Automation for Fun & ProfitRegister Free
Mallory
MalwareUsed by 1 actor

sysmon.py

sysmon.py is a persistent Python backdoor referenced across multiple 2026 software supply-chain intrusions attributed in the reporting to TeamPCP. It is described as a follow-on implant used in campaigns linked to the Trivy attack, the CanisterWorm npm compromises, the Checkmarx KICS/OpenVSX compromises, and trojanized LiteLLM PyPI releases. On Linux systems, the malware is dropped to paths such as ~/.config/sysmon/sysmon.py, /root/.config/sysmon/sysmon.py, or /host/root/.config/sysmon/sysmon.py and persisted via a systemd user service, including names such as sysmon.service or a disguised "System Telemetry Service," to ensure restart on boot or continued execution without root on standard hosts. The implant polls attacker-controlled endpoints for follow-on payloads, including https://checkmarx.zone/raw and, in related reporting, behavior similar or identical to the sysmon.py payload from the Trivy attack. It uses delayed beaconing, periodically retrieves a URL, downloads a remote binary to /tmp/pglog, marks it executable, and launches it as a detached process. A kill-switch/dormant-state check ignores URLs containing youtube.com. In Kubernetes-aware variants, the malware adds persistence by using available service account access to enumerate nodes, deploy highly privileged pods in the kube-system namespace, escape to the host via hostPath-mounted root filesystems, and install sysmon.py plus a systemd service on cluster nodes, allowing persistence beyond the original CI or container context. The malware has been associated with credential-theft operations targeting CI environments, cloud credentials, Kubernetes secrets, SSH material, package-manager tokens, and developer infrastructure, but sysmon.py itself is specifically the persistent C2 backdoor component used to fetch and execute additional payloads.

Share:
For your environment

Hunt this family in your stack

Mallory pivots from this family to the IOCs, detections, and named campaigns that touch your stack, and pages you when something new lands.

THREAT ACTORS

Groups observed using it

1 distinct threat actor attributed by public researchers. Open in Mallory to see the full evidence chain and overlapping campaigns.

View more details
TeamPCP

As with the Trivy operation, this malware can drop a python script intended to download and install a follow-on payload... If it is run on a standard linux host, it creates hidden directories in the users home folder ~/.config/sysmon and writes the python backdoor there. The backdoor is the same as in the previous version, except it reads from https://checkmarx.zone/raw

via wiz blogwiz.io
MITRE ATT&CK

Techniques & procedures

25 distinct techniques documented for this family, organized by ATT&CK tactic.

Initial Access

2 techniques
T1133External Remote ServicesEvidence1

The dropper sleeps 5 minutes, then polls the ICP blockchain-hosted C2 for a second-stage payload URL, downloads it to /tmp/pglog , and executes it.

T1195Supply Chain CompromiseEvidence1

The KICS GitHub Action was compromised with credential-stealing malware by TeamPCP... The malicious code was injected in the same manner as the Trivy incident: The attacker staged imposter commits... and directly update all 35 tags in the project... Update 03/24: The "litellm" packages on PyPI have been trojanized... Both compromised extensions... contained identical payloads.

Execution

5 techniques
T1053Scheduled Task/JobEvidence2

If absent (meaning it's running on a developer machine or standalone server, not in CI), it writes this Python script to ~/.config/systemd/user/sysmon.py and creates a systemd unit for persistence.

T1053.006Systemd TimersEvidence2

If absent (meaning it's running on a developer machine or standalone server, not in CI), it writes this Python script to ~/.config/systemd/user/sysmon.py and creates a systemd unit for persistence.

T1059Command and Scripting InterpreterEvidence2

// Title: TeamPCP Process Execution Artifacts ... // MITRE ATT&CK TTP ID: T1059 ... action_process_image_name in ( "openssl" , "tar" , "curl" , "systemctl" , "python" )

T1059.006PythonEvidence5

it executes a base64-encoded Python filesystem harvester signed "TeamPCP Cloud stealer"

T1610Deploy ContainerEvidence1

If the script is run on a Kubernetes container that has sufficient permissions, it will attempt to deploy a highly privileged pod and run sysmon.py within it... places a highly privileged pod in the 'namespace':'kube-system'.

Persistence

5 techniques
T1053Scheduled Task/JobEvidence2

If absent (meaning it's running on a developer machine or standalone server, not in CI), it writes this Python script to ~/.config/systemd/user/sysmon.py and creates a systemd unit for persistence.

T1053.006Systemd TimersEvidence2

If absent (meaning it's running on a developer machine or standalone server, not in CI), it writes this Python script to ~/.config/systemd/user/sysmon.py and creates a systemd unit for persistence.

T1133External Remote ServicesEvidence1

The dropper sleeps 5 minutes, then polls the ICP blockchain-hosted C2 for a second-stage payload URL, downloads it to /tmp/pglog , and executes it.

T1543Create or Modify System ProcessEvidence2

Beyond stealing credentials and achieving persistence, the threat actors also masqueraded their activity as legitimate services like systemd... Figure 4 shows code written to /host/root/.config/sysmon/sysmon.py.

T1543.002Systemd ServiceEvidence6

On non-CI systems, the malware installs persistence via a systemd user service... it creates a systemd unit file at /root/.config/systemd/user/sysmon.service to ensure the python script is run.

Privilege Escalation

4 techniques
T1053Scheduled Task/JobEvidence2

If absent (meaning it's running on a developer machine or standalone server, not in CI), it writes this Python script to ~/.config/systemd/user/sysmon.py and creates a systemd unit for persistence.

T1053.006Systemd TimersEvidence2

If absent (meaning it's running on a developer machine or standalone server, not in CI), it writes this Python script to ~/.config/systemd/user/sysmon.py and creates a systemd unit for persistence.

T1543Create or Modify System ProcessEvidence2

Beyond stealing credentials and achieving persistence, the threat actors also masqueraded their activity as legitimate services like systemd... Figure 4 shows code written to /host/root/.config/sysmon/sysmon.py.

T1543.002Systemd ServiceEvidence6

On non-CI systems, the malware installs persistence via a systemd user service... it creates a systemd unit file at /root/.config/systemd/user/sysmon.service to ensure the python script is run.

Stealth

5 techniques
T1027Obfuscated Files or InformationEvidence2

On GitHub-hosted Linux runners, a Base64-encoded Python script is decoded and executed... On self-hosted runners, a different Base64-encoded Python script performs broad filesystem credential harvesting.

T1036MasqueradingEvidence1

The primary exfiltration channel is an HTTPS POST to scan.aquasecurtiy[.]org — a typosquatted domain mimicking Aqua Security's legitimate aquasecurity.com... The choice of filename mimics PostgreSQL logging

T1218.001Compiled HTML FileEvidence1

If absent (meaning it's running on a developer machine or standalone server, not in CI), it writes this Python script to ~/.config/systemd/user/sysmon.py and creates a systemd unit for persistence.

T1497.003Time Based ChecksEvidence1

After an initial five-minute sleep (likely intended to outlast sandbox analysis timeouts), it enters a polling loop that contacts a command-and-control (C2) server approximately every 50 minutes.

T1564.001Hidden Files and DirectoriesEvidence1

If it is run on a standard linux host, it creates hidden directories in the users home folder ~/.config/sysmon and writes the python backdoor there.

Credential Access

5 techniques
T1003OS Credential DumpingEvidence1

On GitHub-hosted Linux runners, a Base64-encoded Python script is decoded and executed with sudo. It locates the Runner.Worker process, reads its memory maps via /proc/{PID}/maps, and scrapes raw process memory via /proc/{PID}/mem looking for GitHub Actions secrets

T1552Unsecured CredentialsEvidence2

It targets the following: ... Kubernetes configs and service account tokens ... Infrastructure-as-code secrets (Terraform state/vars, Ansible, Helm) ... TLS/SSL private keys ... .env files and API keys ... System files (/etc/passwd, /etc/shadow, shell histories)

T1552.007Container APIEvidence1

If the script is run on a Kubernetes container that has sufficient permissions, it will attempt to deploy a highly privileged pod... The script checks to see if the file: /var/run/secrets/kubernetes.io/serviceaccount/token exists and if it does, it uses that token to query /api/v1/nodes.

T1555Credentials from Password StoresEvidence1

It targets the following: ... Cloud credentials (AWS, Google Cloud, Azure) ... Docker registry credentials ... Database credentials ... CI/CD configs ... .env files and API keys

T1649Steal or Forge Authentication CertificatesEvidence1

On self-hosted runners, a different Base64-encoded Python script performs broad filesystem credential harvesting. It targets the following: SSH private keys and configs

Discovery

2 techniques
T1057Process DiscoveryEvidence1

Stage 1: Runner Process Discovery Initially, the script enumerates process IDs (PIDs) of GitHub Actions runner processes (Runner.Worker, Runner.Listener, runsvc, run.sh)...

T1497.003Time Based ChecksEvidence1

After an initial five-minute sleep (likely intended to outlast sandbox analysis timeouts), it enters a polling loop that contacts a command-and-control (C2) server approximately every 50 minutes.

Command and Control

3 techniques
T1071Application Layer ProtocolEvidence3

...maintains ongoing access through a takedown-resistant C2 hosted on the Internet Computer Protocol. | The dropper sleeps 5 minutes, then polls the ICP blockchain-hosted C2 for a second-stage payload URL...

T1071.001Web ProtocolsEvidence3

polls the ICP blockchain-hosted C2 for a second-stage payload URL, downloads it to /tmp/pglog , and executes it.

T1105Ingress Tool TransferEvidence5

The dropper sleeps 5 minutes, then polls the ICP blockchain-hosted C2 for a second-stage payload URL, downloads it to /tmp/pglog , and executes it.

Exfiltration

2 techniques
T1029Scheduled TransferEvidence3

The persistence script polls https://checkmarx.zone/raw every 50 minutes for additional payloads... while True ... time.sleep(3000)

T1567Exfiltration Over Web ServiceEvidence1

The primary exfiltration channel is an HTTPS POST to scan.aquasecurtiy[.]org... If the endpoint returns a non-2XX response and INPUT_GITHUB_PAT is available, the script falls back to exfiltrating through GitHub itself. It will create a public repository named tpcp-docs under the victim's GitHub account, create a timestamped release, and upload the encrypted bundle as a release asset.

INDICATORS OF COMPROMISE

IOCs tracked for this family

19 indicators attributed across vendor reports, sandbox runs, and researcher write-ups. Full values are available in Mallory.

View more in app
Network
1 tracked

IPs, domains, and DNS infrastructure linked to this family.

Hashes
17 tracked

File hashes (MD5, SHA-1, SHA-256) from samples and reports.

Other
1 tracked

Other indicator types observed in public reporting.

TypeValueLatest sighting
domain●●●●●●●●●●●●View more in app1 month ago
hash.sha1●●●●●●●●●●●●View more in app3 months ago
hash.sha1●●●●●●●●●●●●View more in app3 months ago
hash.sha1●●●●●●●●●●●●View more in app3 months ago
hash.sha1●●●●●●●●●●●●View more in app3 months ago
hash.sha1●●●●●●●●●●●●View more in app3 months ago
ACTIVITY FEED

Recent activity

4 sources tracked across advisories, community write-ups, and news. New activity surfaces here as Mallory finds it.

opensourcemalware blogNews
Mar 25, 2026
TeamPCP Hijacks LiteLLM's PyPI Package - Credential Stealer Hits 40k-Star Project | OpenSource Malware Blog

A Linux persistence backdoor dropped by the malicious LiteLLM package payload. It is installed as a disguised system telemetry service, beacons to checkmarkr.zone/raw for commands, and provides persistent access on Linux hosts and Kubernetes nodes.

Read more
step security blogNews
Mar 24, 2026
litellm: Credential Stealer Hidden in PyPI Wheel - StepSecurity

A persistent C2 backdoor dropped by the malicious litellm package. It is installed as a systemd user service, polls https://checkmarx.zone/raw roughly every 50 minutes, downloads arbitrary binaries, makes them executable, and runs them detached. In Kubernetes environments, it is also written onto host nodes for persistence and lateral compromise.

Read more
ramimac blogNews
Mar 23, 2026
KICS GitHub Action Compromised: TeamPCP Supply Chain Attack | Wiz Blog

A Python backdoor dropped by the malicious setup.sh script. It persists on Linux hosts or Kubernetes nodes, polls attacker-controlled infrastructure for additional payload URLs, downloads and executes follow-on payloads, and is used to maintain access after the initial CI/container execution ends.

Read more
aikido dev blogNews
Mar 20, 2026
TeamPCP deploys CanisterWorm on NPM following Trivy compromise

A Python backdoor payload referenced as highly similar or identical to the CanisterWorm second-stage implant, using an ICP canister dead-drop to retrieve a URL for a downloadable binary payload.

Read more
What this page doesn’t show

The version that knows your environment.

This page is what’s public. Mallory adds the parts that aren’t: which of your assets match these IOCs, which detections are missing, which campaigns to expect next, and what to do in the next 30 minutes.
IOC matching19

Match every observed IP, domain, and hash against your live telemetry.

Threat actor attribution1

Named campaigns wielding this family, with evidence pinned to each claim.

Exploited vulnerabilities

CVEs this family uses for access and lateral movement.

Detection signatures

YARA, Sigma, Snort, and vendor rules, auto-deployed to your SIEM.

MITRE ATT&CK mapping25

Every documented technique, ranked by evidence weight.

Researcher chatter

Reddit, Mastodon, and CTI community discussion around this family.