← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:83347 · CWE-295 · Disclosed 2015-04-29

MySQL 5

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

This is a seatbelt that looks latched until someone opens the door from the outside

BACKRONYM is a client-side cleartext-downgrade flaw in legacy MySQL connection handling. In affected builds, telling the client to use SSL/TLS did not reliably mean encryption was required; a man-in-the-middle could interfere with the handshake and push the session back to plaintext. The plugin tracks Oracle MySQL client library versions 5.1.x, 5.5.x, 5.6.x, and 5.7.x before 5.7.3; the underlying CVE also covers MySQL Connector/C before 6.1.3 and MariaDB before 5.5.44 / 10.0.20.

The vendor MEDIUM label is technically fair in a vacuum, but too high operationally for enterprise patch triage because exploitation requires an attacker to already be on-path between app and database or to control/poison DNS. That makes this a post-compromise or network-positioning issue, not an internet-to-RCE event. The blast radius can still be ugly if your apps talk to databases over shared or hostile networks, but for a 10,000-host patch program this is backlog hygiene, not a front-of-queue emergency.

"Real bug, wrong fire drill: BACKRONYM matters only if an attacker can get on-path or own your DNS."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Gain network position with bettercap/ettercap or DNS spoofing

The attacker first needs to sit between the application host and the MySQL server, or redirect the client to an attacker-controlled endpoint. In practice that means ARP spoofing on the same segment, routing control inside the estate, malicious Wi-Fi/VPN position, or DNS poisoning/hijack that changes where the client connects.
Conditions required:
  • Attacker has internal network access, L2 adjacency, routing influence, or DNS control
  • The application connects to MySQL over TCP rather than a local Unix socket / named pipe
  • The network path is not already pinned inside a trusted tunnel with endpoint identity validation
Where this breaks in practice:
  • Modern segmented networks, private service meshes, and VPC controls reduce easy on-path positioning
  • Many enterprise apps reach local or same-host databases over sockets rather than routed TCP
  • DNS hardening and static service discovery narrow the redirect option
Detection/coverage: EDR will not see this well. Look instead for ARP anomalies, rogue DHCP/DNS behavior, unexpected route changes, or DNS answers for database names deviating from inventory.
STEP 02

Abuse legacy client behavior during the MySQL handshake

A vulnerable client starts a connection expecting SSL/TLS, but pre-5.7.3 behavior treated --ssl as effectively advisory. Oracle changed this in MySQL 5.7.3 so that client-side --ssl became prescriptive, and added MYSQL_OPT_SSL_ENFORCE semantics for the C API.
Conditions required:
  • Client library is vulnerable: Oracle MySQL < 5.7.3, Connector/C < 6.1.3, or comparable legacy MariaDB builds
  • The application depends on legacy --ssl behavior rather than explicit enforced TLS mode / identity validation
  • Connection traverses the attacker-controlled path
Where this breaks in practice:
  • Newer clients fail closed instead of silently falling back
  • Backported distro packages may already contain the fix even when package versions look old
  • Apps that explicitly verify CA/server identity shut this down
Detection/coverage: Version scanners like Nessus catch likely exposure, but they do not prove a reachable downgrade path. Host package provenance matters because distro backports can invalidate naive version checks.
STEP 03

Strip encryption with a custom proxy or published advisory logic

Once on-path, the attacker tampers with the negotiation so the client proceeds without effective TLS guarantees. Public advisory material exists, and NVD tags related references from the original write-up ecosystem as exploit/advisory material, so this is not a purely theoretical research bug.
Conditions required:
  • Client will continue after downgrade instead of failing closed
  • Server and app are reachable by the attacker-controlled relay/proxy
  • No higher-layer tunnel or mutual-authenticated wrapper protects the session
Where this breaks in practice:
  • Enterprise TLS wrappers, SSH tunnels, or private link overlays can make the MySQL-layer bug irrelevant
  • Connection retries, cert requirements, or app-specific error handling may break the attacker workflow
  • The attacker must keep the proxy stable enough not to crash production traffic and reveal themselves
Detection/coverage: You may catch this by comparing expected encrypted sessions against reality: Ssl_cipher empty, connection type reported as plain TCP/IP, or packet captures showing unencrypted MySQL commands on paths that should be encrypted.
STEP 04

Read or alter SQL traffic in transit

If the downgrade succeeds, the attacker can observe credentials, queries, result sets, and can potentially modify data in flight. Impact is mostly confidentiality and integrity of database traffic, not direct code execution on the server.
Conditions required:
  • Useful SQL traffic crosses the compromised path
  • Application credentials have meaningful database permissions
  • Attacker maintains session continuity without obvious outages
Where this breaks in practice:
  • Least-privilege DB accounts constrain what altered traffic can do
  • App-layer integrity checks, signed business workflows, or out-of-band reconciliations can expose tampering
  • Database audit trails may reveal odd client/source patterns if the proxy changes connection characteristics
Detection/coverage: DB logs and app telemetry may show strange source addresses, changed connection types, or unexpected query outcomes, but a clean in-path proxy can be hard to distinguish from normal client behavior.
03 · Intelligence Metadata

The supporting signals.

CVE mappingtenable:83347 maps to CVE-2015-3152.
In-the-wild statusNo current KEV listing was found in the CISA Known Exploited Vulnerabilities catalog page reviewed, and I found no primary-source reporting of active campaigns abusing this exact CVE.
Proof-of-concept availabilityPublic exploit/advisory material exists. NVD links the original Duo write-up ecosystem and tags mysqlblog.fivefarmers.com as Exploit, with Packet Storm also referenced.
EPSSTenable currently shows EPSS 0.51876 for CVE-2015-3152. Treat that as attacker-interest telemetry, not proof that the on-path prerequisite disappears.
KEV statusNot listed in CISA KEV. That matters: there is no public U.S. federal exploitation mandate signal here.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N = network reachable in theory, but high attack complexity because the attacker must gain MITM/DNS position first.
Affected versionsPrimary plugin scope: Oracle MySQL client library 5.1.x / 5.5.x / 5.6.x / 5.7.x before 5.7.3. Broader CVE scope also includes MySQL Connector/C before 6.1.3 and MariaDB before 5.5.44 / 10.0.20.
Fixed versionsOracle changed client behavior in MySQL 5.7.3 so --ssl became prescriptive and added MYSQL_OPT_SSL_ENFORCE; distro channels may instead carry backports under Debian/Red Hat advisories without upstream-looking version numbers.
Exposure / scanning realityShadowserver reported 3,957,457 MySQL servers on IPv4 port 3306 and 2,279,908 accessible with a server greeting on 2022-05-26. Useful context, but this CVE is client-side, so exposed-server counts overstate true exploitable population.
Disclosure / reportingPublic disclosure traces to oCERT-2015-003 and the Duo Security research/publication cycle in late April 2015; NVD publication followed on 2016-05-16.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.2/10)

The decisive factor is the attacker-position requirement: this bug is only useful if the adversary can already get on-path or poison DNS for the app-to-DB connection. That makes it a post-initial-access/network-manipulation issue with a sharply smaller real-world exposure pool than the vendor baseline implies.

HIGH Version mapping from `tenable:83347` to CVE-2015-3152 and fixed-version behavior change
MEDIUM Operational severity downgrade based on enterprise network friction and typical deployment patterns
MEDIUM No current active-exploitation signal in public primary sources reviewed

Why this verdict

  • Start from MEDIUM 5.9: the underlying impact is real because successful exploitation exposes or alters live SQL traffic.
  • Subtract hard for attacker position: this is not unauthenticated internet-to-service exploitation; it needs MITM placement or DNS control, which usually implies prior compromise, insider position, or network abuse capability.
  • Subtract again for reachable population: the vulnerable side is the client library, not just the server daemon, and many enterprise DB paths stay on private networks, local sockets, or already trusted overlays.
  • No exploitation amplifier: there is no KEV signal and I found no primary-source campaign reporting for this CVE, so there is no reason to override friction with urgency.
  • Impact is bounded: the outcome is traffic disclosure/manipulation, not default RCE or host takeover.

Why not higher?

Because the exploit chain starts with a strong prerequisite that modern programs should already make hard: getting between the application and the database or owning DNS for that relationship. If you cannot reach that position, the bug does nothing. It also does not hand an external attacker direct code execution on the MySQL host.

Why not lower?

Because once an attacker is on-path, the downgrade can quietly expose credentials and business data or let them tamper with query results. Legacy MySQL client code is still common in brownfield estates, so the condition is narrow but not exotic.

05 · Compensating Control

What to do — in priority order.

  1. Force private DB paths — Keep application-to-MySQL traffic on private segments, sockets, or dedicated overlays so an attacker cannot easily obtain the required MITM position. For a LOW verdict there is no SLA; treat this as backlog hygiene and align it with normal network-hardening work.
  2. Require identity-validated TLS — Move clients to enforced TLS modes that fail closed and verify the server identity, not just 'try SSL'. This directly removes the downgrade condition; for LOW, schedule it as backlog hygiene alongside client-library modernization.
  3. Reduce DNS trust for DB endpoints — Use static service discovery, tightly scoped internal DNS, and monitoring for changes to database records to make redirection attacks harder. For this LOW finding, fold the work into routine platform engineering rather than emergency change windows.
  4. Watch for plaintext MySQL — Baseline where MySQL traffic should be encrypted, then alert on sessions that show plain TCP MySQL where TLS is expected. This is a cheap detective control and fits backlog hygiene timing for a LOW issue.
What doesn't work
  • Setting legacy client --ssl on affected versions and assuming that means must encrypt. That assumption is the bug.
  • Closing public port 3306 alone. Helpful generally, but this vulnerability can still matter on east-west paths inside your estate.
  • Server-side TLS support by itself. If the client does not enforce or validate it, the attacker can still aim for fallback behavior.
06 · Verification

Crowdsourced verification payload.

Run this on the application host or database client host, not on your scanner, because the flaw lives in the client library / client binary behavior. Invoke it as python3 verify_backronym.py with no arguments; standard user privileges are usually enough, but package-manager queries may return less detail without elevated rights.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# verify_backronym.py
# Heuristic checker for BACKRONYM / CVE-2015-3152 exposure on local hosts.
# Outputs exactly one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

import os
import re
import subprocess
import sys
from shutil import which

EXIT_PATCHED = 0
EXIT_VULN = 1
EXIT_UNKNOWN = 2


def run(cmd):
    try:
        p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=8)
        return p.returncode, (p.stdout or '') + (p.stderr or '')
    except Exception:
        return 127, ''


def parse_version(text):
    # Accepts versions like 5.7.2, 5.5.44-MariaDB, 10.0.19-MariaDB
    m = re.search(r'(\d+)\.(\d+)\.(\d+)', text)
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def cmp_ver(a, b):
    return (a > b) - (a < b)


def collect_evidence():
    evidence = []

    candidates = [
        ['mysql', '--version'],
        ['mysql_config', '--version'],
    ]

    for cmd in candidates:
        if which(cmd[0]):
            rc, out = run(cmd)
            if out.strip():
                evidence.append(('binary', cmd[0], out.strip()))

    # Package manager hints. These can be ambiguous because distros backport fixes.
    pkg_cmds = [
        ['rpm', '-qa'],
        ['dpkg-query', '-W', '-f=${Package} ${Version}\n'],
    ]

    for cmd in pkg_cmds:
        if which(cmd[0]):
            rc, out = run(cmd)
            if rc == 0 and out:
                for line in out.splitlines():
                    l = line.lower()
                    if any(x in l for x in ['mysql', 'mariadb', 'libmysqlclient', 'mysql-community', 'connector/c']):
                        evidence.append(('package', cmd[0], line.strip()))

    return evidence


def decide(evidence):
    # Prefer direct binary evidence over package names.
    binary_text = ' | '.join(x[2] for x in evidence if x[0] == 'binary')
    package_text = ' | '.join(x[2] for x in evidence if x[0] == 'package')

    if not evidence:
        return 'UNKNOWN', 'No MySQL/MariaDB client evidence found on host.'

    text = (binary_text or package_text).strip()
    t = text.lower()
    ver = parse_version(text)

    if not ver:
        return 'UNKNOWN', 'Version string could not be parsed.'

    # Distro package streams often backport without matching upstream versioning.
    if package_text and not binary_text:
        return 'UNKNOWN', 'Only package-manager evidence found; distro backports may already include the fix.'

    # MariaDB logic from NVD/oCERT change history.
    if 'mariadb' in t:
        if ver[0] == 5 and ver[1] == 5:
            if cmp_ver(ver, (5, 5, 44)) < 0:
                return 'VULNERABLE', f'MariaDB client appears older than 5.5.44: {ver}'
            return 'PATCHED', f'MariaDB client appears at or above 5.5.44: {ver}'
        if ver[0] == 10 and ver[1] == 0:
            if cmp_ver(ver, (10, 0, 20)) < 0:
                return 'VULNERABLE', f'MariaDB client appears older than 10.0.20: {ver}'
            return 'PATCHED', f'MariaDB client appears at or above 10.0.20: {ver}'
        return 'UNKNOWN', f'MariaDB detected, but version branch is not directly covered by this heuristic: {ver}'

    # Oracle/Percona/MySQL client heuristic aligned to plugin scope.
    if 'mysql' in t:
        if cmp_ver(ver, (5, 7, 3)) < 0:
            return 'VULNERABLE', f'MySQL client appears older than 5.7.3: {ver}'
        return 'PATCHED', f'MySQL client appears at or above 5.7.3: {ver}'

    return 'UNKNOWN', 'Unable to classify local client software.'


def main():
    evidence = collect_evidence()
    verdict, reason = decide(evidence)

    # Keep primary output machine-friendly.
    print(verdict)
    # Send evidence to stderr for operators.
    print(reason, file=sys.stderr)
    for kind, source, line in evidence[:20]:
        print(f'[{kind}:{source}] {line}', file=sys.stderr)

    if verdict == 'PATCHED':
        sys.exit(EXIT_PATCHED)
    if verdict == 'VULNERABLE':
        sys.exit(EXIT_VULN)
    sys.exit(EXIT_UNKNOWN)


if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not treat tenable:83347 as a stop-everything patch wave. First, inventory where legacy MySQL client libraries are actually used on app hosts and identify the subset whose DB traffic crosses shared, routed, or otherwise untrusted network paths; that is the only slice that deserves attention. For a LOW verdict there is no noisgate mitigation SLA and no noisgate remediation SLA—treat it as backlog hygiene—but fold compensating controls into normal network/TLS hardening and retire vulnerable client versions during your routine legacy middleware refresh cycle. If you find a sensitive app talking to MySQL across a hostile/shared segment, pull that one forward out of backlog on exposure grounds, not because this CVE is broadly urgent.

Sources

  1. Tenable plugin 83347
  2. NVD CVE-2015-3152
  3. oCERT-2015-003 MySQL SSL/TLS downgrade
  4. Oracle MySQL encrypted connections documentation
  5. Oracle MySQL 5.7 release notes
  6. CISA Known Exploited Vulnerabilities catalog
  7. Shadowserver MySQL exposure scan results
  8. Ubuntu CVE tracker for CVE-2015-3152
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.