← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:104631 · Disclosed 2017-10-26

PHP 5

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

This is less a front-door master key and more a brittle lock that only breaks if your app hands strangers the tumblers

Tenable plugin 104631 fires when a remote web server banners PHP 5.6.x earlier than 5.6.32. That release fixed two security-relevant issues in this branch: CVE-2017-16642, an out-of-bounds read in date parsing (timelib_meridian) reachable when PHP parses attacker-controlled date strings, and CVE-2016-1283, a heap overflow in bundled PCRE 8.38 triggered by compiling a crafted regular expression. In plain English: one bug can leak or crash during weird date parsing, the other needs the application to treat attacker input as the *regex pattern itself*, not just as data matched by a safe developer-written regex.

The vendor label does not match reality. Tenable inherits a 9.8 vector from the worst underlying PCRE case and stamps the plugin critical, but that assumes generic unauthenticated network exploitation that most PHP apps simply do not expose. In real deployments, CVE-2017-16642 is mostly an info-leak/crash bug, and CVE-2016-1283 depends on an unusually dangerous app design pattern. That makes this a patch-worthy internet-facing hygiene issue, not a drop-everything emergency on its own.

"Tenable called this critical, but the real attack path is app-specific and usually stops at crash or minor memory disclosure."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find an app path that hands attacker input into a vulnerable parser

The attacker first needs a PHP endpoint that passes untrusted input into either date parsing (strtotime, DateTime, php_parse_date, wddx_deserialize) or into regex *compilation* via preg_* where the user controls the pattern. Tooling here is mundane: curl, Burp Repeater, or a simple fuzzer against form fields, query parameters, XML/WDDX payloads, or search/filter features. The important detail is that most PHP apps expose user-controlled *subjects* to regex, not user-controlled *patterns*, which sharply narrows the PCRE path.
Conditions required:
  • Internet-reachable or otherwise reachable PHP application
  • Application passes attacker-controlled input into date parsing or regex compilation
  • Runtime is actually PHP 5.6.0 through 5.6.31 and not a distro-backported build
Where this breaks in practice:
  • Most apps do not let unauthenticated users supply arbitrary regex patterns
  • Many apps never touch WDDX, the clearest published repro path for CVE-2017-16642
  • Remote scanners often key off banners and cannot prove the dangerous code path exists
Detection/coverage: Nessus plugin 104631 is version/banner-based remote detection. It confirms an old PHP branch is exposed, but not whether a reachable exploit path exists in the application.
STEP 02

Send a crafted payload to the exact parser primitive

For CVE-2017-16642, public repro material shows malformed date strings such as front of 0 0 flowing into date parsing and causing out-of-bounds reads. For CVE-2016-1283, the attacker must submit a crafted recursive named-subgroup regex pattern that gets compiled by PCRE 8.38. This is not a generic "send one HTTP request to PHP" bug; it is a "your application must expose the dangerous parser surface" bug.
Conditions required:
  • Input reaches the vulnerable parser unmodified enough to preserve trigger syntax
  • Relevant extension/code path is enabled and used by the application
Where this breaks in practice:
  • Input validation, normalization, and framework parsing often break the trigger
  • Applications commonly use fixed developer regexes, eliminating the PCRE exploit path
  • Some front-end WAF rules or strict schema validators block malformed payload structure
Detection/coverage: Network scanners will not reliably validate exploitability. App testing, code review, and targeted fuzzing are better suited than commodity vuln scanners.
STEP 03

Turn parser failure into something operationally useful

CVE-2017-16642 is primarily an out-of-bounds read, so the likely outcomes are memory disclosure or worker crash, not turnkey code execution. CVE-2016-1283 is technically worse because it is a heap overflow, but reliable remote code execution from this path in a hardened modern deployment is a much higher bar than the inherited 9.8 suggests. In practice, most teams should think "request crash / possible memory exposure" first, not "internet-to-root RCE."
Conditions required:
  • Process memory layout and allocator behavior cooperate with the crafted input
  • The attacker can observe crash effects or leaked response artifacts
Where this breaks in practice:
  • PHP-FPM worker recycling and process isolation limit blast radius
  • ASLR and modern heap behavior reduce reliability for memory-corruption weaponization
  • A crash in one worker is often noisy and self-limiting rather than silently exploitable
Detection/coverage: Look for anomalous requests containing strange date directives or recursive regex syntax, paired with PHP-FPM/Apache worker crashes, core dumps, or parser warnings.
STEP 04

Chain with a second weakness for meaningful compromise

To get from this plugin to full compromise, attackers usually need an additional application flaw: a response oracle for memory leakage, an auth bypass, file write, deserialization bug, or another memory-safety primitive. Without that second leg, this plugin mostly represents old, fragile parser bugs in an old runtime rather than a standalone internet RCE event. That is the decisive downgrade from the vendor label.
Conditions required:
  • A second vulnerability or overly permissive app behavior exists
  • The attacker can iterate requests long enough to stabilize the chain
Where this breaks in practice:
  • No public, turnkey internet PHP exploit chain is cited by the primary sources here
  • No KEV listing or campaign evidence suggests attackers are broadly chaining this in the wild
Detection/coverage: Correlate app exceptions, repeated malformed parser inputs, and crash-loop behavior. EDR on the host should catch repeated PHP worker faults or abnormal child restarts.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence in the sources of broad active exploitation for this plugin's underlying CVEs. I found no CISA KEV entry for CVE-2016-1283 or CVE-2017-16642.
KEV statusNot KEV-listed as of 2026-05-29 review. That removes the strongest urgency amplifier.
Proof-of-concept availabilityPublic repro artifacts exist, but they are crash/research-grade, not a turnkey campaign chain: PHP bug #75055 includes a working trigger path for CVE-2017-16642, and the CVE-2016-1283 record includes the crafted PCRE pattern.
EPSSUnderlying signal is moderate, not alarming: Tenable shows CVE-2017-16642 EPSS 0.04644 and CVE-2016-1283 EPSS 0.02952. BitSight renders CVE-2017-16642 at 8.26% / 92nd percentile.
CVSS and why it overstates riskTenable scores the plugin from CVE-2016-1283 at 9.8 (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), but that assumes generic remote reachability. In practice, the attacker usually needs an app-specific unsafe coding pattern.
Affected versionsUpstream PHP says affected versions are PHP 5.6.x before 5.6.32 for this plugin. The individual CVEs also affect later PHP 7 branches, but plugin 104631 is specifically about the 5.6 line.
Fixed versions and distro backportsUpstream fixed at PHP 5.6.32 on 2017-10-26. Distros also backported fixes: Ubuntu USN-3566-1 patched supported packages without requiring the upstream version string to equal 5.6.32.
Exposure/scanning realityPHP is widely exposed, but exposure is not equal to exploitability. BitSight's footprint page for CVE-2017-16642 shows millions of observed software observations, which means large population, not that each host exposes the dangerous parser path.
Disclosure timelinePHP announced 5.6.32 as a security release on 2017-10-26. CVE-2017-16642 traces back to public PHP bug #75055, submitted 2017-08-09, and CVE-2016-1283 was originally published 2016-01-03.
Reporting researcher / sourceCVE-2017-16642 bug credit goes to Wei Lei and Liu Yang of Nanyang Technological University in the PHP bug report. CVE-2016-1283 is an upstream PCRE issue inherited into PHP's bundled PCRE.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.4/10)

The single biggest downgrade factor is attacker path friction: meaningful exploitation usually requires an application to expose attacker-controlled regex compilation or a very specific date-parsing path. Without that unsafe app behavior, this plugin is mostly evidence of stale PHP rather than a broadly weaponizable internet compromise route.

HIGH Affected upstream version range and fixed version (`5.6.32`)
MEDIUM Real-world exploitability downgrade from vendor `critical` to noisgate `medium`
MEDIUM Exposure interpretation for internet-facing PHP estates

Why this verdict

  • Big downgrade for app-specific reachability Tenable starts from a 9.8 PCRE vector, but real exploitation usually requires user control of the *regex pattern itself* or a precise date-parsing sink. Most enterprise PHP apps do not expose that to unauthenticated users.
  • One underlying bug is not a generic RCE CVE-2017-16642 is an out-of-bounds read with confidentiality-focused impact. That is materially weaker than the plugin's critical label implies.
  • No strong threat signal No KEV listing, no campaign evidence in the cited sources, and public material is mostly repro/crash-grade. That removes the usual reasons to keep a parser bug in the high-end buckets.

Why not higher?

If this were a broadly reachable, unauthenticated parser bug with confirmed internet exploitation, the vendor baseline would hold. But the attack chain narrows hard at the first step because the application must expose an unusually dangerous parser sink. That compounding friction is exactly why this does not deserve a HIGH or CRITICAL operational label.

Why not lower?

You are still looking at an internet-facing, outdated PHP runtime with memory-safety issues. In shops with legacy apps, search features, filter builders, importers, or custom date handling can absolutely expose the vulnerable paths, and the install base of PHP is huge. That keeps it above LOW even without active exploitation evidence.

05 · Compensating Control

What to do — in priority order.

  1. Inventory every PHP 5.6 endpoint — Map all hosts, vhosts, containers, and FPM pools still serving PHP 5.6.x and tag whether they are internet-facing, authenticated-only, or internal. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but you should complete inventory immediately because this plugin is usually a marker for broader legacy exposure.
  2. Review code paths that compile user regex — Search for preg_* usage where the pattern can be influenced by request data, admin UI rules, search builders, or templating features. If found, add server-side allowlists or pattern generation rather than free-form regex input; do this now if migration will be delayed, even though a MEDIUM verdict has no separate mitigation SLA.
  3. Constrain untrusted date parsing — Replace permissive natural-language date parsing on untrusted input with strict formats like ISO-8601 and schema validation. This blocks the easiest published trigger style for CVE-2017-16642 and reduces noisy parser edge cases while you work toward remediation.
  4. Prefer distro-patched packages over raw upstream relics — If you cannot move off legacy PHP immediately, at least verify whether the host is on a vendor-supported package stream with backports rather than a hand-built upstream tarball. That does not eliminate old-branch risk, but it avoids assuming banner version equals unpatched state.
  5. Monitor PHP worker crashes and parser anomalies — Ship Apache/nginx, PHP-FPM, and application logs to your SIEM and alert on repeated worker restarts, segfaults, or bursts of malformed date/regex inputs. There is no noisgate mitigation deadline for MEDIUM, but this is cheap detection coverage you can deploy while remediation is scheduled.
What doesn't work
  • A generic perimeter WAF by itself does not solve this, because the dangerous condition is often legitimate app behavior behind normal HTTP requests and can sit in POST bodies or authenticated workflows.
  • MFA does nothing for unauthenticated internet paths and only partially helps if the dangerous feature is behind login; it does not remove the vulnerable parser from the runtime.
  • Relying only on remote banner scans is insufficient, because distro backports can look old and truly vulnerable apps can hide behind rewritten headers or proxies.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux host that serves PHP, not from an auditor workstation. Save it as check_php_5632.sh, then run sudo bash check_php_5632.sh or point at a specific binary with sudo bash check_php_5632.sh /usr/bin/php; root is helpful for checking package metadata and multiple install paths, but the script can often work without it.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_php_5632.sh
# Purpose: detect whether a Linux host is running upstream-style PHP 5.6.x earlier than 5.6.32
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

TARGET_BIN="${1:-}"
FOUND=0
VULN=0
UNKNOWN=0

declare -a CANDIDATES
if [ -n "$TARGET_BIN" ]; then
  CANDIDATES+=("$TARGET_BIN")
fi

# Common paths
for p in /usr/bin/php /usr/local/bin/php /opt/*/bin/php /usr/sbin/php-fpm /usr/sbin/php-fpm5 /usr/sbin/php-fpm5.6 /usr/sbin/php-fpm56; do
  for r in $p; do
    [ -x "$r" ] && CANDIDATES+=("$r")
  done
done

# Deduplicate while preserving order
uniq_candidates=()
for c in "${CANDIDATES[@]:-}"; do
  skip=0
  for u in "${uniq_candidates[@]:-}"; do
    [ "$c" = "$u" ] && skip=1 && break
  done
  [ $skip -eq 0 ] && uniq_candidates+=("$c")
done

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

check_php_version() {
  local bin="$1"
  local out ver
  out="$($bin -v 2>/dev/null | head -n1 || true)"
  ver="$(printf '%s' "$out" | sed -nE 's/^PHP[[:space:]]+([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')"

  if [ -z "$ver" ]; then
    echo "UNKNOWN: could not parse version from $bin"
    return 2
  fi

  echo "INFO: $bin reports PHP $ver"

  case "$ver" in
    5.6.*)
      if version_lt "$ver" "5.6.32"; then
        echo "VULNERABLE: $bin is PHP $ver (< 5.6.32)"
        return 1
      else
        echo "PATCHED: $bin is PHP $ver (>= 5.6.32)"
        return 0
      fi
      ;;
    *)
      echo "PATCHED: $bin is not in the affected PHP 5.6.x range"
      return 0
      ;;
  esac
}

if [ ${#uniq_candidates[@]} -eq 0 ]; then
  echo "INFO: no PHP binaries discovered in common paths"
else
  for bin in "${uniq_candidates[@]}"; do
    FOUND=1
    check_php_version "$bin"
    rc=$?
    [ $rc -eq 1 ] && VULN=1
    [ $rc -eq 2 ] && UNKNOWN=1
  done
fi

# Package-manager hints for distro installs/backports
if command -v dpkg-query >/dev/null 2>&1; then
  echo "INFO: dpkg package hints:"
  dpkg-query -W -f='${Package} ${Version}\n' 'php*' 2>/dev/null | grep -E '^(php|libapache2-mod-php|php5|php5.6|php7|php8)' || true
elif command -v rpm >/dev/null 2>&1; then
  echo "INFO: rpm package hints:"
  rpm -qa | grep -Ei '^(php|php56|php5)' || true
fi

if [ $VULN -eq 1 ]; then
  echo "VULNERABLE"
  exit 1
fi

if [ $FOUND -eq 0 ] && [ $UNKNOWN -eq 0 ]; then
  echo "UNKNOWN: no PHP runtime found; check containers, alternate paths, or webserver-specific modules"
  exit 2
fi

if [ $UNKNOWN -eq 1 ]; then
  echo "UNKNOWN"
  exit 2
fi

echo "PATCHED"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: treat this as a legacy-PHP cleanup item, not an emergency outage driver. Because the reassessed verdict is MEDIUM, there is no noisgate mitigation SLA — go straight to the 365-day remediation window; schedule remediation to remove or upgrade all PHP 5.6.x < 5.6.32 runtimes within 365 days under the noisgate remediation SLA, and in the meantime prioritize code review of any features that compile user-supplied regexes or parse free-form untrusted date strings. If you discover one of those risky app patterns on an internet-facing host, manually re-prioritize that host upward even if the fleet-wide plugin stays MEDIUM.

Sources

  1. Tenable Nessus Plugin 104631
  2. PHP 5.6.32 Release Announcement
  3. PHP 5 Changelog
  4. NVD CVE-2016-1283
  5. NVD CVE-2017-16642
  6. PHP Bug #75055 for CVE-2017-16642
  7. Ubuntu USN-3566-1 PHP Vulnerabilities
  8. BitSight Observation Footprint for CVE-2017-16642
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.