Home / AWS

AWSRunbookIntermediate

PHP2Shell on AWS - finding every PHP install with SSM Inventory, patching EC2 and containers, and using AWS WAF as a stopgap

CVE-2026-109618 and CVE-2026-109619 let a single unauthenticated request take over PHP web servers, and Amazon's honeypots saw an exploitation attempt days before disclosure. Use SSM Inventory and Run Command to find and patch PHP at fleet scale, rebuild container images, and narrow exposure while you work.

Deepak Bhardwaj4 min read

Applies toPHP web workloads on EC2, Auto Scaling groups, Elastic Beanstalk, ECS/EKS and Lightsail; AWS Systems Manager; AWS WAF; Amazon Inspector

The short version

  • Fixed PHP releases (21 October 2026): 8.5.12, 8.4.27, 8.3.36, 8.2.35. Source backports exist for 7.4, 8.0 and 8.1.
  • Affected: every PHP that serves web requests (PHP-FPM, mod_php, php-cgi, FrankenPHP, LiteSpeed). mod_php is the most exposed.
  • Amazon Threat Intelligence reported an exploitation attempt against its MadPot honeypot on 17 October 2026, four days before public disclosure.

1. Find PHP across the fleet

SSM Inventory collects installed applications on managed instances. Query for PHP packages:

aws ssm list-inventory-entries --instance-id i-0123456789abcdef0 \
  --type-name "AWS:Application" \
  --filters "Key=Name,Values=php,Type=BeginWith" \
  --query "Entries[].[Name,Version]" --output text

Across many instances, use Resource Data Sync to S3 and query with Athena:

SELECT resourceid, name, version
FROM aws_application
WHERE lower(name) LIKE 'php%'
  AND lower(name) NOT LIKE 'phpmyadmin%'
ORDER BY resourceid;

(The table name depends on how you set up the Glue crawler for the sync bucket.)

Instances where PHP was built from source won't appear as a package. Catch them with Run Command:

aws ssm send-command --document-name AWS-RunShellScript \
  --targets "Key=tag:Tier,Values=web" \
  --parameters 'commands=["for p in $(command -v php php-fpm php-cgi 2>/dev/null); do echo $p; $p -v | head -1; done"]' \
  --output-s3-bucket-name ops-ssm-output --max-concurrency 20 --max-errors 5

Amazon Inspector reports package vulnerabilities on EC2 and in ECR images once its database includes the CVEs; filter findings by the CVE IDs.

Warning

Linux distributions often backport fixes without changing the upstream version, so a version string isn't proof either way. Check the vendor's security notice for the package release that contains the fix.

2. Patch

Where How
EC2 with distro packages SSM Run Command or Patch Manager with a baseline that includes the PHP packages; then restart php-fpm / httpd
Auto Scaling groups Bake a new AMI, update the launch template, run an instance refresh
Elastic Beanstalk PHP platforms Apply the platform update that contains the fix (managed platform updates), or update the environment's platform version
ECS / EKS Rebuild images from a patched php: base, push to ECR, roll out new tasks/pods
Lightsail (Bitnami/LAMP) Follow the stack vendor's update steps; take a snapshot first
aws ssm send-command --document-name AWS-RunShellScript \
  --targets "Key=tag:Tier,Values=web" \
  --parameters 'commands=["(command -v dnf && dnf -y upgrade \"php*\") || (apt-get update && apt-get -y install --only-upgrade \"php*\")","systemctl restart php-fpm 2>/dev/null || systemctl restart httpd 2>/dev/null || systemctl restart apache2"]' \
  --max-concurrency 10% --max-errors 1

Restart is required. The second CVE involves state left in long-running workers.

3. Reduce exposure while you patch

  • AWS WAF: check whether AWS has added protection to its managed rule groups (the Known Bad Inputs and core rule set release notes). If not, add rate-based rules and size constraints on headers and body for PHP endpoints. Treat any rule as a delay, not a fix.
  • Security groups: remove direct internet access to instances behind a load balancer; only the ALB should reach them.
  • Admin and internal tools (phpMyAdmin, internal portals): restrict to VPN or Verified Access, or stop them until patched.
  • If a host can't be fixed quickly, consider taking it offline, as the UK NCSC advises.

4. Check for compromise

  • GuardDuty findings for the web tier (unusual outbound traffic, crypto-mining, credential exfiltration from instance roles).
  • ALB access logs from 17 October onwards: bursts of 5xx responses from single IPs.
  • New files in the web root, new cron jobs, new SSH keys. If anything looks wrong, treat the instance as compromised: isolate it, rebuild it, and rotate any credentials its instance role or application could reach.

Checklist

  • PHP inventory from SSM Inventory plus Run Command for source builds
  • Every web host on a fixed or vendor-backported build, and restarted
  • Container images rebuilt and redeployed
  • Instances reachable only through the load balancer
  • WAF rules added as a stopgap
  • GuardDuty and ALB logs reviewed since 17 October

Sources