---
id: "MAL-2026-15603"
kind: "package"
aliases: ["MAL-2026-15603"]
title: "Malicious code in pyservercheck (PyPI)"
severity: "critical"
cvss: null
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "pyservercheck", "fixed": [], "affected": "= 0.1.0; = 0.1.1", "ecosystem": "pypi"}]
ecosystems: ["pypi"]
tags: ["malicious", "package"]
not_affected_if: []
published_at: "2026-08-31T05:02:04+00:00"
first_seen_at: "2026-10-26T20:51:57+00:00"
updated_at: "2026-10-26T21:12:36+00:00"
sources: [{"source": "osv-malicious", "url": "https://osv.dev/vulnerability/MAL-2026-15603", "first_seen_at": "2026-10-26T20:51:57+00:00"}]
---

# Malicious code in pyservercheck (PyPI)

## Affected

- pypi:pyservercheck affected = 0.1.0; = 0.1.1 fixed ?

## Timeline

- 2026-10-26T20:51:57+00:00 osv-malicious https://osv.dev/vulnerability/MAL-2026-15603

## From the sources

---
_-= Per source details. Do not edit below this line.=-_

## 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://<decoded-ip>: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

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
