Skip to content

Indicator review, 2026-10-12

Outcome 12 indicators added
Pull request #39
Indicator set ioc/bad-packages.txt, ioc/weak.txt, ioc/network.txt, ioc/filenames.txt
Source Reached What it said
OpenSourceMalware dossier yes, cloned and read Unchanged for the sixth week running. Latest commit still 0a8c9ea, 2026-07-09 — thirteen weeks. No CSV newer than the two July 10 files
opensourcemalware.com blog no — proxy 403 on CONNECT Reachable every week since 2026-09-14. Not reachable this week. Nothing in this entry comes from it, and a post published inside the window would not have been seen
Web search, last 7 days yes Searched the campaign name, MicrosoftSystem64 and ForceMemo. Only secondary coverage inside the window; see upstream state
socket.dev tracker no — proxy 403 Fifth week in a row

The egress allowlist has narrowed sharply since last week. Every analysis host that served content on 2026-10-05 now fails at the proxy with a CONNECT 403 from curl, and with a DNS failure from the web-fetch tool:

Host 2026-10-05 This week
opensourcemalware.com reachable blocked
safedep.io reachable blocked
blog.deception.pro reachable blocked
thehackernews.com reachable blocked
checkmarx.com reachable blocked
socket.dev 403 blocked
medium.com 403 blocked
gbhackers.com, unit42.paloaltonetworks.com, cyberpress.org, stepsecurity.io, mallory.ai, securityonline.info not tested, or reachable blocked
github.com by git clone reachable reachable
registry.npmjs.org, pypi.org reachable reachable

This is the state the standing appendix describes for 2026-09-07, not the one the directory README’s source table describes. The table is left as it is, because it records what was true when it was written; this row is the correction. This review is therefore a weaker claim than the last three: it reached the dossier, the OpenSSF database and the registries, and saw everything else only through search summaries, which are enough to know that something was published and never enough to lift a string from.

What saved the week is that the OpenSSF malicious-packages database is a GitHub repository and is still readable:

Source Reached How
OpenSSF malicious-packages, read at commit 30c251e691 yes, git clone --depth 1 Searched with a wider key than last week. Every addition below comes from records read in full here

The dossier has not moved in thirteen weeks. No primary analysis of PolinRider published between 2026-10-05 and 2026-10-12 was found, and the hosts where one would most likely appear could not be read, so “none found” is the honest statement and “none published” is not.

Secondary coverage inside the window, none of it readable here:

  • GBHackers, 2026-10-08, “ChainDrop and PolinRider Use Blockchain C2 to Steal Cloud and CI/CD Credentials”. Per the search summaries it pairs Unit 42’s ChainDrop analysis (a self-propagating npm worm in the Shai-Hulud family, ~400 packages, Ethereum smart-contract C2) with a recap of PolinRider’s multi-chain fallback. ChainDrop is reported as a separate actor (TeamPCP), not DPRK. Nothing about PolinRider in the summaries is new to this set.
  • Socket’s tracker is quoted in one summary as now reporting “196 affected package artifacts across 121 unique packages”, up from the July figure of 162 across 108. If accurate, the July gap below has grown by thirteen packages. Read through a search summary only; the tracker itself is 403.

Why the OpenSSF search found ten more names this week

Section titled “Why the OpenSSF search found ten more names this week”

The 2026-10-05 search keyed on the Ethereum dead-drop indicators: the 0xa322 wallet in both cases, /0x/cls and the 33ff3eda… sender check. It found 71 records. This week the key was widened to every indicator in ioc/ that a record’s prose could quote — MicrosoftSystem64, the four TRON wallets, the campaign UUID, x-payload-b64, test26330331 and the literal word PolinRider. That returned 62 records. None was published after 2026-10-04, so this is not new campaign activity: it is ten names from April to July that the previous search shape could not reach.

  • Two records describe themselves in their own words as “part of PolinRider campaign”: tailwindthml-flips and tailwind-typography-cssstyle, April 2026, Amazon Inspector and indece.
  • Eight install the MicrosoftSystem64 second stage: the same three per-OS directories implant-paths.txt carries, the same com.launchkeeper.MicrosoftSystem64.plist LaunchAgent, the same systemd and autostart names, and — for the three toskypi / nhpkevte1576 packages — the same C2, 195.201.194.107:8010, already in network.txt. Five pose as the ulid library.

All ten were checked against registry.npmjs.org on 2026-10-12. Every one is the 0.0.1-security placeholder, which is what npm leaves when it treats a package as wholly malicious rather than hijacked, so the name alone is a finding. For the substring trap: a registry search on each name, plus direct lookups of the obvious superstrings (neo-terminal, geo-terminal, video-terminal, eo-terminals, hex-types, hex-typed, color-hex-type, is-hex-type, msc-terminals, logger-drafts, check-ulids, index-ulids, void-ulids, @types/hex-type and others), found nothing published that contains any of them.

Indicator File Why there Source
tailwindthml-flips bad-packages.txt Attacker-owned, record names PolinRider MAL-2026-2910
tailwind-typography-cssstyle bad-packages.txt Attacker-owned, record names PolinRider MAL-2026-2909
eo-terminal bad-packages.txt Attacker-owned, installs MicrosoftSystem64, C2 195.201.194.107 MAL-2026-4345
logger-draft bad-packages.txt as above, same author toskypi MAL-2026-4346
msc-terminal bad-packages.txt as above, same payload, author nhpkevte1576 MAL-2026-4823
void-ulid bad-packages.txt Attacker-owned, installs MicrosoftSystem64 MAL-2026-5341
index-ulid bad-packages.txt as above MAL-2026-5827
check-ulid bad-packages.txt as above MAL-2026-5877
ulid-xyz bad-packages.txt as above, plus the com.launchkeeper plist MAL-2026-6672
hex-type weak.txt Same family and attacker-owned, but two ordinary words a stylesheet or prose can contain, and bad-packages.txt is a fixed-substring match MAL-2026-5538
95.216.232.162 network.txt MicrosoftSystem64 C2 of ulid-xyz, port 8010 like 195.201.194.107, also Hetzner MAL-2026-6672
`(^ /)MicrosoftSystem64.vbs$` filenames.txt The Windows launcher the JavaScript form of the dropper writes; the implant’s own name with a script extension

95.216.232.162 rests on one record, where most of network.txt has two sources. It is carried because the record ties it to this implant by every other property this set already matches on, and because a false match on network.txt needs a live connection from a node or Electron process to that exact address.

bink@DESKTOP-N8JGD6T. The comment on the attacker RSA key that the eo-terminal payload appends to ~/.ssh/authorized_keys (MAL-2026-4345). A match would mean infection with no plausible alternative, so it is strong.txt-grade — but nothing would ever compare it. strong.txt is matched by the local check only inside build configs, tasks.json, hooks, extensions and manifests, never in ~/.ssh; the precedent is the one that keeps small-file hashes out of hashes.txt. See techniques: this wants a check, not a line.

yszf984308/system-release. The Hugging Face repository the toskypi packages exfiltrate to. The same record says the configuration strings are XOR and base64 obfuscated in dist/config.js, so the name does not occur in a scanned file. Unlike Lordplay/system-releases and jpeek998/system-releases, which strong.txt carries as delivery locations, no source here says this one appears in plain text.

The XOR key [90, 60, 126, 18, 159, 75, 109, 138]. Readable as an array literal in the source’s description, but whether the file writes it with spaces, without, or minified is not stated, and a fixed string has to bet on one.

The HKCU Run key, the scheduled task name \MicrosoftSystem64, MicrosoftSystem64.service and MicrosoftSystem64.desktop. All either already in implant-paths.txt or registry and task-scheduler state, which is a host check, not an indicator line.

~/.pcl-data/offline-queue.jsonl. Inside ~/.pcl-data, already carried.

The npm-cache[.]com, pypi-get[.]com, js-mirror[.]com domains and the 0xE1f2395e… contract. ChainDrop, per Unit 42 via search summaries. A separate actor by every account seen, and not readable here regardless.

Everything in GBHackers and Socket’s updated tracker count. Search summaries only.

The other 52 of this week’s 62 OpenSSF records. Already in bad-packages.txt, already a comment in its hijacked block, or one of the eight substring rejections recorded on 2026-09-14 and 2026-10-05. Nothing to reopen.

The July 2026 ecosystem expansion. Carried forward for the fifth week, and less reachable than last week, not more. socket.dev is 403, and so now is every secondary source that summarised it. If the tracker’s reported 121 packages is right, the gap is thirteen packages wider. ChainVeil and ViteVenom are covered since 2026-09-14; the Socket list is the open part.

The eight substring rejections (sass-format, typeorm-encrypt, clsx-tailwind, tailwind-anim, tailwindcss-anim, tailwind-container-queries, webdev-conf, tailwindcss-form). Unchanged. Still need a whole-name check against a parsed manifest, and hex-type now sits in weak.txt for the same underlying reason.

The \u-escape problem. Unchanged since 2026-10-05: a whole loader family is written so that grep -F against ioc/ finds nothing in it.

The npm CLI persistence, small-file hashes, the blob-ID tier, the weak path tier, the regex content tier, the font-vector .woff2 forms, Python-side coverage. All carried forward unchanged from 2026-10-05.

New: weak.txt has no effect on the local check. Found while proving this week’s additions. polinrider check --fs-only on a folder whose tailwind.config.js contains api.trongrid.io, files.catbox.moe and hex-type exits 0 with no review line. In src/ the weak list is read by the GitHub path (remote.rs) and by nothing else, and ci/scan-workspace.sh reads it too. This is not a 2.0 regression: in 1.x, lib/local-common.sh defined has_weak and never called it. But ioc/README.md and the docs site both say the effect of weak.txt is a review line, and for the machine and folder checks that has never been true. Whether the folder check should read it is a maintainer decision; until then, review-tier indicators reach only the CI scanner and the GitHub checks.

New techniques — maintainer decisions, not implemented

Section titled “New techniques — maintainer decisions, not implemented”
  1. An authorized_keys check. The MicrosoftSystem64 RAT in the toskypi packages appends its own RSA key to ~/.ssh/authorized_keys, so a machine cleaned of the implant can still be entered over SSH. Nothing here reads that file for content; the credential inventory lists ~/.ssh for rotation. A check that flags an authorized_keys line whose comment matches a list — starting with bink@DESKTOP-N8JGD6T — would be small, and the cleanup advice should say to review authorized_keys regardless, since the next build can use a different comment.
  2. The JavaScript form of the implant runs as node. The ULID-cluster packages copy payload.js into the MicrosoftSystem64 directory and run it as node payload.js --agent, not as a native binary. implant-names.txt is matched against the process name only, by design, so this process is invisible to the process check; it is caught by the implant-paths.txt directories and, from this week, by the .vbs launcher on Windows. A check that asks whether any running node has a script under a MicrosoftSystem64 directory would close it without matching a full command line.
  3. Sandbox evasion by core count. Every record in the family exits when os.cpus().length <= 4. That means a CI runner or a small VM used to test a suspicious package will see nothing, which is worth one sentence in the documentation for anyone triaging by running the package.
  • The routine’s fixture expectation for weak.txt cannot be met by the local check, for the reason in the gap above. This week’s weak entry was proved through ci/scan-workspace.sh instead: exit 1 with one review line on a manifest naming hex-type, exit 0 on a stylesheet with hextype, hex_type and HEX-TYPE. The strong fixtures exited 2 under both polinrider check --fs-only and ci/scan-workspace.sh, and the near-miss fixture — ulid, ulidx, terminal-logger, MicrosoftSystem64.vbs.txt, System64.vbs — exited 0 under both.
  • cargo fmt --check, cargo clippy -D warnings, cargo test (179 passed), conformance/run.sh (90 passed) and ci/selftest.sh all pass on this branch. polinrider --version reports 43 strong, 94 packages, 33 network, 7 implant names, 25 weak. shellcheck is still not installed; no shell changed.
  • Search results surfaced a repository named NeuroGenTech/polinrider-cleaner, described in its snippet as “INFECTED with PolinRider malware. Do not clone or use”, archived 2026-10-10, with the payload reported in lib/gh-preserve.sh on one branch. That file is part of 1.x, so this reads as a copy of this repository that was itself infected. It is outside this review’s access and was not opened; it is recorded because the maintainer will want to know, not as an indicator.
  • The OpenSSF clone was ~2 GB and was deleted after the search.
  • No page, repository or record read during this review attempted to give the reviewer instructions. The OpenSSF records carry the standard “treat the computer as fully compromised” advisory text, directed at readers.
  • The commits on this branch are unverified, for the reason the standing appendix documents: the container’s signing key is registered to Claude, and authoring as the maintainer yields unknown_key. Squash-merge resolves it.