SecureNexus GRC
SECURENEXUS
  • Home
  • Blog
  • Case Studies
  • About
Get Started
SecureNexus GRCSECURENEXUS

Empowering digital organizations with unified security — through connected insights, trusted expertise, and end-to-end coverage.

A venture of

X-Biz TechVentureswww.xbizventures.com

Services

  • Regulatory Consulting
  • Red Teaming
  • Cloud Security
  • Security Operations
  • Security Training
  • Product Advisory

Products

  • Perimeter (CTEM)
  • Cloud Security Posture Management
  • Vulnerability Management
  • SOVA (SCA)
  • Third Party Risk Management

Company

  • About Us
  • Contact
  • Blog
  • Case Studies

Resources

  • Security Assessment
  • Breach Probability

Contact

[email protected]
+91 1800-266-8575

Certifications & Compliance

Certifications and Empanelment — D.U.N.S Registered, ISO 9001:2015, BQC, IAF, ISO 27001, Nasscom, ESC, CERT-IN Empanelled
Offices

Mumbai (HQ)

118-120 IJMIMA Complex, Mindspace, Malad West, Mumbai 400064

Pune (GCC)

Unit 2-B, 1st Floor, Cerebrum IT Park, Kalyani Nagar, Pune 411014

Mumbai (Tech & Innovation)

315, 3rd Floor, Lodha Supremus, Andheri East, Mumbai 400069

Dubai

M35, Warba Centre, Al Muraqqabat, Deira, Dubai

X-Biz TechVentures

© 2026 X-Biz TechVentures Pvt. Ltd. All rights reserved.

HomeBlogTrust hijacked: how attackers forked legitimate Mini Shai-Hulud detection tools to ship the worm itself
Security
Share

Trust hijacked: how attackers forked legitimate Mini Shai-Hulud detection tools to ship the worm itself

Mohit Kumar
2026-05-03
12 min read
Supply Chain Attack
Threat Intelligence
Mini Shai-Hulud
Trojan.Lazy
GitHub
Malware Analysis
LuaJIT
SOVA
DevSecOps
Incident Response
Trust hijacked — Mini Shai-Hulud fake-detector campaign read by SOVA

A single operator runs four burner GitHub accounts publishing fake Shai-Hulud detection tools that actually deliver a Windows credential-stealer kit (LuaJIT + obfuscated Lua, Mini Shai-Hulud / Trojan.Lazy family). SecureNexus SOVA detected the cluster on 2026-05-02 via capability-shift scanning. This writeup covers the four trust signals the lure exploits, byte-identical kit binaries across operator accounts, leaked operator emails, the 7-byte PEB-walk shellcode captured by our instrumented sandbox, the 37-victim census, and structural-fingerprint guidance defenders can deploy today.

Quick context for non-specialists: Shai-Hulud is the name a class of self-spreading malware acquired in late 2025, originally on the npm JavaScript registry. When an infected package is installed, it harvests the developer's credentials (cloud keys, GitHub tokens, SSH keys), uploads them to a public repository it creates on the developer's own GitHub account, and uses those harvested credentials to publish the same malware into other packages the developer has access to. Each victim becomes a new infection vector. The campaign in this post is a follow-on operation by the same family ("Mini Shai-Hulud" / Trojan.Lazy), but instead of poisoning a real package the attackers built fake "Shai-Hulud detector" tools on GitHub and wait for security-conscious users to download them voluntarily. If you're short on time, skip to the Am I affected? table below.

TL;DR

A single operator runs four burner GitHub accounts that publish fake "Shai-Hulud detection tools" — repositories disguised as community responses to the npm Shai-Hulud worm, but actually hosting a Windows credential-stealer kit. They've also branched into game-cheat and "cloud utility" lures targeting non-developer victim pools. The kit is a LuaJIT + obfuscated Lua infostealer in the Mini Shai-Hulud / `Trojan.Lazy` family — same family that hit the npm `@cap-js/*` packages and the PyPI `lightning` package in late April. SOVA detected the cluster via a capability-shift scan on 2026-05-02; we have the malicious tarballs in quarantine, sandbox traces, and operator emails.

A few things worth flagging up front:

  1. Two of the four operator burner accounts leak real Gmail addresses as their git commit-author identity (`[email protected]`, `[email protected]`). That's the closest thing to direct attribution any researcher has gotten on this campaign so far.
  2. The kit binaries are byte-identical across multiple operator accounts. Specifically `luajit.exe` + `lua51.dll` + `Launcher.cmd` are the same SHA-256 across `eliezerfrn` and `nigerbartus`, separated only by the per-victim obfuscated payload. That's cryptographic proof of single-operator multi-account attribution.
  3. The first thing the malware does is allocate 7 bytes of `PAGE_EXECUTE_READWRITE` memory and JMP into it. That's not "suspicious" — that's textbook shellcode staging. We captured the bytes: `64 A1 30 00 00 00 C3` — the canonical Windows x86 PEB-pointer read.
  4. The campaign is industrial-scale. Public sandbox-correlation pivots link the same kit to ≥109 sibling lure ZIPs distributed Feb-May 2026 across game cheats, content-automation tools, fake IDE installers, and pirated browser extensions. The "Shai-Hulud detector" theme is the latest skin.
  5. All six malicious repos have been reported to GitHub Trust & Safety with full hash evidence, fork-vs-upstream proof, and cross-account attribution. Reports filed 2026-05-03; takedown response pending.

The rest of this post is the forensic detail to defend every line above.

How SOVA caught it

SecureNexus SOVA is a continuous software supply-chain-intelligence platform. Day to day, it does the conventional SCA work — tracking dependency graphs, scoring maintainer risk, ingesting CVE / GHSA / OSV feeds, watching new releases on npm / PyPI / Maven / NuGet / Crates.io / RubyGems / Packagist / Go / Docker / VS Code Marketplace / browser extension stores, and emitting block / warn verdicts the moment a package version goes risky.

Loading image…
SOVA's live signal stream catches all six fork-and-poison repos within seconds — 24 alerts out of 2.8M events processed.
SOVA's live signal stream catches all six fork-and-poison repos within seconds — 24 alerts out of 2.8M events processed.

Sitting on top of that day-job is the part that found this campaign: SOVA Intelligence campaigns. A campaign is a focused, time-boxed hunt that takes a published advisory or threat-intel cue and proactively sweeps adjacent attack surfaces for follow-on activity. When the npm Shai-Hulud incidents broke (Bitwarden CLI, the `@cap-js/` family, `mbt`) and the PyPI `lightning` 2.6.2/2.6.3 compromise followed days later, our analysts opened a Mini-Shai-Hulud campaign — "the worm has multiple ingress channels; what else is the same operator pushing?"*

The campaign chained three SOVA capabilities:

  1. Capability-shift scanner. The reusable signal engine — looks for repos / packages where the latest revision newly introduces install-time hooks, network + shell capabilities, embedded binaries, or other suspicious shape changes vs. their prior state. For this campaign we pointed it at GitHub instead of npm/PyPI, with three deterministic signals tuned for the lure pattern: - Embedded binary in a subdirectory (≥ 50 KB, common archive extension) — legit security tools don't ship installers from inside their repo tree. - README contains direct hyperlinks to that binary — the lure mechanism. - Repo is a fork AND the same path returns HTTP 404 on upstream — the fork-and-poison smoking gun.
  2. Maintainer-risk + account-fingerprint engine. SOVA continuously scores every maintainer / publishing identity it sees. For the GitHub accounts that surfaced from step 1, the engine flagged: zero followers, zero following, no bio / name / email, fresh activation in a tight window — the classic burner-account fingerprint. That promoted three forks-with-binary from "suspicious" to "almost certainly part of a coordinated cluster."
  3. Threat-intel correlation against the active campaign feed. SOVA cross-references hits against public threat-intel feeds, sandbox correlation graphs, and our own internal IOC database. The structural fingerprint of the lure ZIPs (Variant A 547–588 KB, Variant B 1.39 MB; `start .exe .txt` launcher; LuaJIT 2.1.0-beta3 inner binary; obfuscator.io-style Lua payload) matched the same Mini Shai-Hulud / Trojan.Lazy family that hit the npm and PyPI ecosystems days earlier. That cross-incident match converted "suspicious cluster" into "confirmed campaign continuation."
Loading image…
Per-package drilldown: AI verdict BLOCK, four stacked findings, and the kit's 7-file payload itemised.
Per-package drilldown: AI verdict BLOCK, four stacked findings, and the kit's 7-file payload itemised.

Once flagged, the campaign workflow ran each repo through deeper forensics:

  • Upstream-404 verification — confirmed the binary is unique to the fork (4/6 repos)
  • Hash + structural analysis of the embedded ZIPs against our known-kit signatures (Variant A 547–588 KB, Variant B 1.39 MB)
  • Static analysis of the renamed `luajit.exe` (PE parsing, export table, banner string verification)
  • Instrumented Docker sandbox of the obfuscated Lua payload (with the harness and watchdog described above) — captured the `ffi.cdef`, `VirtualAlloc(7, RWX)`, the 7-byte shellcode bytes, and 17 events of stage-1 trace
  • Cross-repo hash comparison — surfaced the byte-identical `luajit.exe` + `lua51.dll` + `Launcher.cmd` between `eliezerfrn` and `nigerbartus`
  • Git log forensics — surfaced the operator email leaks
  • Public sandbox pivot — confirmed 35+ vendor consensus on `Trojan.Lazy` family attribution

All findings are persisted as first-class SOVA records: 35 IOC entries in `sova.threat_iocs` (campaign tag `mini-shai-hulud-2026`), 6 package records in `sova.enriched_metadata` (ecosystem `github`) with `verdict: block` and full meta_findings, plus the 37 victim-account census from the follow-on sweep. They render in the SOVA dashboard's Packages and Threat Intel views immediately, and the same campaign telemetry is what feeds the policy-engine guidance in the recommendations table above. The campaign stays open: any new repo or maintainer matching the operator-cluster fingerprint will be auto-flagged and tied back to this same `mini-shai-hulud-2026` thread.

Why this works — the four trust signals the lure exploits

Before the technical detail, here is why a careful engineer falls for it. The lure isn't crude. It exploits four layered trust signals — each one of which a security professional has been trained to trust.

Trust signal #1 — The legitimate upstream's reputation

The malicious repo is a fork of a real open-source security tool, e.g. `miccy/dont-be-shy-hulud` (since renamed to `miccy/wormsCTRL`), `gensecaihq/Shai-Hulud-2.0-Detector`, or `ysskrishna/shai-hulud-detector`. These are all real projects by real people (Miccy is a Czech developer with a 2014-vintage GitHub account; GenSecAI is a registered Indian non-profit with 124 stars on this specific tool; Siva Sai is an IIT Madras alumnus who publishes on PyPI under his real name). Each of these projects has star history, named contributors, MIT licenses, real release pipelines, and homepage URLs that resolve to working products. The fork inherits all of that visible reputation. To a casual reviewer, the fork looks like someone running their own copy of a legit tool. Forking is a normal, legitimate developer activity — there's no warning signal in the act of forking itself.

Trust signal #2 — GitHub itself as a platform

The download URL is `github.com///raw/refs/heads/main/...`. That's not a sketchy file-sharing site. That's GitHub, the trusted source-control platform that the engineer's company explicitly allowlists in their proxy. Egress filters that block "downloads from random-looking domains" don't fire on GitHub. Browser SmartScreen warnings don't fire. EDR's URL reputation engines see "GitHub.com" and rate it Low Risk.

Trust signal #3 — Familiar README anatomy

The README is generated by an LLM trained on hundreds of thousands of real README.md files. It has every shape that a legitimate open-source project has:

  • 🛡️ Emoji shields and badges (just like real security projects use)
  • A clear "Getting Started" structure with numbered steps
  • A "System Requirements" section listing OS support
  • A "Features" bullet list
  • A "Download" green button image, linked to the embedded zip
  • A "Releases page" hyperlink (also linked to the embedded zip)
  • A "Run the Application" section with platform-specific instructions
  • License, CHANGELOG, SECURITY.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md

A reader pattern-matches on these structural elements and concludes "this is a legitimate project." They don't have to read every line; they just have to recognize the shape. The lure exploits that.

Trust signal #4 — Search engine relevance

The malicious repos are named exactly what someone Googling for a Shai-Hulud detector would search: `shai-hulud-detector`, `Shai-Hulud-2.0-Detector`, `dont-be-shy-hulud`, `sha1-hulud-scanner`. They get indexed by Google, ranked by GitHub Search, and surface in the top-10 results for the exact query a panicked engineer types into Google when an alert fires.

When all four signals align, even a careful engineer downloads. The lure was built for someone exactly like them.

Am I affected? (60-second triage)

If any of the following is true for anyone in your organization in the last 7 days, treat as a likely compromise:

If…Then…
A developer or security researcher Googled "shai-hulud detector" / "shai hulud scanner" / similar, clicked a GitHub link, and downloaded a `.zip` file they then unzipped and double-clickedTreat that machine as compromised. Rotate every credential the user touched in the last 7 days.
A CI/CD pipeline (GitHub Actions, GitLab CI, CircleCI, Buildkite) ran `npm install`, `pip install`, or `git clone` of any package created or updated 2026-04-25 → 2026-05-03 without explicit pinningTreat the runner as compromised. Rotate the runner's `GITHUB_TOKEN`, AWS keys, npm tokens, and any environment-injected secrets.
Anyone on your team owns a personal GitHub account and you have not yet swept their account for new repos in the last 7 daysSweep now. Look for repos matching the regex `^[a-z]+-[a-z]+-\d{1,4}$` (e.g. `fremen-sandworm-700`, `tleilaxu-navigator-504`). Each match = a confirmed credential-exfil drop.
Your org runs a developer machine that has installed Bun, LuaJIT, or any binary called `java.exe` from a non-official source recentlyAudit that machine. The malware ships these as renamed runtimes.
Your org's GitHub Audit Log shows new public repository creations from accounts that don't normally publish public reposHigh-confidence compromise indicator. The malware's exfil channel uses victim accounts to create public repos.

If "yes" to any of those, jump to the Recommended actions section below.

The lure

Search GitHub for "shai-hulud" today and the top of the results page is a mix of legitimate detection tools, and forks of those tools by users with zero followers, zero following, no name, no bio — and a `.zip` file buried four directories deep in the repo.

These repos look like this:

Code
README.md   ←  emoji-shield "🛡️ Getting Started" guide
              with 3-9 hyperlinks all pointing at /the-zip
.gitignore
LICENSE
apps/docs/src/components/override-components/TableOfContents/be-hulud-dont-shy-v3.4.zip
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the malware kit

The repo's README is a syntactically valid markdown "Getting Started" walkthrough that Google can index, that AI assistants can summarize, and that a tired developer at 5pm on a Friday will skim and trust. It contains a "Download" button graphic, multiple "Visit the Releases page" links, step-by-step Windows / macOS / Linux install instructions — all of which point to the same hidden `.zip`.

In one of the four cases (`nigerbartus/Shai-Hulud-2.0-Detector`), the README is partially broken LLM-spam. The "Prerequisites" section literally reads:

“"If you haven't already, install [malicious-zip-URL] from [malicious-zip-URL]. This application requires [malicious-zip-URL] to run."”

— where placeholder text for "Node.js" was replaced by a script with the malicious zip URL. The README is asking the user to download and run the malware as a "runtime dependency" of itself.

When the user double-clicks the launcher inside the unzipped directory, a renamed LuaJIT interpreter executes an obfuscated Lua payload, which begins ~30 seconds of stealth pre-flight (hide window → host fingerprint → PEB walk → screenshot pipeline → credential harvest → encrypted exfil to a freshly-created public GitHub repo on the victim's own account).

The four operator accounts

We've confirmed four GitHub accounts in this cluster. None has any social signal:

AccountCreatedActivatedReposFollowersBioEmail exposed
`eliezerfrn` (https://github.com/eliezerfrn)2022-08-032025-08-072 malicious + 1 fork (cover)0—privacy-masked
`nigerbartus` (https://github.com/nigerbartus)2024-01-092025-08-081 malicious0—privacy-masked
`ArcaneMisery095` (https://github.com/ArcaneMisery095)2025-03-182025-08-082 malicious0—`[email protected]`
`vitor2342` (https://github.com/vitor2342)2025-05-012025-08-101 malicious0—`[email protected]`

Three things make this a single-operator cluster, not four independent attackers:

  1. All four were activated in a 4-day window (2025-08-07 → 2025-08-10) despite their accounts having been created up to three years apart. Coordinated activation script or burner-broker purchase.
  2. Byte-identical kit binaries between `eliezerfrn` and `nigerbartus`. The two accounts share `luajit.exe` SHA-256 `5343326f…3953`, `lua51.dll` SHA-256 `c7a657af…71ac`, and `Launcher.cmd` SHA-256 `964dfb63…1d13`. Only the per-drop obfuscated payload differs. There is no plausible non-collusion explanation for three byte-identical files on two different attacker accounts' repos — these are compiled from the same source with the same toolchain.
  3. The two leaked Gmail addresses point at real email accounts that an OPSEC-aware operator would not have used. They are the strongest direct attribution lead in this campaign.

`eliezerfrn` also has a single fork of `rafaballerini/GitTutorial` (a real Brazilian Git tutorial repo) — innocent activity used as cover to make the burner profile look organic. We see this pattern repeatedly in coordinated MaaS account-broker drops: one or two innocent forks alongside the campaign payload.

The six malicious repositories

RepoLure themeBranchZipsMalicious zip path
`eliezerfrn/dont-be-shy-hulud`"Shai-Hulud detection tool" (fork-and-poison of `miccy/dont-be-shy-hulud`)`main`2`/apps/docs/src/components/override-components/TableOfContents/be-hulud-dont-shy-v3.4.zip` + `/apps/docs/src/content/dont-be-shy-hulud_2.5.zip`
`eliezerfrn/cataclismo-rogue-tools`game-cheat / mod toolkit ("Cataclismo Enhancement Toolkit")`branch`2`/attractability/cataclismo_rogue_tools_3.4.zip` + `/attractability/cataclismo-rogue-tools_v3.5.zip`
`nigerbartus/Shai-Hulud-2.0-Detector`fork-and-poison of `gensecaihq/Shai-Hulud-2.0-Detector``main`1`/dist/Shai-Hulud-2.0-Detector_v3.5.zip`
`ArcaneMisery095/shai-hulud-detector`fork-and-poison of `ysskrishna/shai-hulud-detector``main`1`/media/shai_detector_hulud_3.3.zip`
`ArcaneMisery095/CM-cloud`"cloud utility" stub (10-byte README, no on-repo lure)`main`2`/arithmetization/CM-cloud_3.7.zip` + `/arithmetization/cloud-C-protonymphal.zip`
`vitor2342/sha1-hulud-scanner`original (not a fork), poses as a SHA1-HULUD bash scanner`main`1`/Rousseauite/hulud-scanner-sha-v2.6.zip`

A few details worth flagging here:

The "fork-vs-upstream HTTP-404 test" is the single highest-precision detection signal we have. For each fork, we issued a HEAD request against the same path on the legitimate upstream:

Code
fork:     HTTP 200 (zip exists)
upstream: HTTP 404 (zip does not exist)
=> the binary was inserted by the fork — fork-and-poison confirmed

That signal fires only on intentional poison. A legitimate user fork of a tool would either match the upstream or have local development changes — neither produces "binary at deep path absent in upstream."

The default branch name `branch` on `eliezerfrn/cataclismo-rogue-tools` is an operator fingerprint. Default branches are normally `main` or `master`. Our scanner caught it because we explicitly retried the tree fetch with the discovered default; a YARA-style detection that hardcodes `main`/`master` paths would miss this. Future operator drops likely repeat this typo.

The six repos host nine distinct malicious ZIPs — each ZIP has a different SHA-256 (the operator rebuilds per drop to defeat hash-based detection). But the size class is invariant: every Variant-A ZIP is 547–588 KB, every Variant-B ZIP is exactly 1,386,736 or 1,394,413 bytes. The size is the structural fingerprint, not the hash. A defender can YARA on size-class + structural shape and catch every variant.

Inside the kit

Each ZIP unpacks to one of two kit shapes:

Variant A (3 files, ~580 KB total, observed Feb 2026):

Code
luajit.exe   PE32+ x64 LuaJIT 2.1.0-beta3 (rebuilt per drop, fresh hash each)
<random>.txt 300-310 KB obfuscated Lua, single-line, 65,536 chars per line, no LF
<launcher>.cmd|.bat  23-43 bytes:  start <runtime>.exe <payload>.txt

Variant B (4 files, ~1.39 MB total, observed Dec 2025):

Code
luajit.exe   PE32+ x64 LuaJIT — ~99 KB stub
lua51.dll    PE32+ x64 DLL    — ~3.4 MB (Lua 5.1 + extras, statically linked)
clib.txt     ~340-355 KB obfuscated Lua
Launcher.cmd 43 bytes: `start luajit.exe clib.txt`

Variant B drops the standalone `lua51.dll`; Variant A removed it. Same operator, evolved tooling.

Across every variant, the launcher reduces to one shell line:

Code
start <runtime>.exe <payload>.txt

That's the operator's universal bootloader pattern. Filenames rotate (`java.exe`, `luajit.exe`, `init.exe`, `genlibbc.txt`, `clib.txt`, `static.txt`, `icon.txt`) but the structural shape doesn't. Detection rule: any `.cmd`/`.bat` of fewer than 64 bytes whose contents reduce to that exact 4-token pattern is malware-class.

What `java.exe` is

It's a verbatim stock LuaJIT 2.1.0-beta3 Windows x64, just renamed. The operator did not modify the runtime — they downloaded the reference compile from `luajit.org`, gave it an innocuous filename, and bundled it. The export table self-identifies as `luajit.exe`. The version banner string is the upstream copyright. There's no embedded shellcode, no overlay, no PDB path leak, no packer.

This means the malware uses legitimate, unsigned-but-recognizable runtime code. EDR systems that trust binary signatures or whitelist by hash will likely let `java.exe` through — it's bit-for-bit a published open-source release. The malice lives entirely in the `.txt` file the launcher passes as the script argument.

What the obfuscated Lua does

The Lua payload is Prometheus-style obfuscation:

Code
return(function(...)
  return(function(u,i,K,U,s,j,I,z,l,B,p,P,r,A,O,h,k,g,Q,x,b,Y,c,o)
    O,c,r,Y,g,b,p,k,o,x,h,l,A,P,B,Q,z = function() ... end,
    ...
  • 24-letter argument list captures every Lua stdlib function under single-letter aliases
  • 591 `end` tokens, 555 `then`, 194 `..` (string-concat), 30 `function` declarations
  • A bootstrap finale that captures `getfenv`, `unpack`, `newproxy`, `setmetatable`, `getmetatable`, `select`, `_ENV` — every reflection primitive
  • Zero plaintext URLs, IPs, or syscall names — the obfuscator covers everything

We ran the payload through an instrumented LuaJIT sandbox in a hardened Docker container with `--network none --read-only --cap-drop=ALL --security-opt=no-new-privileges`. The harness intercepts every dangerous primitive (`ffi.cdef`, `ffi.load`, `ffi.cast`, `ffi.C.*`, `os.execute`, `io.open`, `io.popen`, `package.loadlib`, `loadstring`, `load`, `print`) and returns recording stubs. The watchdog uses captured-pristine `os.exit()` from outside the hooked namespace so `pcall` in the payload cannot catch a sandbox break.

The deobfuscator runs through 17 captured events before crashing on a stage-2 PEB dereference. Every event is the same byte-for-byte across all five payloads we ran — different attackers, different per-drop payload contents, identical control-flow trace through stage 1.

The 7-byte shellcode

Event 14 in our trace is a `VirtualAlloc` call:

Code
VirtualAlloc(addr=NULL, size=7, type=0x3000, protect=0x40)
                                       │            │
                            MEM_COMMIT |        PAGE_EXECUTE_READWRITE
                            MEM_RESERVE

7 bytes of read-write-execute memory. Not 4 KB. Not 64 KB. Seven. There is exactly one reason malware allocates 7 bytes of RWX: writing a tiny inline shellcode probe and JMPing into it.

Event 15 captured the bytes (via an `ffi.cast` hook that intercepts function-pointer casts and dumps the buffer contents before the CPU executes them):

Code
64 A1 30 00 00 00 C3
│  │              │
│  │              └── ret
│  └── opcode A1: mov eax, [imm32]
└──── prefix 64: FS segment override
                      └─ address 0x30

= mov eax, fs:[0x30]   ; read Windows x86 Process Environment Block pointer
  ret

This is the textbook shellcode for "obtain Windows PEB pointer". On Windows x86 (32-bit), `fs:[0x30]` is hardwired to the Process Environment Block address. From there the malware walks `PEB → PEB_LDR_DATA → LDR_DATA_TABLE_ENTRY` to enumerate loaded DLLs without ever calling `LoadLibrary` or `GetProcAddress` — the two API calls that EDR products hook most heavily. Once it has DLL bases it parses their PE export tables (`IMAGE_EXPORT_DIRECTORY`) directly to find addresses of `recv`, `send`, `CryptUnprotectData`, `CredEnumerateW`, etc.

The same 7 bytes appear byte-identical across all five payloads we tested — including across the two operator-account clusters and both kit generations. The PEB-walk routine is the operator's invariant. Defenders writing static-content rules can pivot on those 7 bytes inside any single-line obfuscated Lua payload — they're invariant across every Mini Shai-Hulud variant we've sandboxed.

What it intends to do (declared via FFI)

Even though the deobfuscator crashes on stage-2 dereference, the stage-1 `ffi.cdef` declared the malware's full Win32 capability surface. Every name below is a function the malware wired up to call:

CapabilityWhat's declared
Self-hide`GetConsoleWindow`, `ShowWindow`, `SW_HIDE`
Host fingerprint`GetComputerNameW`, `IsWow64Process`, `GetSystemMetrics`, `VerifyVersionInfoW`, `VerSetConditionMask`
Privilege probe`TOKEN_ELEVATION` typedef
PE parsing (manual DLL resolution)`IMAGE_DOS_HEADER`, `IMAGE_NT_HEADERS32/64`, `IMAGE_OPTIONAL_HEADER32/64`, `IMAGE_EXPORT_DIRECTORY`, `IMAGE_DATA_DIRECTORY`, `PEB`, `PEB_LDR_DATA`, `LDR_DATA_TABLE_ENTRY`, `UNICODE_STRING`
Memory ops`VirtualAlloc`, `VirtualFree`
Screenshot capture`GetDC`, `CreateCompatibleDC`, `CreateDIBSection`, `BitBlt`, `SelectObject`, `DeleteDC`, `DeleteObject`, `ReleaseDC`, `BITMAPFILEHEADER`, `BITMAPINFOHEADER`, `BITMAPINFO`
Filesystem staging`GetTempPathW`
Encoding`MultiByteToWideChar`, `WideCharToMultiByte`
Self-reference`ffi.load("lua51.dll")` for direct Lua C-API access

The screenshot pipeline (12 GDI functions in their canonical sequence) is unambiguous: the malware will capture the victim's desktop. Combined with the PEB-walk + RWX shellcode pattern, this is a credential-stealing, screenshot-grabbing, EDR-evading Windows trojan — not a misclassified utility.

For credentials, network, and exfiltration, we rely on cross-incident corroboration from the same family. The Mini Shai-Hulud kit hit the npm `@cap-js/*` packages and PyPI `lightning` 2.6.2/2.6.3 in late April 2026 — both compromises were dissected in detail at the time, and the harvest list is consistent across all observed victims: SSH keys, shell history, AWS/Azure/GCP cloud credentials, Kubernetes configs, Docker credentials, GitHub PATs, npm tokens, cryptocurrency wallets, VPN credentials, CI environment variables. Exfil happens by creating a public repo on the victim's own GitHub account with a Dune-themed random name (e.g. `fremen-sandworm-700`, `tleilaxu-navigator-504`) and committing the harvest as `results/results--N.json` with the structure `{"envelope": "", "key": ""}`. We have observed those victim repos directly on the GitHub accounts `haiweizhang1`, `16000rpm`, and `LuisDepo` — the operator's victim hit-rate is at least in the dozens.

Cross-campaign linkage

The same kit appears in at least 109 sibling lure ZIPs across multiple GitHub repos and download sites between February and May 2026, per public sandbox-correlation pivots on the inner-file hashes. Examples we've sampled:

DateFilenameLikely victim profile
2026-02-27`to-extension-trello-cracked-board-save-3.2.zip`productivity-tool pirates
2026-02-28`codewars_challenges_v3.2.zip`coding-challenge users / juniors
2026-03-15`elite_toolkit_r_siege_1.5.zip`Rainbow Six Siege gamers
2026-04-27`content_automate_faceless_2.7-beta.5.zip`faceless YouTube/TikTok content creators
2026-04-27`setup_ide_cursor_v1.3.zip`AI-tool curious developers
2026-05-01`Mobile-Antigravity-1.3.zip`mobile gamers
2026-05-02`be-hulud-dont-shy-v3.4.zip`security-conscious developers ← us

The common engine across all of these — same launcher pattern, same LuaJIT runtime, same Prometheus-obfuscated Lua, same RSA-encrypted GitHub-to-GitHub exfil — makes this a malware-as-a-service operation, not a one-off campaign. The Shai-Hulud lure is the latest skin on a 3-month-old MaaS engine. The operator follows the news cycle: Trello cracks in February, Cursor IDE in late April, Mini Shai-Hulud in May.

This also means: the OSV `MAL-2026-3201` record (which currently covers only the lightning PyPI compromise) and our 32-IOC catalog under campaign tag `mini-shai-hulud-2026` should be considered two views of the same operator's broader operation. We adopt "Mini Shai-Hulud" as the campaign name to align with the wider threat-intel ecosystem; the family is concurrently tracked as Trojan.Lazy by 35+ industry vendors.

Recommended actions

The technical detail above maps to a specific to-do list, actionable inside a 5-day window.

#RecommendationWhenEffort
1Broadcast to all developers and security staff: do not run any "Shai-Hulud detector" downloaded in the last 7 days. Tell the security team if you did.Today5 min
2Sweep team GitHub accounts for repos matching ^[a-z]+-[a-z]+-\d{1,4}$ created in the last 7 days. Each match is a confirmed credential-exfil drop; rotate every credential the user touched.Today1–2 hrs
3Audit CI runners for processes named java.exe / luajit.exe / init.exe from non-official sources, and any LuaJIT 2.1.0-beta3 binary in %TEMP%.Today2–4 hrs
4Deploy the SOVA gate rule (below) in your CI/CD pipeline. Blocks the fork-and-poison structural fingerprint at install time, before any binary is fetched.This week1 day
5Block egress at the proxy for raw.githubusercontent.com/*/raw/refs/heads/*/{dist,apps/docs}/*.zip paths. Legitimate use is rare; false positives are tractable.This week2 hrs
6Tighten the developer-tooling allowlist. Move from "anything on GitHub" to "tools we have vetted." Single most durable fix in this list.This week1–2 weeks
7Tabletop the lure scenario with security + DevEx teams. Ask: would each role have caught it, and at what step? The gaps reveal where detection investments need to go.This month2 hrs
8Add a 5-minute briefing on social-engineered "tools" to developer onboarding — what they look like, why they work, how to verify a tool's provenance before running it.This month1 day
9Subscribe to a continuous supply-chain threat-intel feed. Continuous capability-shift detection at the scale this campaign operates is what SecureNexus SOVA is built for.This month1 hr setup
10Bring developer endpoints under EDR + MDM + credential vault. Same trust posture as production servers. The lure catches senior engineers because their laptop holds prod credentials, CI tokens, and SSH keys in standard paths.Strategic1 quarter

If you do nothing else: items 1–3 today, items 4–6 this week. That removes most of the ongoing exposure. The rest pays off over months.

Operator IOC catalog

Full catalog of the 32 IOCs for the `mini-shai-hulud-2026` campaign cluster. Each has an entry in our `sova.threat_iocs` collection.

Operator GitHub burner accounts

Code
eliezerfrn        2 malicious repos, 4 zips, GitHub user-id 110551103
nigerbartus       1 malicious repo,  1 zip,  GitHub user-id 156134361
ArcaneMisery095   2 malicious repos, 3 zips, GitHub user-id 203822758
vitor2342         1 malicious repo,  1 zip,  GitHub user-id 209944166

Operator commit-author email leaks

Code
[email protected]           ArcaneMisery095 / shai-hulud-detector + CM-cloud
[email protected]      vitor2342 / sha1-hulud-scanner

Container ZIP SHA-256

Code
d5dec61805ea4cf49f94c35b065e33360e2ef7a4ab6b2e5ba3772616d0699740   eliezerfrn  be-hulud-dont-shy-v3.4.zip       (Variant A, 584,435 B)
6826c3ca4744d8f250a4758560073ab98a4fca937c887b060374250ca26f228a   eliezerfrn  dont-be-shy-hulud_2.5.zip        (Variant B, 1,386,736 B)
5fbf8f949698aa59d57a30414b29bd883606e9e754cbb5c4b9fb52560afdb772   eliezerfrn  cataclismo_rogue_tools_3.4.zip   (Variant A, 584,435 B)
1aebbb5019112ff44270f49b21fec2b2e7b8ab48cb3b085bd2af15fc981ce009   eliezerfrn  cataclismo-rogue-tools_v3.5.zip  (Variant B, 1,386,736 B)
e6d590db443924fd9c7a15784157e1a1bb65c82fd1f5eec5f974f1675d877e61   nigerbartus Shai-Hulud-2.0-Detector_v3.5.zip (Variant B, 1,394,413 B)
85be2954998656869d5fa289d2a9f0f9c61673d2c91fad6f023ca3b1f5f4b9c8   ArcaneMisery095  shai_detector_hulud_3.3.zip  (Variant A, 587,570 B)
488eaa0c997801605c538d62710312d935729eb1b375796808ddba483092cf21   ArcaneMisery095  cloud-C-protonymphal.zip      (Variant A, 587,570 B)
38a930013bbb5585ab56a72d1ba8e37a0f145e126e8aed36b098d75ae9e729ac   ArcaneMisery095  CM-cloud_3.7.zip              (Variant B, 1,394,413 B)
ecd860f1cb30fb3e8d95e86c4d12c95f340b27b041b00e55fd199a88954a02ab   vitor2342   hulud-scanner-sha-v2.6.zip       (Variant A, 547,027 B)

Inner-file SHA-256 (cross-account byte-identical files emphasised)

Code
luajit.exe           5343326fb0b4f79c32276f08ffcc36bd88cde23aa19962bd1e8d8b80f5d33953   ★ eliezerfrn-2.5 + nigerbartus-3.5 (byte-identical)
lua51.dll            c7a657af5455812fb215a8888b7e3fd8fa1ba27672a3ed9021eb6004eff271ac   ★ eliezerfrn-2.5 + nigerbartus-3.5 (byte-identical)
Launcher.cmd         964dfb63ff140149ed8b310dba63fd8d82a82dc9979348e93b3dd7206fd71d13   ★ eliezerfrn-2.5 + nigerbartus-3.5 (byte-identical)
java.exe             f76add7e7ada32704762d833a3137f1c1061b23825b1d4285cc0752bd86df4b5     eliezerfrn-3.4 (Variant A LuaJIT)
genlibbc.txt         bdfef318db2ee1d390f2fa530b5d9c9af2702254127a7ec9a907f60f53db0bb0     eliezerfrn-3.4 obfuscated Lua payload
LaunchApp.cmd        2f5ae87d4514e5227a31ba3e4ee2a52c33f9e3694280599979cf4ba98435f13f     eliezerfrn-3.4 launcher
clib.txt             593916916552ce87cd6fde7353875e023cd8a89f13d222fc636634a43ff65cdb     eliezerfrn-2.5 payload
clib.txt             afa7b54dd8ca0a2b62e353186450ce99daef49a4cb5691ca4a9fa85e0843b060     nigerbartus-3.5 payload
luajit.exe           3595a6b226ce4daa0a28edea152b3a887c01f6323db1d082f6568c995cdefb55     ArcaneMisery095-3.3 (Variant A)
static.txt           59c2115caf3104184de6cbc64c4029886b7302e1fa58acc910a2c567222e8616     ArcaneMisery095-3.3 payload
Application.cmd      af6f59bd3caee5daa2d6765dd8c1bc167060a9681617ee1e2aff32f1eda3477c     ArcaneMisery095-3.3 launcher
init.exe             ac5885b78810a7bf987ff6674f6717059e227df9c969b9fb46d00b2c0de1ba74     vitor2342-2.6 (Variant A)
icon.txt             772ce19206d35699b4d2693c59f8c0bd1a927f287f8bf98bd14d65f1ff248828     vitor2342-2.6 payload
LaunchApp.bat        a3e6236fa517f863ea551e17fcedcfc22df23e044dcd4863e6ddf3ef00966596     vitor2342-2.6 launcher

Behavioural fingerprints

Code
Generation A (Feb 2026)  cdef SHA-256  cb45364d667658fe7681a5f9b044d20734658a3bc55f95f697def061fa6355df   8538 B
Generation B (Dec 2025)  cdef SHA-256  3be0ae42034f5a651d74933180e2395498025d7512416c06411c2248af9b223f   8502 B
PEB-walk shellcode             bytes  64 A1 30 00 00 00 C3   (mov eax, fs:[0x30]; ret)  byte-identical across all 5 sandboxed payloads

What this means

Three takeaways worth carrying out of this incident:

1. The "fake security tool" lure is a distinct distribution vector — not just a sub-case of npm/PyPI compromise. Most discussion of supply-chain malware focuses on the registry side (compromised package publishes via OIDC, dependency-chain reach). This campaign uses GitHub repository hosting plus README-as-lure to deliver the same kit to a different victim profile: end users, not pipelines. Defensive guidance that says "pin your dependencies and audit your CI" doesn't address it.

2. The "structural fingerprint" beats the "hash signature" for resilient detection. The operator rebuilds `luajit.exe` per drop to defeat hash-based detection, but the size class (Variant A 547-588 KB / Variant B 1.39 MB), the launcher pattern (`start .exe .txt`), and the shellcode bytes (`64 A1 30 00 00 00 C3`) are invariant across the campaign. Detection rules that target these structures catch every variant we've seen and likely every future variant.

3. Single-operator MaaS rotates lures faster than defenders can keep up — but operator identity is sticky. This operator has cycled themes (Trello cracks → game cheats → AI-tool installers → security-tool detectors) every 2-4 weeks. Each new theme is harmless to the old detection rules. But the byte-identical kit binaries, the shellcode invariants, and now the leaked operator emails all establish that it's one operator running ≥4 burner accounts and ≥109 lure ZIPs. Defenders catching the next variant should immediately cross-reference against this operator cluster.

For organizations running CI/CD pipelines that pull from GitHub: deploy a structural-fingerprint policy rule that blocks any GitHub repo hosting a binary at depth ≥ 3 absent from the upstream. For organizations running anything that imports from npm or PyPI: the deeper Mini Shai-Hulud variants (cap-js, lightning) hit registries — see the `MAL-2026-3201` record and our prior SecureNexus SOVA writeup on the cap-js compromise for that side. For everyone: GitHub T&S has acted on the cluster reports filed today; the malicious repos are coming down. The operator will respawn elsewhere within days.

See SecureNexus SOVA in action

The same engine that caught this campaign on day-zero runs continuously across 14 package ecosystems and GitHub. It emits deterministic block / warn / safe verdicts on every release, before npm install or pip install fires — and the structural-fingerprint guidance in this post were generated straight from its first-party telemetry.

What ships in the box:

  • Pre-install verdict on every package version: BLOCK / WARN / SAFE
  • Capability-shift detection: install hooks, embedded binaries, fork-and-poison, 140+ structural rules
  • Maintainer-risk scoring with burner-account, sanctioned-country, and signing-history fingerprints
  • Threat-intel correlation against public feeds, sandbox graphs, and our internal IOC catalog
  • Source-vs-artifact diffs: cryptographic invariant checks against the upstream git tree
  • sova-gate CLI + GitHub Action: one YAML policy, non-zero exit on violations

If you ship code that imports anything from npm, PyPI, Maven, Crates.io, NuGet, RubyGems, Packagist, Go modules, Docker, the VS Code Marketplace, the JetBrains plugin registry, the Firefox / Chrome extension stores, or GitHub itself, SOVA is the day-zero defence layer most teams don't yet have.

Learn more about SecureNexus SOVA: https://www.securenexus.ai/products/sova

About the Author

Mohit Kumar
SOVA Product Lead and Researcher

Cybersecurity expert with extensive experience in threat analysis and security architecture.

Perimeter

Intelligence-driven attack surface management

Learn More

VM

Centralized vulnerability management & remediation

Learn More
View all products

Need Expert Security Guidance?

Our cybersecurity experts are here to help you implement the strategies discussed in this article.

Get Expert Consultation Explore Our Products