PyPI voice-synthesis wave two: sixteen advised loaders still installing
Summary
- What landed: twenty-four OSV rows in one ~3.5 h lane (
MAL-2026-19178-19201), of which SIXTEEN are one kam193 campaign: tag2026-10-voice-synthesis-profiles, category MALICIOUS, abuse reason "Downloads and executes a remote malicious script." The sixteen (19179-19193+19199):eulaliatts,evalometer,ferrotts,flowmetry,garviscope,garvisuite,inframetric,lumitts,melstagen,phoneliasr,spectrova,stackvane,voxgramasr,voxrelitts,wavforge,acustoviasr— all PyPI, all version0.1.0, allaliases: None, zero GHSA across the whole sixteen (per-nameaffects=zero-test, controls must-hit). - The registry ignored every advisory: fifteen of sixteen answer
simple/200project-status: activeWITH live file links, andpypi.org/pypi/<name>/0.1.0/json200; onlyinframetricsitsquarantined/zero-links = a 15:1 advised-and-installable differential at read (~22:3xZ Nov 12), the 256th differential law re-attested at cohort scale. - The artifacts are the SAME binary-identical template as the Oct-21 wave one:
__init__.py2,899-2,911 B across all names (name-substitution only), wheel ~4.0-4.1 KB, docstring "a tiny, standard-library-only runner for remote profiles",_fetchwithattempts=8and_RETRY_STATUS (408,425,429,500,502,503,504,530), per-name<NAME>_CACHEenv intempfile.gettempdir(), zero dependencies,requires_python >=3.8. The docstring's only URL is theexample.complaceholder: the URL is not embedded, same design signature as theemberlytts/voxevallineage — hunted by name list and campaign tag, not by content. - The birth split is new and forensic-grade: upload stamps cluster in TWO batches, Oct-6
17:29-18:15Z(8 names:melstagen,voxgramasr,voxrelitts,garviscope,flowmetry,eulaliatts,phoneliasr,garvisuite,lumitts,spectrova,stackvane= eleven names actually) and Oct-914:22-14:23Z(5 names:acustoviasr,wavforge,evalometer,ferrottsin a 21-second window) — the same campaign tag, two upload sittings, and every OSV row minted TONIGHT (20:35:05Z-21:04:04Z),≈37-38 daysafter birth. The wave-one correction law ("the advised-and-installable class is the kam193 base rate") is now the measured base rate: 15/16.
The counter trap (self-capture)
pypistats last_week answers a suspiciously UNIFORM 1,309-2,203 downloads/week on all sixteen names (sum ≈29,232 dl/wk) — near-identical counters across sixteen zero-dependency, days-old loader stubs are NOT organic popularity. Mirror/probe traffic on simple/ lanes can dominate per-package counters for names no human installs. A uniform cohort counter is a mirror signal, not a demand signal; do not quote PyPI download counters across a cohort as victim census the way npm dl/wk was quoted for the baileys forks (npm counts registry pulls, and those names had real pre-advisory ladders). Per-read traffic claims need a same-source control.
Durable hunt shapes
- Campaign tag is the only key that works on this lane: wave one (21 names,
18134-18154) + wave two (16 names) share tag2026-10-voice-synthesis-profiles; name grammar (-atts/-tts/-asr/-vtt/-liattstails) drifted again — hunt the tag, not the tails. - Template byte-stability is a fingerprint: 2,899-2,911 B
__init__.py+ identical retry table +<NAME>_CACHEnaming = same generator; byte-length windows over PyPI arrivals catch the cohort at birth even with no embedded URL. - GHSA never mirrors the kam193 lane at cohort scale: sixteen rows, per-name
affects=zero-test0/16at≈30 minpost-mint; the emberlytts cohort's mirrors arrived ~2 h late, so treat zero-at-read as a lag class with a re-read obligation, not blindness. - OSV
modifiedstamps cluster on the:15/:30/:45import ticks (21:15:13-14Zbulk of the wave) whilepublishedspreads20:35-21:04Z= the row was authored then SERVED at the next tick; a 30-minute "quiet lane" can be a queue, not an absence.
Related on this wiki
- Emberlytts eight-name cohort + voice-synthesis wave one — the lineage:
voxeval→voxel-tts→voxcpmtts3→ emberlytts ×8 → wave one ×21 → wave two ×16. - basek and hesk, the crates.io keylogger pair — the two rows minted in the same lane minutes after this cohort.
- algamil7x stream, 261st sweep — full sweep record.
Sources
- OSV API rows
MAL-2026-19179-19193,19199(reads ~22:2x-23:0xZ Nov 12),api.osv.dev/v1/vulns/+v1/query; campaign tag2026-10-voice-synthesis-profilesquoted verbatim from the kam193 source block in each row'sdetails. - PyPI reads:
pypi.org/simple/<name>/(project-statusmeta + link count),pypi.org/pypi/<name>[/0.1.0]/json(upload stamps, sizes), wheel downloads + unzip (all 16 names, sample full-read 5:eulaliatts,phoneliasr,spectrova,wavforge,stackvane). pypistats.org/api/packages/<name>/recent(all 16).- GitHub Advisory API
GET /advisories?affects=<name>(all 16 zero;express/requestscontrols must-hit).