Back to Intelligence

13 Malicious Packagist Composer Packages Deploy iOS Spyware — Detection and Removal Guide

SA
Security Arsenal Team
September 1, 2026
12 min read

Supply-chain compromises through open-source package registries continue to be one of the most cost-effective intrusion vectors available to threat actors, and the latest campaign against Packagist is a textbook example. Security researchers have identified 13 malicious Composer theme packages on Packagist — the primary package repository for PHP — engineered to inject malicious JavaScript into any site that installs them. The campaign specifically targets Vietnamese movie and comic streaming sites, but the technique generalizes to any PHP application that pulls in one of these packages.

Once installed, the injected JavaScript executes two operations against a site's visitors:

  1. Mobile ad-fraud and gambling-redirect logic, monetizing hijacked traffic.
  2. Spyware deployment aimed at unpatched iOS devices, with the end goal of stealing cryptocurrency wallet seed phrases — the master keys to a victim's crypto holdings.

This is not a theoretical risk. These packages are live, installable dependencies. If your development team, your marketing agency, or a third-party theme vendor installed one of them, your site is currently weaponizing your own visitors. For defenders, the priority actions are: audit your composer.json/composer.lock files, scan your deployed web content for injected script tags, and treat any confirmed installation as a full incident — because the compromise path runs through your build pipeline and your production webroot simultaneously.

Technical Analysis

Affected Ecosystem and Delivery Mechanism

  • Registry: Packagist (packagist.org), the canonical Composer repository for PHP
  • Package type: Composer theme packages — a category that typically bundles front-end assets (HTML templates, CSS, JavaScript) alongside PHP code. This packaging style is ideal for abuse because themes legitimately ship and render JavaScript, so injected <script> payloads blend into expected artifacts.
  • Target population (upstream): Vietnamese movie and comic streaming site operators who install the trojanized themes
  • Target population (downstream): End users visiting the compromised sites — specifically mobile users running unpatched iOS versions, and crypto holders whose wallet seed phrases can be harvested by the delivered spyware

Attack Chain (Defender's View)

  1. Dependency ingestion: A developer or site operator runs composer require on one of the 13 malicious theme packages, either directly or transitively through another dependency.
  2. Payload placement: During install or at template render time, the package injects malicious JavaScript into pages served by the site — typically appended to theme templates, footer includes, or asset bundles.
  3. Visitor-side execution: When a mobile browser loads a compromised page, the injected script profiles the device. For iOS devices missing current security updates, the chain proceeds to spyware delivery; otherwise it falls back to ad-fraud/gambling redirects.
  4. Objective — seed phrase theft: The spyware component targets cryptocurrency wallets on the device, seeking recovery seed phrases. Seed phrase compromise is irreversible — funds can be drained instantly and there is no fraud-recovery mechanism on-chain.

No CVE identifier has been published for this campaign as of this writing, and no official iOS CVE is referenced in the disclosure. The iOS-side exploitation relies on the victim running an unpatched OS version — which is a patch-hygiene problem on the endpoint, but the root cause is a supply-chain compromise on the server side, and that is where defenders have the most leverage.

Exploitation Status

  • Confirmed active in the wild. The packages are live malicious artifacts identified by researchers; the injected code is operational (ad fraud + spyware delivery).
  • Not a zero-day story. This is a registry-abuse and social-engineering campaign. The "vulnerability" is the trust developers place in unvetted packages.
  • Blast radius is unbounded downstream. Every visitor to every compromised site is a potential victim. A single infected theme on a high-traffic streaming site can expose hundreds of thousands of users.

Why Theme Packages Are a Dangerous Abuse Vector

Themes are trusted to render content. Unlike a utility library — where unexpected outbound network calls or DOM manipulation would stand out in review — a theme is expected to ship JavaScript. Malicious script tags, obfuscated loaders, and conditional mobile-user-agent logic hide in plain sight. Reviewers and automated scanners tuned for malicious PHP often ignore bundled front-end assets entirely.

Detection & Response

The observable surface here spans three layers: the build/dev environment (Composer install activity), the web server (injected content in served pages and modified theme files), and the network (outbound connections from the web tier to attacker-controlled redirect/payload infrastructure). The detections below target all three.

Sigma Rules

YAML
---
title: Composer Installation of Untrusted Theme Packages
description: Detects Composer require/update operations pulling theme-type packages, which is the ingestion vector for the malicious Packagist theme campaign. Tune the vendor allowlist for your environment.
references:
  - https://thehackernews.com/2026/09/13-malicious-packagist-packages-target.html
  - https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
status: experimental
date: 2026/09/15
tags:
  - attack.supply_chain
  - attack.t1195.002
logsource:
  category: process_creation
  product: linux
detection:
  selection_composer:
    Image|endswith:
      - '/composer'
      - '/composer.phar'
    CommandLine|contains:
      - ' require '
      - ' update'
  selection_theme:
    CommandLine|contains:
      - 'theme'
      - 'template'
      - 'skin'
  condition: selection_composer and selection_theme
falsepositives:
  - Legitimate theme installation by development teams — alert should drive package provenance review, not automatic blocking
level: medium
---
title: Unexpected Modification of PHP Theme Files Post-Deployment
description: Detects modification or creation of PHP/template/asset files inside deployed web application theme directories by the web server or PHP process, consistent with a malicious package injecting content at runtime rather than at deploy time.
references:
  - https://thehackernews.com/2026/09/13-malicious-packagist-packages-target.html
  - https://attack.mitre.org/techniques/T1505/
author: Security Arsenal
status: experimental
date: 2026/09/15
tags:
  - attack.persistence
  - attack.t1505
logsource:
  category: file_event
  product: linux
detection:
  selection_writer:
    Image|endswith:
      - '/php-fpm'
      - '/php'
      - '/httpd'
      - '/apache2'
      - '/nginx'
  selection_path:
    TargetFilename|contains:
      - '/vendor/'
      - '/themes/'
      - '/templates/'
    TargetFilename|endswith:
      - '.php'
      - '.phtml'
      - '.twig'
      - '.blade.php'
      - '.js'
  condition: selection_writer and selection_path
falsepositives:
  - Cache/template compilation by frameworks (Laravel, Symfony) — baseline compilation paths and alert on writes outside deploy windows
level: high
---
title: Injected External Script Tag Served by Web Application
description: Detects web server processes reading theme assets that reference newly introduced external script sources, and correlates with known ad-fraud/gambling redirect behavior. Best deployed as a content-integrity check against served HTML via proxy or WAF telemetry.
references:
  - https://thehackernews.com/2026/09/13-malicious-packagist-packages-target.html
  - https://attack.mitre.org/techniques/T1189/
author: Security Arsenal
status: experimental
date: 2026/09/15
tags:
  - attack.initial_access
  - attack.t1189
logsource:
  category: webserver
detection:
  selection_ua:
    cs-user-agent|contains:
      - 'iPhone'
      - 'iPad'
      - 'Mobile/15E148'
  selection_response_indicator:
    sc-status: 302
    cs-referer|contains:
      - 'casino'
      - 'bet'
      - 'gambling'
      - 'slot'
  condition: all of them
falsepositives:
  - Legitimate affiliate/redirect campaigns on streaming sites — validate destination domains against threat intel before escalating
level: medium

KQL — Microsoft Sentinel / Defender

This query hunts across Syslog/web telemetry for the two strongest signals: Composer package ingestion on build hosts, and iOS-targeted redirect behavior on the web tier. It assumes Apache/Nginx access logs are ingested via Syslog/CEF and process telemetry via Defender for Endpoint or AMA.

KQL — Microsoft Sentinel / Defender
let lookback = 14d;
// Signal 1: Composer require/update activity on build or web hosts
let ComposerActivity =
    union isfuzzy=true
    (DeviceProcessEvents
    | where Timestamp > ago(lookback)
    | where FileName in~ ("composer", "composer.phar", "php")
    | where ProcessCommandLine has_any ("composer require", "composer update")
    | project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcessAccountName),
    (Syslog
    | where TimeGenerated > ago(lookback)
    | where SyslogMessage has_all ("composer", "require")
    | project TimeGenerated, HostName, ProcessName, SyslogMessage);
// Signal 2: iOS user agents receiving redirects to gambling/redirect domains
let IosRedirects =
    union isfuzzy=true
    (CommonSecurityLog
    | where TimeGenerated > ago(lookback)
    | where RequestContext has_any ("iPhone", "iPad", "Mobile/")
    | where AdditionalExtensions has_any ("302", "redirect")
    | where RequestURL has_any ("bet", "casino", "slot", "gambl", "lucky")
    | project TimeGenerated, SourceIP, DestinationHostName, RequestURL, RequestContext),
    (Syslog
    | where TimeGenerated > ago(lookback)
    | where SyslogMessage has_any ("iPhone", "iPad")
    | where SyslogMessage has " 302 "
    | where SyslogMessage has_any ("casino", "bet", "gambl")
    | project TimeGenerated, HostName, SyslogMessage);
ComposerActivity
| union IosRedirects
| sort by Timestamp desc

Velociraptor VQL — Hunt for Injected Theme Artifacts

Use this artifact against Linux web servers to enumerate recently modified files in Composer vendor and theme directories — the footprint left by a malicious package injecting JavaScript after deployment.

VQL — Velociraptor
-- Hunt for recently modified PHP/JS files in vendor and theme directories
-- Modified-after-deploy files are the hallmark of runtime injection by a malicious package
LET suspicious_paths = {
  SELECT FullPath, Mtime, Size, Mode
  FROM glob(globs=['/var/www/**/vendor/**/*.php', '/var/www/**/vendor/**/*.js',
                   '/var/www/**/themes/**/*.js', '/var/www/**/templates/**/*.js',
                   '/srv/www/**/vendor/**/*.php', '/srv/www/**/themes/**/*.js'])
  WHERE Mtime > now() - 1209600
};
SELECT FullPath, Mtime, Size,
       (now() - Mtime) / 86400 AS DaysSinceModified
FROM suspicious_paths
ORDER BY Mtime DESC

Pair this with a netstat review on the web tier for outbound connections to unfamiliar hosts — the injected JavaScript's payload/redirect infrastructure must be reachable from the victim's browser, but server-side callbacks from the malicious package itself will appear here:

VQL — Velociraptor
-- Review outbound connections from web server / PHP processes
SELECT Pid, Name, RemoteAddress, RemotePort, Status
FROM netstat()
WHERE Name =~ 'php|httpd|apache|nginx|composer'
  AND Status =~ 'ESTABLISHED|SYN'
  AND NOT RemoteAddress =~ '^(10\\.|192\\.168\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|127\\.)'

Remediation / Verification Script (Bash)

Run this on build hosts and production web servers to audit Composer dependencies, diff deployed content for injected scripts, and flag suspicious outbound references. Review output before removing anything.

Bash / Shell
#!/bin/bash
# Packagist malicious-theme audit — run on build hosts and web roots
# Usage: sudo ./packagist_audit.sh /var/www/mysite

WEBROOT="${1:-/var/www}"
REPORT="/tmp/packagist_audit_$(date +%Y%m%d_%H%M%S).txt"

echo "=== Packagist Malicious Theme Audit ===" | tee "$REPORT"

echo -e "\n[1] Enumerating installed Composer packages..." | tee -a "$REPORT"
find "$WEBROOT" -maxdepth 4 -name composer.lock 2>/dev/null | while read -r lock; do
  echo "--- $lock ---" | tee -a "$REPORT"
  # List all package names and flag theme/template/skin packages
  grep -oP '"name"\s*:\s*"[^"]+"' "$lock" | grep -iE 'theme|template|skin|layout' | tee -a "$REPORT"
  # Flag packages with no/dist pointing to non-packagist or unusual sources
  grep -oP '"(url|reference)"\s*:\s*"[^"]+"' "$lock" | grep -ivE 'github|gitlab|bitbucket|packagist' | tee -a "$REPORT"
done

echo -e "\n[2] Files in vendor/ and theme dirs modified in last 30 days (runtime injection indicator)..." | tee -a "$REPORT"
find "$WEBROOT" -type d \( -name vendor -o -name themes -o -name templates \) -prune -o -type f -print 2>/dev/null | head -1 > /dev/null
find "$WEBROOT" -path '*/vendor/*' -type f \( -name '*.php' -o -name '*.js' \) -mtime -30 -ls 2>/dev/null | tee -a "$REPORT"
find "$WEBROOT" -path '*/themes/*' -type f -name '*.js' -mtime -30 -ls 2>/dev/null | tee -a "$REPORT"

echo -e "\n[3] Scanning served templates for injected external script tags and obfuscation..." | tee -a "$REPORT"
grep -rIlE '<script[^>]+src=["'"'"']https?://' "$WEBROOT" --include='*.php' --include='*.phtml' --include='*.twig' --include='*.blade.php' 2>/dev/null | while read -r f; do
  echo "External script reference: $f" | tee -a "$REPORT"
done
grep -rIlE 'eval\(|atob\(|fromCharCode|\\x[0-9a-f]{2}\\x[0-9a-f]{2}|document\.write' "$WEBROOT" --include='*.js' --include='*.php' 2>/dev/null | grep -v node_modules | while read -r f; do
  echo "Obfuscation indicator: $f" | tee -a "$REPORT"
done

echo -e "\n[4] Outbound connections from web/PHP processes..." | tee -a "$REPORT"
ss -tnp 2>/dev/null | grep -E 'php|httpd|apache|nginx' | grep -vE '10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.' | tee -a "$REPORT"

echo -e "\nAudit complete. Review $REPORT and validate every flagged package against packagist.org before removal."

Remediation

Immediate (24 hours):

  1. Audit every Composer dependency. Run composer show against every project and cross-reference each package name against the researcher's published list of the 13 malicious packages. Check composer.lock files in version control for when any flagged package was introduced and by whom.
  2. Remove and purge confirmed malicious packages. composer remove <vendor>/<package>, then redeploy from a clean build. Do not trust in-place cleanup — the package may have modified templates outside its own directory.
  3. Scan your rendered output, not just your source. Crawl your production pages (including mobile user-agent variants) and diff the served HTML against expected templates. Injected script tags may be conditional on User-Agent: iPhone and invisible to desktop scans.
  4. Rotate credentials touched by affected build pipelines. If the malicious package executed during CI/CD (Composer install scripts run with build-user privileges), treat build secrets, deploy keys, and registry tokens as compromised.

Short term (1 week):

  1. Implement dependency provenance controls. Pin all dependencies by lockfile hash, require code review for any new package introduction, and enforce a private Composer repository (e.g., Satis, or a proxy through your artifact manager) that allowlists vetted packages.
  2. Disable Composer install/update scripts in production builds where feasible (composer install --no-scripts), since package lifecycle hooks are a primary payload-execution vector.
  3. Deploy Subresource Integrity (SRI) and a strict Content Security Policy on web properties. A CSP with an explicit script-src allowlist will block injected third-party script loads for most visitors — this is a strong compensating control against exactly this class of attack.
  4. File integrity monitoring on webroots. Alert on any change to theme/template/vendor files outside a deploy window. Runtime injection is only successful because nobody is watching.

Downstream/user-facing:

  1. Notify affected site operators and, where applicable, your user base. If you operate a compromised streaming property, your visitors — particularly iOS users — need to update to the current iOS release immediately, and crypto holders should consider their seed phrases exposed and migrate funds to wallets with newly generated seeds from a clean device.
  2. Report malicious packages to Packagist security (security@packagist.org) and preserve the packages, lockfiles, and web logs as evidence before cleanup.

The Bigger Lesson

This campaign illustrates why registry hygiene is now a frontline SOC concern, not just a developer concern. The attack never touches your perimeter — it arrives as a trusted dependency, executes inside your build, and weaponizes your own infrastructure against your users. Organizations that treat third-party packages as trusted-by-default will keep losing this fight. Lockfile discipline, dependency provenance review, file integrity monitoring on deployed assets, and a strict CSP would each independently have blunted or exposed this campaign. Layer all four.

Related Resources

Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.