← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:111665 · Disclosed 2018-07-18

Oracle WebLogic Server Deserialization RCE

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

This is a loaded nail gun left in the server room, not a sniper rifle pointed at every building

CVE-2018-2893 is a pre-auth deserialization RCE in Oracle WebLogic Server's WLS Core Components over the T3 protocol. Oracle lists affected versions as 10.3.6.0, 12.1.3.0, 12.2.1.2, and 12.2.1.3; successful exploitation gives an unauthenticated attacker code execution as the WebLogic process and can end in full server takeover.

Oracle's technical severity is fair in a vacuum: the bug is easy to exploit, no auth is required, and public PoCs plus real attacks followed quickly. But for enterprise patching priority, this is usually one notch below CRITICAL because the attack path starts with T3 reachability, and many production estates do not expose T3 directly to the internet; where 7001/T3 is only reachable internally, this becomes a post-initial-access amplifier instead of a clean edge compromise.

"Pre-auth WebLogic RCE with real exploit history, but it only matters where T3 is actually reachable"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a reachable T3 listener

The attacker fingerprints WebLogic on TCP/7001 or another mapped listener and confirms that T3 is exposed. Commodity tooling now includes Nuclei coverage, and older campaigns simply mass-scanned for port 7001 before attempting exploitation.
Conditions required:
  • Attacker has network reachability to the WebLogic listener
  • T3 is enabled and not blocked by a firewall, security group, or load balancer design
Where this breaks in practice:
  • Many enterprises publish HTTP(S) through reverse proxies but do not expose raw T3
  • Admin and middleware ports are often restricted to app subnets or jump hosts
  • Non-default ports and network ACLs reduce blind internet hit rate
Detection/coverage: Strong external scanner coverage exists; Tenable plugin 111665 and Nuclei both target this condition, but exposure scanners only matter if the listener is actually reachable.
STEP 02

Send the serialized payload

Using public PoCs such as anbai-inc/CVE-2018-2893 or ysoserial-style gadget delivery, the attacker opens a T3 session and sends a crafted serialized object chain. This is the low-friction part once the port is reachable and the target version is unpatched.
Conditions required:
  • Target is one of the affected WebLogic trains or missing the July 2018 CPU fix
  • Java deserialization path is still exposed through T3
Where this breaks in practice:
  • July 2018 CPU or later patching breaks the exploit path
  • Some environments disable or tightly constrain T3/RMI-style channels
  • Middleboxes that only proxy HTTP(S) will not carry this attack
Detection/coverage: Network IDS can catch T3 exploit handshakes and serialized-object patterns; ET/Snort-style coverage exists for WebLogic deserialization traffic.
STEP 03

Land code execution in the JVM

WebLogic deserializes attacker-controlled data and executes the gadget chain inside the Java process, usually leading to command execution or a second-stage fetch. In practice, attackers used the foothold for miners, shell drops, and follow-on staging rather than delicate one-shot actions.
Conditions required:
  • A working gadget chain is present for the runtime
  • The WebLogic process can spawn a shell or reach a staging host
Where this breaks in practice:
  • EDR often flags java spawning sh, bash, cmd, or PowerShell
  • Egress filtering can break payload retrieval
  • Hardened service accounts and containerized deployments can limit blast radius
Detection/coverage: High-quality EDR should alert on suspicious child processes from java; JVM, auditd, Sysmon, and process lineage are useful here.
STEP 04

Pivot from app server to business impact

From there the attacker can steal app secrets, tamper with deployed applications, or pivot deeper into databases and adjacent middleware. The real damage depends less on the bug itself and more on what the WebLogic host can already reach.
Conditions required:
  • WebLogic host has valuable credentials, trust paths, or lateral access
  • Attacker can maintain access after initial RCE
Where this breaks in practice:
  • Segmented application tiers contain the blast radius
  • Short-lived workloads and immutable deployments reduce persistence value
  • App servers without outbound internet or broad east-west access are less useful
Detection/coverage: Post-exploitation is easier to see than the initial flaw: watch credential access, webshell writes, miner deployment, unexpected archives, and lateral movement from middleware nodes.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusYes, historically exploited. CERT-EU and Qualys both documented exploitation shortly after patch release; activity included cryptominer deployment and mass scanning.
Proof-of-concept availabilityPublic PoCs are abundant. See anbai-inc/CVE-2018-2893 and ProjectDiscovery's Nuclei template.
EPSS0.94277 (94.277%) per Tenable's CVE page, placing it in the ~99.9th percentile class of likely exploitation.
KEV statusNot listed in CISA's Known Exploited Vulnerabilities Catalog at time of review, despite historical public exploitation reporting.
CVSS vectorCVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = unauthenticated network RCE with full CIA impact per Oracle and NVD.
Affected versions10.3.6.0, 12.1.3.0, 12.2.1.2, 12.2.1.3 in Oracle WebLogic Server WLS Core Components over T3.
Fixed versionJuly 2018 Critical Patch Update (CPUJul2018) or later. Oracle patched by CPU bundle rather than a neat product major-version jump; do not assume the base train being unchanged means safe.
Exposure and scanning realityInternet scanning was immediate. BleepingComputer and SANS ISC/DShield port 7001 documented spikes against WebLogic's default port. The practical exposure population is still narrower than a normal HTTPS flaw because T3 must be reachable.
Disclosure date2018-07-18 via Oracle's July 2018 CPU, with NVD publication the same day.
Research / reporting trailOracle disclosed the CVE; exploitation tracking was amplified by CERT-EU, Qualys, Tenable, SANS ISC, and campaign reporting around Netlab 360 / Luoxk activity.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (8.6/10)

The decisive factor is attacker reachability to T3, not the theoretical RCE impact. If T3 is not exposed beyond trusted app networks, this flaw is a dangerous post-compromise accelerator, not a universal edge-fire emergency across every WebLogic host.

HIGH Technical exploitability and impact of the vulnerability itself
HIGH Historical public exploitation and PoC availability
MEDIUM How often T3 is truly reachable in modern enterprise deployments

Why this verdict

  • Vendor 9.8 is technically justified: no auth, low complexity, network reachable over T3, and successful exploitation yields full server takeover.
  • Real exploit evidence is not hypothetical: public PoCs landed quickly and defenders observed active attacks and mass scanning shortly after disclosure.
  • First friction cut: attacker position matters. The chain requires unauthenticated network access to T3, which is materially narrower than a routine HTTP/HTTPS edge bug because many enterprises never publish raw T3 externally.
  • Second friction cut: exposure population is limited. WebLogic is common in large estates, but the subset with externally reachable 7001/T3 is far smaller than the total installed base; reverse proxies often front web apps while leaving T3 internal.
  • Third friction cut: modern controls can break the chain after RCE. EDR, egress filtering, and segmentation often catch or blunt the payload execution and follow-on staging, which reduces practical blast radius compared with a silent appliance exploit.

Why not higher?

I am not calling this CRITICAL by default because the exploit path is not universal edge reachability; it hinges on a specific middleware protocol being exposed. In estates where T3 is internal-only, the vulnerability still matters, but it behaves like post-initial-access privilege and lateral movement fuel, not the first domino.

Why not lower?

I am not pushing this to MEDIUM because the technical bug is still pre-auth RCE with a very strong exploitability profile, public tooling, and real attack history. Any environment with reachable T3 on an affected WebLogic host has a serious compromise path with little attacker effort.

05 · Compensating Control

What to do — in priority order.

  1. Block inbound T3 now — Remove TCP/7001 and any alternate T3/T3S listeners from internet reachability and non-required east-west paths. Because there is public exploitation evidence, do this immediately, within hours rather than waiting for the normal HIGH bucket timing.
  2. Constrain WebLogic to trusted app networks — Limit listener access to known application peers, admin jump hosts, and required middleware clients only. Use firewalls, security groups, or Kubernetes network policy and complete this immediately, within hours if any broad reachability exists.
  3. Hunt for Java child-process abuse — Alert on java spawning shells, downloaders, PowerShell, curl, wget, or miner binaries from WebLogic hosts. This does not prevent exploitation, but it is the fastest way to catch successful weaponization while patching proceeds; stand it up immediately, within hours where coverage is missing.
  4. Verify patch state with Oracle inventory — Do not trust base product version alone because Oracle fixed this in a CPU bundle. Validate OPatch / inventory evidence and close the gap on any still-unfixed nodes within the HIGH remediation window.
What doesn't work
  • WAF-only protection does not solve this because the exploit rides T3, not normal HTTP request handling.
  • MFA on the WebLogic console does nothing for a pre-auth T3 deserialization path.
  • Changing the public web URL or hiding /console is irrelevant if the raw listener still accepts T3.
  • AV signatures alone are too late; by the time a dropped miner or shell is detected, the JVM already executed attacker-controlled data.
06 · Verification

Crowdsourced verification payload.

Run this on the target WebLogic host or from your software-audit agent with read access to the Oracle Middleware home. Invoke it as python3 check_cve_2018_2893.py --mw-home /u01/oracle/middleware --listen-port 7001; no root/admin is required, but the account must be able to read the WebLogic install tree. Because Oracle patched this via a CPU overlay, the script will return UNKNOWN for affected base versions unless it can see clear evidence you are on an unaffected train.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_cve_2018_2893.py
# Oracle WebLogic Server CVE-2018-2893 local assessment helper
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=usage/runtime error

import argparse
import os
import re
import socket
import sys
import zipfile
from xml.etree import ElementTree as ET

AFFECTED = {"10.3.6.0", "10.3.6.0.0", "12.1.3.0", "12.1.3.0.0", "12.2.1.2", "12.2.1.2.0", "12.2.1.3", "12.2.1.3.0"}
UNAFFECTED_PREFIXES = ["12.2.1.4", "14."]


def norm(v):
    if not v:
        return None
    v = v.strip()
    if re.fullmatch(r"\d+\.\d+\.\d+\.\d+", v):
        return v
    if re.fullmatch(r"\d+\.\d+\.\d+\.\d+\.\d+", v):
        return v
    return v


def parse_manifest_version(jar_path):
    try:
        with zipfile.ZipFile(jar_path, 'r') as zf:
            for name in ("META-INF/MANIFEST.MF", "meta-inf/manifest.mf"):
                if name in zf.namelist():
                    data = zf.read(name).decode('utf-8', errors='ignore')
                    for line in data.splitlines():
                        if line.lower().startswith("implementation-version:"):
                            return norm(line.split(":", 1)[1].strip())
    except Exception:
        return None
    return None


def find_version_from_registry(mw_home):
    candidates = [
        os.path.join(mw_home, "registry.xml"),
        os.path.join(mw_home, "inventory", "ContentsXML", "comps.xml"),
        os.path.join(mw_home, "oraInventory", "ContentsXML", "comps.xml"),
    ]
    for path in candidates:
        if not os.path.isfile(path):
            continue
        try:
            tree = ET.parse(path)
            root = tree.getroot()
            text = ET.tostring(root, encoding='unicode', method='xml')
            m = re.search(r"12\.2\.1\.4(?:\.0)?|12\.2\.1\.3(?:\.0)?|12\.2\.1\.2(?:\.0)?|12\.1\.3\.0(?:\.0)?|10\.3\.6\.0(?:\.0)?|14\.1\.1\.0(?:\.0)?", text)
            if m:
                return norm(m.group(0))
        except Exception:
            pass
    return None


def find_version_from_jar(mw_home):
    jar_candidates = [
        os.path.join(mw_home, "wlserver", "server", "lib", "weblogic.jar"),
        os.path.join(mw_home, "server", "lib", "weblogic.jar"),
    ]
    for jar in jar_candidates:
        if os.path.isfile(jar):
            v = parse_manifest_version(jar)
            if v:
                return v
    return None


def port_open(host, port, timeout=1.5):
    try:
        with socket.create_connection((host, port), timeout=timeout):
            return True
    except Exception:
        return False


def classify(version, reachable):
    if version is None:
        print("UNKNOWN: could not determine WebLogic version from install tree")
        return 2

    version = norm(version)
    if any(version.startswith(p) for p in UNAFFECTED_PREFIXES):
        print(f"PATCHED: version train {version} is outside the affected range for CVE-2018-2893")
        return 0

    if version in AFFECTED:
        if reachable:
            print(f"VULNERABLE: affected base version {version} detected and listener is reachable; confirm July 2018 CPU/OPatch status immediately")
            return 1
        print(f"UNKNOWN: affected base version {version} detected, but listener was not reachable on the tested port; verify July 2018 CPU/OPatch status")
        return 2

    print(f"UNKNOWN: version {version} not confidently mapped by this checker; verify Oracle CPUJul2018 or later manually")
    return 2


def main():
    ap = argparse.ArgumentParser(description="Local helper for Oracle WebLogic CVE-2018-2893")
    ap.add_argument("--mw-home", help="Middleware home, e.g. /u01/oracle/middleware")
    ap.add_argument("--version", help="Explicit WebLogic version override, e.g. 12.2.1.3")
    ap.add_argument("--host", default="127.0.0.1", help="Host to test for listener reachability (default: 127.0.0.1)")
    ap.add_argument("--listen-port", type=int, default=7001, help="Listener port to test (default: 7001)")
    args = ap.parse_args()

    if not args.version and not args.mw_home:
        print("UNKNOWN: supply --version or --mw-home", file=sys.stderr)
        sys.exit(3)

    version = norm(args.version) if args.version else None
    if version is None and args.mw_home:
        version = find_version_from_registry(args.mw_home) or find_version_from_jar(args.mw_home)

    reachable = port_open(args.host, args.listen_port)
    rc = classify(version, reachable)
    sys.exit(rc)


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

If you remember one thing.

TL;DR
Monday morning, split this into externally reachable T3 and internal-only T3. If any affected WebLogic host exposes 7001/T3 outside trusted app networks, use the noisgate mitigation SLA override for active exploitation evidence and patch / mitigate immediately, within hours by blocking reachability first; then complete vendor patching inside the noisgate remediation SLA for HIGH issues, which is ≤180 days. If T3 is internal-only, still verify segmentation and hunt for compromise indicators the same day, but prioritize actual patching behind internet-exposed middleware and other clean edge RCEs.

Sources

  1. Oracle July 2018 CPU verbose advisory
  2. NVD CVE-2018-2893
  3. CERT-EU advisory 2018-018
  4. Tenable CVE page with EPSS
  5. Qualys ThreatPROTECT write-up
  6. BleepingComputer scan/exploitation reporting
  7. ProjectDiscovery Nuclei template
  8. CISA Known Exploited Vulnerabilities Catalog
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.