← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:122591 · CWE-200 · Disclosed 2018-04-29

PHP 5

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a spare key left under the mat inside a locked apartment building

CVE-2018-10545 affects PHP-FPM in upstream PHP before 5.6.35 and later fixed branches 7.0.29 / 7.1.16 / 7.2.4. The bug is not remote code execution; it is a local information disclosure / security-bypass issue where dumpable PHP-FPM worker processes let one local user dump another pool worker's memory and read secrets from shared opcache-backed state. In practice, the attacker needs local execution on the same Linux host, PHP-FPM in use, separate pools, and a multi-user setup where hostile and victim workloads coexist.

The low-ish vendor framing matches reality better than the scarier wording in some scanners. For a normal enterprise web tier, this is post-compromise, same-host, same-platform, narrow-topology abuse with very limited reachable population; it matters mostly for shared hosting or other deliberately multi-tenant Linux PHP-FPM estates that grant shell or code execution to mutually untrusted users.

"This is a shared-hosting edge case, not a general enterprise patch emergency."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Get a same-host foothold with bash or a webshell

The attacker first needs execution on the exact Linux server running the vulnerable PHP-FPM instance. This is not an internet-to-root path; it assumes the adversary already landed a shell, customer account, CI runner, or comparable code execution context on that host.
Conditions required:
  • Attacker already has local execution on the target Linux host
  • Target uses PHP-FPM rather than only CLI or mod_php
  • Vulnerable upstream or equivalent unpatched build is installed
Where this breaks in practice:
  • Requires a prior compromise stage or intentionally shared-hosting model
  • Most enterprise app servers do not expose arbitrary shell access to untrusted users
  • If the foothold is in a container isolated from the FPM host, the path often dies here
Detection/coverage: Network scanners do not meaningfully prove exploitability here; this is mostly version-and-topology driven.
STEP 02

Locate a dumpable PHP-FPM worker with ps

Using standard local tooling such as ps, the attacker identifies active php-fpm worker PIDs. The vulnerable behavior comes from PHP-FPM setting PR_SET_DUMPABLE, which re-enables ptrace/core-dump access in cases where it should have remained blocked after UID/GID changes.
Conditions required:
  • At least one PHP-FPM worker process is running
  • Workers are handling or recently handled victim application data
Where this breaks in practice:
  • No worker, no dump
  • Single-tenant deployments remove the cross-account value proposition
  • Minimal process visibility or namespaces can complicate PID discovery
Detection/coverage: EDR or auditd may capture process enumeration only weakly; it is common admin-like behavior.
STEP 03

Dump memory with gcore / ptrace

The weaponized step is straightforward: run gcore <pid> or equivalent ptrace tooling against a PHP-FPM worker. In the reporter's demonstrated case, this produced a core dump readable by another local user, exposing data that opcache permission checks were supposed to isolate.
Conditions required:
  • Attacker can ptrace or core-dump the target worker
  • Kernel hardening does not block the action
Where this breaks in practice:
  • kernel.yama.ptrace_scope, hardened containers, or restricted core-dump policy can stop this cold
  • Some EDR products alert on gcore, gdb, or abnormal ptrace activity
  • The attacker still needs the right victim process at the right time
Detection/coverage: Good EDR coverage if gcore, gdb, or ptrace events are monitored; otherwise low.
STEP 04

Mine secrets from the core file with strings

Once the dump exists, the attacker can run strings or more specialized memory analysis to recover database credentials, API tokens, or application secrets from victim PHP memory. The public bug report explicitly demonstrated recovery of WordPress database credentials from another account's process memory.
Conditions required:
  • Victim secrets were resident in memory
  • The dump file is readable to the attacker
Where this breaks in practice:
  • Not every dump contains useful secrets
  • Secrets may be short-lived or masked by workload timing
  • Impact is usually confidentiality theft, not direct host takeover by itself
Detection/coverage: Core file creation plus follow-on strings/file reads are visible to host telemetry if enabled.
STEP 05

Pivot with stolen app credentials

The real harm is what the stolen credentials unlock next: database access, lateral movement into another app account, or unauthorized reads of neighboring tenant data. That pivot is environment-specific and is why the bug is meaningful in shared hosting but usually mediocre in conventional enterprise estates.
Conditions required:
  • Recovered secrets are valid and reusable
  • Neighboring applications share infrastructure worth pivoting into
Where this breaks in practice:
  • Blast radius is typically confined to one host and adjacent app identities
  • Credential rotation, network ACLs, and DB auth separation limit the follow-on value
  • This is still downstream of an initial local foothold
Detection/coverage: Downstream detections depend on the stolen credential's next use, not the CVE itself.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo credible active exploitation evidence found in the reviewed sources; this CVE is better characterized as a niche post-compromise abuse path than a campaign driver.
KEV statusNot listed in CISA KEV in the reviewed catalog source; no KEV add date located.
PoC / exploit availabilityPublic reproduction steps exist in the PHP bug report (gcore on a PHP-FPM worker, then strings on the dump). I did not find a widely adopted turnkey GitHub exploit that materially changes defender urgency.
EPSSVery low by available mirrors: roughly 0.04% probability / ~14th percentile from public EPSS mirrors of FIRST data, which fits the narrow local-only reach.
CVSS vector meaningCVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N means local attack vector, high complexity, low privileges required, and confidentiality-only impact.
Affected versionsUpstream PHP < 5.6.35, 7.0.x < 7.0.29, 7.1.x < 7.1.16, 7.2.x < 7.2.4 when PHP-FPM on Linux is in play.
Fixed versionsUpstream fixed in 5.6.35 / 7.0.29 / 7.1.16 / 7.2.4. Debian tracker also shows backports such as jessie 5.6.36+dfsg-0+deb8u1 and stretch 7.0.30-0+deb9u1.
Exposure populationInternet exposure is the wrong lens here. Shodan/Censys can find PHP-facing services, but they cannot tell you whether an attacker already has same-host local execution plus a dumpable cross-tenant PHP-FPM topology.
Disclosure timelineBug submitted 2017-11-30; upstream fix shipped in PHP 5.6.35 on 2018-03-29; NVD published the CVE on 2018-04-29.
Reporter / researcherReported by jd@cpanel.net in PHP bug #75605; Red Hat later summarized shared-hosting as the most obvious exploitation case.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to IGNORE (0.8/10)

The decisive factor is attacker position: this bug starts at local execution on the same Linux host, which means the attacker is already past initial access and sitting in a very specific PHP-FPM deployment model. In a 10,000-host enterprise estate, that sharply limits both reachable population and incremental blast radius, so this does not deserve scarce patch capacity as a standalone emergency.

HIGH Exploit chain requires prior same-host local execution
HIGH Impact is primarily confidentiality theft, not direct remote takeover
MEDIUM Applicability to your estate depends on whether you run true multi-tenant PHP-FPM hosting

Why this verdict

  • Downward pressure: local-only — the NVD vector is AV:L; this is not reachable from the internet without a separate compromise step first.
  • Downward pressure: post-initial-access topology — needing same-host execution implies the attacker already beat your perimeter, app controls, or tenant boundary before this CVE matters.
  • Downward pressure: narrow real-world population — the bug is most relevant to shared hosting / mutually untrusted multi-user PHP-FPM setups, not ordinary enterprise app servers.
  • Downward pressure: modern controls can interrupt it — ptrace restrictions, container isolation, and EDR coverage on gcore/gdb materially raise practical friction.
  • Limited blast radius — even when exploited, the outcome is usually theft of neighboring app secrets from one host, not universal domain compromise.

Why not higher?

There is no unauthenticated remote path here, no wormability, and no evidence that this vulnerability by itself opens broad enterprise attack surface. The attack chain assumes prior local code execution plus a very particular hosting model, which is exactly the kind of compounding friction that should crush severity.

Why not lower?

It is not pure noise if you actually run multi-tenant Linux PHP-FPM with untrusted co-resident users or workloads. In that niche, it can expose real secrets and defeat assumptions around opcache isolation, so I would not call it nonexistent risk.

05 · Compensating Control

What to do — in priority order.

  1. Document applicability — If your environment is a normal enterprise web tier with no untrusted same-host users, no action is required for this CVE; document the post-compromise/local-only rationale and move on. If you *do* run shared hosting or customer shell access, record those assets as exceptions and treat them separately.
  2. Restrict ptrace and core dumps — On shared-hosting-style Linux systems, enforce kernel.yama.ptrace_scope, restrict gcore/gdb, and tighten core-dump policy so unprivileged users cannot dump neighboring PHP-FPM workers. Because the noisgate verdict is IGNORE, there is no SLA here unless the host is one of those narrow multi-tenant exceptions.
  3. Collapse unnecessary co-tenancy — Do not place mutually untrusted apps or users in adjacent PHP-FPM pools on the same host if you can avoid it. This removes the cross-tenant memory theft value even when a local foothold exists.
What doesn't work
  • A WAF does not help; exploitation happens after local foothold and uses host debugging/core-dump behavior, not HTTP payload tricks.
  • MFA does not help directly; the attacker is not logging into the app as a user, they are dumping worker memory after obtaining local execution.
  • External internet scanning does not prove safety; the key prerequisites are same-host local access and tenant layout, which scanners cannot infer.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux host as a local auditor. Invoke it with sudo bash check_cve_2018_10545.sh for best results because reading pool configs and package metadata is easier with root, though it often works unprivileged; it checks for PHP-FPM presence, upstream vulnerable version windows, and whether the host appears to use multiple distinct pool users.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2018_10545.sh
# Determine likely exposure to CVE-2018-10545 (PHP-FPM dumpable child processes)
# Outputs one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN

set -u

out_unknown() { echo "UNKNOWN: $1"; exit 2; }
out_vuln()    { echo "VULNERABLE: $1"; exit 1; }
out_patched() { echo "PATCHED: $1"; exit 0; }

have_cmd() { command -v "$1" >/dev/null 2>&1; }

ver_lt() {
  # returns 0 if $1 < $2 using sort -V
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ] && [ "$1" != "$2" ]
}

ver_ge() {
  [ "$1" = "$2" ] && return 0
  ! ver_lt "$1" "$2"
}

phpfpm_bin=""
for c in php-fpm php-fpm5 php-fpm7.0 php-fpm7.1 php-fpm7.2 php-fpm7.3 php-fpm7.4 php-fpm8.0 php-fpm8.1 php-fpm8.2 php-fpm8.3; do
  if have_cmd "$c"; then phpfpm_bin="$c"; break; fi
done

pkg_ver=""
raw_ver=""
if [ -n "$phpfpm_bin" ]; then
  raw_ver="$($phpfpm_bin -v 2>/dev/null | head -n1)"
  pkg_ver="$(printf '%s' "$raw_ver" | sed -n 's/.*PHP \([0-9][0-9.]*\).*/\1/p')"
fi

if [ -z "$pkg_ver" ]; then
  if have_cmd dpkg-query; then
    for p in php5-fpm php-fpm php7.0-fpm php7.1-fpm php7.2-fpm php7.3-fpm php7.4-fpm php8.0-fpm php8.1-fpm php8.2-fpm php8.3-fpm; do
      v="$(dpkg-query -W -f='${Version}' "$p" 2>/dev/null | head -n1)"
      if [ -n "$v" ]; then
        raw_ver="$v"
        pkg_ver="$(printf '%s' "$v" | sed -n 's/^\([0-9][0-9.]*\).*/\1/p')"
        break
      fi
    done
  elif have_cmd rpm; then
    for p in php-fpm php56-php-fpm php70-php-fpm php71-php-fpm php72-php-fpm php73-php-fpm php74-php-fpm php80-php-fpm php81-php-fpm php82-php-fpm php83-php-fpm; do
      v="$(rpm -q --qf '%{VERSION}-%{RELEASE}' "$p" 2>/dev/null)"
      if [ -n "$v" ] && ! printf '%s' "$v" | grep -q 'not installed'; then
        raw_ver="$v"
        pkg_ver="$(printf '%s' "$v" | sed -n 's/^\([0-9][0-9.]*\).*/\1/p')"
        break
      fi
    done
  fi
fi

[ -n "$pkg_ver" ] || out_unknown "php-fpm not found or version could not be determined"

# Determine whether the upstream version falls in a vulnerable window.
upstream_vuln="no"
if ver_ge "$pkg_ver" "5.6.0" && ver_lt "$pkg_ver" "5.6.35"; then upstream_vuln="yes"; fi
if ver_ge "$pkg_ver" "7.0.0" && ver_lt "$pkg_ver" "7.0.29"; then upstream_vuln="yes"; fi
if ver_ge "$pkg_ver" "7.1.0" && ver_lt "$pkg_ver" "7.1.16"; then upstream_vuln="yes"; fi
if ver_ge "$pkg_ver" "7.2.0" && ver_lt "$pkg_ver" "7.2.4"; then upstream_vuln="yes"; fi

# If version is outside affected windows, call it patched.
if [ "$upstream_vuln" = "no" ]; then
  out_patched "Detected PHP-FPM version $pkg_ver is outside upstream vulnerable ranges"
fi

# Look for FPM pool configs and count distinct users.
conf_dirs="/etc/php-fpm.d /etc/php*/fpm/pool.d /usr/local/etc/php-fpm.d"
users=""
for d in $conf_dirs; do
  [ -d "$d" ] || continue
  while IFS= read -r -d '' f; do
    u="$(grep -E '^[[:space:]]*user[[:space:]]*=' "$f" 2>/dev/null | tail -n1 | sed 's/.*=//; s/[[:space:]]//g')"
    [ -n "$u" ] && users="$users
$u"
  done < <(find "$d" -maxdepth 1 -type f \( -name '*.conf' -o -name '*.pool' \) -print0 2>/dev/null)
done

distinct_users="$(printf '%s
' "$users" | sed '/^$/d' | sort -u | wc -l | tr -d ' ')"

# Heuristic: vulnerable upstream version + multiple pool users => likely exposed.
# Single-user deployments are often not meaningfully exposed to the cross-tenant angle.
if [ "$distinct_users" -ge 2 ]; then
  out_vuln "Upstream vulnerable PHP-FPM version $pkg_ver with multiple distinct pool users detected ($distinct_users users); check for distro backports before patching"
fi

# Backport caveat for distro builds.
if printf '%s' "$raw_ver" | grep -Eq 'deb|ubuntu|el[0-9]|fc[0-9]|suse'; then
  out_unknown "Version string '$raw_ver' may include distro backports; upstream version looks vulnerable, but package maintenance could already include the fix"
fi

out_unknown "Upstream vulnerable PHP-FPM version $pkg_ver detected, but host does not clearly appear multi-tenant; verify package backports and pool topology manually"
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: do not burn emergency patch capacity on this CVE unless you run a real shared-hosting or mutually untrusted multi-tenant PHP-FPM environment. For the typical enterprise estate, there is no noisgate mitigation SLA and no noisgate remediation SLA because the verdict is IGNORE — document the rationale and move on; if you do have narrow exception hosts with hostile co-tenancy, harden ptrace/core-dump behavior immediately as a platform control and handle the eventual PHP upgrade under your separate unsupported PHP 5.6 lifecycle program rather than as a CVE-2018-10545 incident.

Sources

  1. Tenable plugin 122591
  2. PHP 5 changelog entry for 5.6.35
  3. PHP bug #75605
  4. NVD CVE-2018-10545
  5. Debian security tracker CVE-2018-10545
  6. Red Hat Bugzilla 1563858
  7. CISA Known Exploited Vulnerabilities Catalog
  8. FIRST EPSS API documentation
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.