← Back to Feed CACHED · 2026-09-21 08:02:48 · CACHE_KEY tenable:320139
tenable:320139 · CWE-825 · Disclosed 2026-06-09

OpenSSL 1.1.1 < 1.1.1zh Multiple Vulnerabilities

ASSESSED — NOISGATE
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

Someone left a loaded gun in the junk drawer — it only fires if you open that specific drawer, but the whole house is past its warranty

CVE-2026-45447 is a heap use-after-free in OpenSSL's PKCS7_verify() function. When a specially crafted PKCS#7 or S/MIME signed message arrives with an empty SignedData.digestAlgorithms ASN.1 SET, OpenSSL frees a caller-owned BIO while the application still holds a reference. Depending on heap allocator behavior, this yields crashes, heap corruption, or potentially attacker-controlled code execution. It affects every OpenSSL release line — 1.0.2 through 4.0 — but the fix for 1.1.1 (version 1.1.1zh) is only available through paid extended support because 1.1.1 went EOL in September 2023. The remaining four CVEs in this plugin (CVE-2026-7383, CVE-2026-34180, CVE-2026-42766, CVE-2026-9076) are all rated Low by OpenSSL and require impractical preconditions like half-a-gigabyte attacker-controlled strings or >2 GB ASN.1 primitive elements.

The user-reported vendor severity of MEDIUM understates the risk. OpenSSL's own advisory rates CVE-2026-45447 as High (CVSS 8.1, AC:H), and Tenable's VPR of 7.6 (98th percentile) agrees. The MEDIUM label likely comes from an aggregated bulletin (e.g., HKCERT) that averages across all 18 CVEs in the June 2026 advisory. That averaging hides the headline bug. The four Low-severity CVEs are noise — the entire plugin's priority should be driven by CVE-2026-45447 and the fact that you're running a library three years past end-of-life.

"Legacy PKCS7 API carries a real RCE path; the EOL status is the louder alarm"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Deliver crafted PKCS#7 / S/MIME message

The attacker constructs a malformed PKCS#7 SignedData structure with the digestAlgorithms field present as an empty ASN.1 SET. This payload is delivered as an S/MIME email attachment, a signed document, or any data stream processed by an application calling PKCS7_verify(). No authentication is required. The PoC structure is trivial to generate with standard ASN.1 tooling.
Conditions required:
  • Target application must call PKCS7_verify() (not CMS APIs) on attacker-controlled input
  • Network path to deliver the message (email, HTTP upload, API endpoint)
Where this breaks in practice:
  • Most modern applications have migrated to CMS APIs — only legacy PKCS#7 callers are affected
  • The TLS stack does not call PKCS7_verify(), so HTTPS endpoints are not directly exploitable via handshake
Detection/coverage: Tenable plugin 320139 (credentialed version check). Qualys QID equivalent expected. No network-level signature — the payload is inside a valid ASN.1 envelope.
STEP 02

Trigger use-after-free in PKCS7_verify()

When the target application passes the crafted message to PKCS7_verify(), OpenSSL encounters the empty digestAlgorithms SET and frees the caller-owned BIO object. The calling application is not notified. On the next use or deallocation of that BIO by the application, a use-after-free condition occurs. This is deterministic — the empty SET always triggers the incorrect free.
Conditions required:
  • Application must actually invoke signature verification on the untrusted input (not just parse headers)
Where this breaks in practice:
  • Some applications validate ASN.1 structure before calling PKCS7_verify(), which may reject the empty SET
  • Applications that discard the BIO immediately after verification reduce the exploitation window
STEP 03

Achieve heap corruption or crash

The freed BIO's memory may be reallocated to a new object. When the application subsequently uses the stale BIO pointer, it reads or writes into the new object's memory. In the common case this produces a crash (DoS). The 0xBlackash PoC on GitHub demonstrates the crash path but deliberately excludes weaponized code.
Conditions required:
  • Heap allocator must reallocate the freed region in a predictable way for controlled exploitation
Where this breaks in practice:
  • Modern glibc heap hardening (tcache key checks, safe-linking in glibc ≥2.32) and ASLR make controlled exploitation significantly harder
  • CVSS rates this AC:H for exactly this reason
STEP 04

Escalate to remote code execution

If the attacker wins the heap layout race — placing a controlled object in the freed BIO's slot — they can redirect execution through corrupted function pointers in the BIO vtable. This gives arbitrary code execution in the context of the application process. On an email gateway or web application, this means full host compromise. No public weaponized exploit exists as of September 2026.
Conditions required:
  • Favorable heap layout (application-specific, requires target profiling)
  • No memory-safety mitigations intercepting the corrupted pointer (CFI, shadow stacks)
Where this breaks in practice:
  • No known weaponized exploit in the wild
  • Heap grooming across a network boundary (S/MIME, HTTP) adds significant unreliability
  • Control-flow integrity in hardened builds (e.g., Fedora/RHEL with -fcf-protection) blocks vtable hijack
Detection/coverage: EDR behavioral detection on anomalous child process spawning or memory corruption signals. CrowdStrike, SentinelOne, and Defender for Endpoint have generic UAF exploitation heuristics.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNot observed. No confirmed campaigns. Not listed in CISA KEV as of 2026-09-21. No GreyNoise or Shadowserver tags for this CVE.
Proof of conceptCrash PoC available. 0xBlackash/CVE-2026-45447 — bash script demonstrating the crash path. Authors explicitly exclude weaponized exploit code. No public RCE exploit chain.
EPSS3.57% (88.8th percentile) — elevated probability of exploitation within 30 days relative to all CVEs, but well below the ~6%+ threshold that typically correlates with imminent weaponization.
CISA KEVNot listed as of 2026-09-21.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H — 8.1 HIGH. Network-reachable, no auth, no user interaction, but Attack Complexity: High reflects the heap exploitation difficulty. Scope unchanged.
Affected versionsOpenSSL 1.1.1 through 1.1.1zg. Also affects 1.0.2–1.0.2zp, 3.0.0–3.0.20, 3.4.0–3.4.5, 3.5.0–3.5.6, 3.6.0–3.6.2, 4.0.0. Only PKCS#7 API callers — CMS API users are not affected.
Fixed versions1.1.1zh (extended support only). Mainstream fixes: 3.0.21, 3.4.6, 3.5.7, 3.6.3, 4.0.1. Distro backports: RHSA-2026:66524 (RHEL), Ubuntu USN tracking, SUSE advisory pending.
Exposure footprintOpenSSL 1.1.1 went EOL September 2023. Shodan historically showed ~16K publicly accessible servers advertising 1.1.1 banners, though many are behind load balancers. The real footprint is internal — embedded in appliances, legacy app servers, and IoT firmware.
Disclosure date2026-06-09 — OpenSSL Security Advisory covering 18 CVEs across all supported branches.
Credited researcherNot publicly attributed in the OpenSSL advisory. CWE-825 (Expired Pointer Dereference).
04 · The Call

Final Verdict
UPGRADED to HIGH (7.5/10)

Why this verdict

  • Headline CVE drives the bus: CVE-2026-45447 (CVSS 8.1) is a network-reachable use-after-free with no auth required. The other four CVEs are all OpenSSL-rated LOW with impractical prerequisites (>2 GB inputs, absent CMS fields). The plugin severity must be anchored to the worst CVE.
  • MEDIUM label is an artifact of bulletin averaging: The user-reported MEDIUM likely reflects HKCERT's aggregate rating across the full 18-CVE advisory. OpenSSL itself rates CVE-2026-45447 as HIGH. Tenable's VPR of 7.6 (98th percentile) confirms. We upgrade to match the dominant risk.
  • Friction: PKCS7_verify() is a narrow attack surface. The TLS stack does not call this function, eliminating the largest class of OpenSSL-consuming applications from the attack path. Only applications that explicitly verify PKCS#7 or S/MIME signatures on untrusted input are reachable. This is a meaningful narrowing from 'all OpenSSL users' but not enough to downgrade below HIGH.
  • Friction: AC:H + no weaponized exploit. Heap exploitation across a network boundary requires target-specific heap grooming. No public RCE exploit exists. The crash PoC confirms the bug is real but the RCE path is unproven in the wild. EPSS at 3.57% is elevated but not alarming.
  • Role multiplier: OpenSSL is *the* canonical TLS/crypto library — it runs on virtually every Linux server, appliance, and container in the fleet. However, the *specific* attack surface (PKCS7_verify on untrusted input) concentrates risk on: (a) email gateways / MTA plugins processing S/MIME (high-value, network edge — RCE here means mail-tier compromise), (b) PHP applications using openssl_pkcs7_verify() on user uploads (web-tier compromise), (c) package/artifact verification pipelines using legacy PKCS#7 (supply-chain tier). On a domain controller or hypervisor, PKCS7_verify() is unlikely to be called on untrusted input, so the DC/hypervisor role is not in-scope for this chain. The worst plausible high-value outcome is RCE on an S/MIME-processing email gateway — this is host-level compromise on a network-edge system, justifying a HIGH floor.
  • EOL amplifier: OpenSSL 1.1.1 has been EOL since September 2023. Running it at all means you're accumulating unpatched CVEs and the fix (1.1.1zh) requires a paid extended support contract. This isn't a CVSS factor but it's an operational severity multiplier that should accelerate your migration timeline.

Why not higher?

CRITICAL would require a reliable, unauthenticated RCE chain with low attack complexity. Here, AC:H is warranted — heap exploitation through a freed BIO vtable requires favorable allocator state that varies by application, libc version, and heap mitigations. No weaponized exploit exists. The attack surface is narrowed to PKCS7_verify() callers processing untrusted input, not all OpenSSL consumers. EPSS at 3.57% is well below the levels seen for actively exploited CVEs.

Why not lower?

The use-after-free is deterministic — the empty digestAlgorithms SET reliably triggers the incorrect BIO free. A crash PoC exists publicly. The CVSS vector is AV:N/PR:N/UI:N, meaning any application exposing PKCS#7 verification to the network is reachable without authentication. S/MIME email gateways are a realistic, high-value target class. Dropping to MEDIUM would ignore the RCE potential on network-edge infrastructure and the EOL status of the library.

05 · Compensating Control

What to do — in priority order.

  1. Audit for PKCS7_verify() callers in your application inventory — The attack surface is limited to applications calling the legacy PKCS#7 API on untrusted data. Run grep -r 'PKCS7_verify\|openssl_pkcs7_verify' /your/codebase and check dynamically linked applications with nm -D or objdump -T against libssl/libcrypto. Prioritize any hits on internet-facing services (email gateways, web apps). Deploy within 30 days per noisgate mitigation SLA for HIGH.
  2. Migrate off OpenSSL 1.1.1 to a supported branch — OpenSSL 1.1.1 has been EOL since September 2023. The real fix is migrating to 3.4.x LTS, 3.5.x, 3.6.x, or 4.0.x. If you're paying for extended support, apply 1.1.1zh immediately. If you're not paying for extended support, you're not getting patches at all and migration is the only path. Target remediation within 180 days per noisgate remediation SLA for HIGH.
  3. Block or quarantine malformed S/MIME at the email gateway — If your email infrastructure processes S/MIME, configure your email security gateway (Proofpoint, Mimecast, Microsoft Defender for Office 365) to strip or quarantine S/MIME signed messages with malformed ASN.1 structures. This is a blunt instrument but reduces the primary delivery vector. Deploy within 30 days.
  4. Enable ASLR and heap hardening on all hosts — Ensure ASLR is enabled (/proc/sys/kernel/randomize_va_space = 2) and that you're running glibc ≥2.32 with safe-linking enabled. These mitigations don't prevent the use-after-free but significantly raise the bar for achieving controlled code execution from a crash. Verify immediately.
  5. Deploy WAF rules for PKCS#7 content types on web application endpoints — If web applications accept PKCS#7 uploads (content-type application/pkcs7-mime or application/x-pkcs7-mime), add WAF rules to inspect and rate-limit these uploads. This provides defense-in-depth for the PHP openssl_pkcs7_verify() attack path.
What doesn't work
  • Upgrading TLS configuration (cipher suites, protocol versions) — The TLS stack does not call PKCS7_verify(). TLS hardening is always good practice but does not mitigate this specific vulnerability.
  • Network segmentation alone — If the vulnerable application is an email gateway, it *must* be network-reachable to function. Segmentation helps contain post-exploitation lateral movement but doesn't prevent the initial exploit.
  • Disabling PKCS#7 at the OpenSSL config level — OpenSSL does not provide a configuration knob to disable the PKCS#7 API. The code is compiled in and callable by any linked application. You cannot 'turn off' PKCS7_verify() without recompiling.
06 · Verification

Crowdsourced verification payload.

Run this script on each target host as any user with read access to the OpenSSL binary. Invoke with: bash check_cve_2026_45447.sh — no arguments needed. It checks the installed OpenSSL version against the patched release (1.1.1zh). For fleet-wide use, push via Ansible/Salt/SSH and collect exit codes (0 = patched, 1 = vulnerable, 2 = unknown).

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_45447.sh
# Checks whether the host is running an OpenSSL 1.1.1 version vulnerable to
# CVE-2026-45447 (Heap Use-After-Free in PKCS7_verify)
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

OPENSSL_BIN="${OPENSSL_BIN:-openssl}"

if ! command -v "$OPENSSL_BIN" &>/dev/null; then
  echo "UNKNOWN - openssl binary not found in PATH"
  exit 2
fi

VERSION_STRING=$("$OPENSSL_BIN" version 2>/dev/null)
if [[ -z "$VERSION_STRING" ]]; then
  echo "UNKNOWN - could not determine OpenSSL version"
  exit 2
fi

echo "Detected: $VERSION_STRING"

# Extract major.minor.patch and letter suffix
if [[ "$VERSION_STRING" =~ OpenSSL\ 1\.1\.1([a-z]*) ]]; then
  SUFFIX="${BASH_REMATCH[1]}"
  # 1.1.1zh is the fixed version. Convert suffix to comparable form.
  # Suffixes go: (empty), a, b, ..., z, za, zb, ..., zg, zh
  # We need to check if suffix >= 'zh'
  if [[ -z "$SUFFIX" ]]; then
    echo "VULNERABLE - OpenSSL 1.1.1 (no patch letter) is affected"
    exit 1
  fi
  
  SUFFIX_LEN=${#SUFFIX}
  
  if [[ $SUFFIX_LEN -eq 1 ]]; then
    # Single letter suffix (a-z): all vulnerable
    echo "VULNERABLE - OpenSSL 1.1.1${SUFFIX} < 1.1.1zh"
    exit 1
  elif [[ $SUFFIX_LEN -eq 2 ]]; then
    # Double letter suffix (za-zz range)
    SECOND_CHAR="${SUFFIX:1:1}"
    if [[ "$SECOND_CHAR" < "h" ]]; then
      echo "VULNERABLE - OpenSSL 1.1.1${SUFFIX} < 1.1.1zh"
      exit 1
    else
      echo "PATCHED - OpenSSL 1.1.1${SUFFIX} >= 1.1.1zh"
      exit 0
    fi
  elif [[ $SUFFIX_LEN -gt 2 ]]; then
    # Suffix longer than 2 chars means newer than zh
    echo "PATCHED - OpenSSL 1.1.1${SUFFIX} >= 1.1.1zh"
    exit 0
  fi
elif [[ "$VERSION_STRING" =~ OpenSSL\ ([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
  MAJOR="${BASH_REMATCH[1]}"
  MINOR="${BASH_REMATCH[2]}"
  PATCH="${BASH_REMATCH[3]}"
  if [[ "$MAJOR" -eq 1 && "$MINOR" -le 0 ]]; then
    echo "VULNERABLE - OpenSSL ${MAJOR}.${MINOR}.${PATCH} is EOL and likely affected (check 1.0.2 separately)"
    exit 1
  elif [[ "$MAJOR" -ge 3 ]]; then
    echo "UNKNOWN - OpenSSL ${MAJOR}.${MINOR}.${PATCH} detected; this script checks 1.1.1 branch only. Check CVE-2026-45447 fixes for your branch."
    exit 2
  fi
else
  echo "UNKNOWN - unrecognized OpenSSL version string: $VERSION_STRING"
  exit 2
fi
07 · Sources

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.