CRITICAL PyPI Malware

Malicious code in pyservercheck (PyPI)

MAL-2026-15603

Published · Modified

Dependency scanning

Check whether pyservercheck is in your codebase

Corgea flags malicious and compromised dependencies with reachability analysis, so you fix the packages that actually run in your application instead of working through the whole lockfile.

Description


__

Source: amazon-inspector (d10f01e2954dde5faac23074d02bb989f22d0dcb78be82c1c4417531fef8b859)

The package ships a bundled Node script pyservercheck/js/main.js whose visible top half is a healthcheck stub matching the README, followed by a long run of tab whitespace and a trailing eval(atob('...')) that decodes to a two-stage loader. The decoded loader queries public Ethereum RPC endpoints (eth.blockscout.com, 1rpc.io/eth, eth.drpc.org, ethereum-rpc.publicnode.com, eth-mainnet.public.blastapi.io) for the latest transaction from the hardcoded sender 0xa322E5f3D311D3080e6f0121063e9aDC2490Ef1a, extracts an IPv4 pair from the tx to field, fetches XOR-obfuscated stage-2 code from http://:443/0x/cls and /0x/ls, eval()s it, and re-launches it via a detached spawn('node', ['-e', <code>]). Execution is wired to two auto-triggers: pyproject.toml overrides setuptools build_py and develop with pyservercheck._setup_cmd.BuildPy/Develop, whose run() calls _run_main_js_now() -> subprocess.run(['node', main.js]) during pip install / pip install -e.; and BuildPy also writes a pyservercheck.pth file containing import pyservercheck._hooks; pyservercheck._hooks.ensure_once(), which Python auto-executes at every interpreter startup, invoking run_js() again. The .main_js_ran marker is advisory and can be removed to force re-execution. The C2 destination is rotatable by publishing a new Ethereum transaction from the sender address, so the fetched payload is fully attacker-controlled at each run.

Source: kam193 (4b365b9df06973db4f112bdbf2ad704dcc91c1b7b3eaceddb06a8e884c3f760a)

Package embeds obfuscated, JS-based malware downloading further remote stages. The code is triggered during building the package and on every Python startup (via PTH file). The next-stage IP is delivered via a blockchain.

The payload and embedded IoCs are consistent with campaigns attributed to Lazarus APT/PolinRider.


Category: MALICIOUS - The campaign has clearly malicious intent, like infostealers.

Campaign: 2026-08-pybitjs

Reasons (based on the campaign):

  • obfuscation

  • Downloads and executes a remote malicious script.

  • malware

  • abuses-pth

  • c2-in-blockchain

Ready to move

Start Securing

Free, no credit card | First findings in minutes