> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗

Back to Articles

SerializeKiller: Mass Scanning for Java's Billion-Dollar Deserialization Bug

[ View on GitHub ]

SerializeKiller: Mass Scanning for Java's Billion-Dollar Deserialization Bug

Hook

A single HTTP request to the right endpoint can give an attacker complete control of your WebLogic server. In 2015, this wasn't theoretical—it was Tuesday.

Context

The Java deserialization vulnerability (CVE-2015-4852) emerged as one of the most devastating security flaws of the 2010s. The issue? Java's ObjectInputStream accepts serialized objects over the network and automatically reconstructs them—including executing any code within their constructors or readObject() methods. When FoxGlove Security researcher Chris Frohoff demonstrated that common libraries like Apache Commons Collections could be weaponized into "gadget chains," it became clear that virtually every major Java application server was vulnerable to unauthenticated remote code execution.

The blast radius was enormous: Oracle WebLogic, IBM WebSphere, JBoss, Jenkins—platforms running critical infrastructure at Fortune 500 companies worldwide. Attackers didn't need credentials. They didn't need insider knowledge. They just needed to send a crafted serialized object to a listening endpoint. Organizations needed a way to inventory their exposure fast, scanning thousands of servers to identify which systems were at risk. SerializeKiller emerged as a purpose-built tool for exactly this scenario: rapid, non-destructive detection of vulnerable Java application servers across entire networks.

Technical Insight

Fingerprinting

targets

open ports

parallel requests

parallel requests

parallel requests

parallel requests

response text

response text

response text

response text

fingerprint matches

Target List/URL

NMAP Port Scanner

Scanning Queue

WebLogic Checker

Port 7001

WebSphere Checker

Port 9080

JBoss Checker

Port 8080

Jenkins Checker

Port 8080

HTTP Response Parser

Vulnerability Report

System architecture — auto-generated

SerializeKiller's architecture is refreshingly straightforward—it's optimized for speed and safety over comprehensive coverage. The scanner operates in two phases: port discovery and fingerprinting. Rather than attempting active exploitation (which could crash production systems), it relies on identifying servers by their default configurations and HTTP response characteristics.

The core scanning logic targets well-known ports for each application server type. WebLogic typically runs on 7001, WebSphere on 9080, JBoss on 8080, and Jenkins on its default 8080. The tool constructs HTTP requests to specific paths known to exist on these platforms:

def check_weblogic(target, port=7001):
    url = f'http://{target}:{port}/console/login/LoginForm.jsp'
    try:
        response = requests.get(url, timeout=5, verify=False)
        if 'Oracle WebLogic Server' in response.text:
            return True
    except:
        pass
    return False

def check_jboss(target, port=8080):
    url = f'http://{target}:{port}/admin-console/'
    try:
        response = requests.get(url, timeout=5, verify=False)
        if 'JBoss' in response.text or 'WildFly' in response.text:
            return True
    except:
        pass
    return False

This fingerprinting approach is intentionally conservative. The tool doesn't send malicious payloads or attempt to trigger deserialization behavior. Instead, it identifies servers that could be vulnerable based on their identity and version. For WebLogic, detecting the login console's presence is sufficient—if it's an unpatched version, the vulnerability exists at /wls-wsat/CoordinatorPortType.

The parallel scanning capability is where SerializeKiller shines for mass assessment. It accepts a newline-delimited targets file and spawns multiple scanning threads:

from multiprocessing.pool import ThreadPool

def scan_targets(targets_file):
    with open(targets_file) as f:
        targets = [line.strip() for line in f]
    
    pool = ThreadPool(50)  # 50 concurrent threads
    results = pool.map(scan_target, targets)
    pool.close()
    pool.join()
    
    return results

This threading model allows scanning of 1000+ servers in under two minutes, making it practical for large enterprise networks. The tool also integrates with NMAP for initial host discovery, letting security teams start with a CIDR range and automatically enumerate live hosts before fingerprinting.

The WebSphere detection is particularly interesting because it highlights the tool's limitations. WebSphere's vulnerability exists in the SOAP connector, but determining patch status requires examining specific version strings or attempting a test deserialization. SerializeKiller takes the conservative approach of marking any detected WebSphere instance as "possibly vulnerable," acknowledging that definitive verification isn't possible without more invasive testing.

The codebase also reveals its 2015-era origins. It's written in Python 2, uses the older requests library patterns, and has SSL certificate verification disabled by default (verify=False)—a necessary evil when scanning self-signed certificates in enterprise environments, but a reminder that this tool predates modern security best practices. The SSL library compatibility issues mentioned in the repo's issues section stem from Python 2's OpenSSL bindings, which struggle with some TLS configurations used by newer JBoss and Jenkins installations.

Gotcha

SerializeKiller's biggest limitation is its narrow focus on default configurations. If your organization runs WebLogic on port 8443 instead of 7001, or uses a custom context path, the scanner will miss it entirely. This isn't a bug—it's an architectural choice that prioritizes speed over exhaustiveness. The tool assumes you're scanning for low-hanging fruit: servers deployed with out-of-the-box settings that administrators forgot to harden.

The false positive problem with WebSphere is also frustrating in practice. Because the tool can't verify patch status, you'll get alerts for every WebSphere instance it finds, even if your team diligently applied IBM's security patches. This means manual verification work—defeating the purpose of automated scanning. The Python 2 dependency is increasingly problematic as operating systems phase out Python 2 support. You'll likely need to maintain a legacy Python 2 environment or containerize the tool to run it reliably. Finally, the tool only knows about four application servers. If you're running other vulnerable Java applications—custom enterprise software, Apache Solr, or other frameworks susceptible to the same deserialization flaw—SerializeKiller won't flag them. It's a scanner for specific platforms, not a general-purpose deserialization detector.

Verdict

Use SerializeKiller if: You're conducting a rapid security assessment of legacy enterprise infrastructure, need a non-disruptive way to inventory potentially vulnerable Java application servers running on default ports, or want a lightweight tool that can scan thousands of hosts in minutes without requiring commercial licensing. It's particularly valuable if you're dealing with acquisitions or inherited infrastructure where you don't have complete visibility into what's running. Skip if: You need comprehensive coverage beyond the big four platforms, require Python 3 compatibility for modern environments, need definitive patch verification rather than "possibly vulnerable" warnings, or are scanning highly customized deployments. In 2024, this tool is primarily of historical interest—most organizations should use modern vulnerability scanners with updated deserialization detection capabilities. However, if you're specifically hunting for CVE-2015-4852 in a large, legacy environment and need something that runs fast without the overhead of commercial tools, SerializeKiller still delivers on its original promise.