PoC Archive PoC Archive
Medium None assigned as of 2026-07-03 unpatched

Ghidra 12.1.2 Conditional Swift Demangler ACE (plus TraceRMI RCE and SevenZipJBinding Reachability)

by bikini (@ashdfrkl) — original discovery; mirrored via exploitarium · 2026-07-03

Severity
Medium
CVE
None assigned as of 2026-07-03
Category
binary
Affected product
Ghidra (NSA reverse-engineering suite)
Affected versions
12.1.2
Disclosed
2026-07-03
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-03
Last Updated2026-07
Author / Researcherbikini (@ashdfrkl) — original discovery; mirrored via exploitarium
CVE / AdvisoryNone assigned as of 2026-07-03
Categorybinary
SeverityMedium
CVSS ScoreNot yet scored (no CVE/CVSS assigned)
StatusIncomplete PoC
Tagsghidra, reverse-engineering, arbitrary-code-execution, tracermi, sevenzipjbinding, native-parser, conditional-exploit, calc-poc
RelatedN/A

Affected Target

FieldValue
Software / SystemGhidra (NSA reverse-engineering suite)
Versions Affected12.1.2
Language / PlatformJava, Python 3 PoC harnesses
Authentication RequiredLocal-only (requires a configured/restored Swift tool directory, or an exposed TraceRMI debugger-agent channel)
Network Access RequiredNo (Swift demangler path is local); TraceRMI variant requires an untrusted peer reaching an already-established debugger-agent channel

Summary

This entry packages three conditional, defensively-scoped findings against Ghidra 12.1.2 rather than a single unconditional exploit. First, the Swift demangler analyzer builds and launches a swift-demangle executable from a program/analyzer-controlled tool directory, which is local arbitrary code execution if that directory can be redirected to an attacker-controlled binary. Second, TraceRMI debugger-agent implementations (GDB/LLDB) expose command/eval sinks (execute(cmd), pyeval(expr)) that grant code execution to any untrusted peer able to drive an already-created TraceRMI channel. Third, Ghidra bundles an older SevenZipJBinding native archive parser and routes recognized archive bytes into it in-process, a plausible native-parser attack surface given reverse engineers routinely open untrusted archives/firmware images. The author is explicit that these are conditional, calc-only demonstrations (simulated sinks and source-reachability checks) rather than full unauthenticated exploit chains against a stock Ghidra install. This PoC was published by a pseudonymous independent researcher (bikini/ashdfrkl) as part of the uncoordinated “exploitarium” vulnerability dump; it has not been vendor-confirmed.


Vulnerability Details

Root Cause

The Swift demangler analyzer resolves and launches a swift-demangle binary from a configurable tool directory without restricting that directory to a trusted, non-writable location. The TraceRMI debugger-agent implementations expose raw command/eval methods (gdb.execute, LLDB command interpreter, Python eval) directly on the RMI channel without a trust boundary for the connecting peer. SevenZipJBinding’s bundled native archive-parsing code is reachable from Ghidra’s archive-recognition logic on attacker-supplied byte streams.

Attack Vector

  1. Swift demangler: an attacker who can influence the configured/restored Swift tool directory (e.g., via a shared project or imported configuration) plants a malicious swift-demangle; when Ghidra’s Swift analyzer runs, it launches that binary, achieving local code execution.
  2. TraceRMI: an untrusted peer that can reach an already-established TraceRMI debugger-agent channel sends a crafted execute/pyeval command, which the agent runs directly (shell command or Python eval).
  3. SevenZipJBinding: a user opens an attacker-supplied archive/firmware container; Ghidra routes the recognized bytes into the native SevenZipJBinding parser in-process, exposing any native parser bugs.

Impact

Where preconditions are met, arbitrary local code execution in the Ghidra process (Swift demangler, TraceRMI) or a native memory-corruption attack surface reachable via untrusted archive files (SevenZipJBinding). All three require specific configuration or interaction preconditions rather than being reachable from a default, unconfigured Ghidra session.


Environment / Lab Setup

Target:   Ghidra 12.1.2 source checkout (for TraceRMI/SevenZip reachability checks) and/or installed Ghidra (for Swift demangler simulation)
Attacker: Python 3 (stdlib only); optional local calculator (calc.exe / xcalc / gnome-calculator / Calculator.app) as a benign proof marker

Proof of Concept

PoC Script

See ace_swift_demangler_calc_poc.py, rce_tracermi_conditional_calc_poc.py, sevenzip_jbinding_reachability.py, calc_helper.py, and SevenZipReachabilityProbe.java in this folder.

1
2
3
python3 ace_swift_demangler_calc_poc.py --run
python3 rce_tracermi_conditional_calc_poc.py --ghidra-source /path/to/ghidra-12.1.2
python3 sevenzip_jbinding_reachability.py --ghidra-source /path/to/ghidra-12.1.2

The Swift demangler script creates a fake swift-demangle tool and simulates the process-launch sink, optionally launching the local calculator as a benign marker. The TraceRMI script scans a Ghidra source checkout for execution-capable agent methods and emits calc-only command shapes for those sinks. The SevenZipJBinding script performs benign source-reachability and harmless archive-sample checks rather than triggering an actual memory-corruption bug.


Detection & Indicators of Compromise

Signs of compromise:

  • Ghidra spawning unexpected child processes during Swift symbol demangling
  • TraceRMI channel activity from peers outside the expected debugger-host relationship
  • Crashes or anomalous behavior in Ghidra’s native archive-parsing path when opening untrusted files

Remediation

ActionDetail
Primary fixNo vendor patch confirmed as of 2026-07-03 — monitor for advisory
Interim mitigationRestrict the Swift tool directory to a trusted, non-writable path; require authentication/trust verification before exposing TraceRMI debugger-agent channels to any peer; treat archive files opened for analysis as untrusted and consider sandboxing native archive-parsing components such as SevenZipJBinding

References


Notes

Mirrored from https://github.com/bikini/exploitarium (folder: ghidra-12.1.2-rce-ace-calc-poc) on 2026-07-03. No CVE has been assigned as of ingestion — this is an uncoordinated disclosure by a pseudonymous researcher; treat with appropriate caution pending vendor confirmation. The source README explicitly frames all three findings as conditional (precondition-gated) rather than unconditional, default-reachable exploits, and the included scripts are calc-only/reachability demonstrations rather than full weaponized exploit chains.

ace_swift_demangler_calc_poc.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/env python3
import argparse
import platform
import subprocess
from pathlib import Path

from calc_helper import launch_calc, make_executable, shell_script_header, write_marker


def default_out_dir() -> Path:
    return Path(__file__).resolve().parent.parent / "artifacts" / "swift-demangler-calc"


def fake_demangler_name() -> str:
    return "swift-demangle.cmd" if platform.system().lower() == "windows" else "swift-demangle"


def build_fake_demangler(fake_demangler: Path, marker: Path, no_calc: bool) -> None:
    lines = [shell_script_header()]
    if platform.system().lower() == "windows":
        lines.extend(
            [
                "echo Swift demangler calc PoC 1.0\n",
                f'echo ran with: %* > "{marker}"\n',
            ]
        )
    else:
        lines.extend(
            [
                "echo 'Swift demangler calc PoC 1.0'\n",
                f'printf "ran with: %s\\n" "$*" > "{marker}"\n',
            ]
        )
    fake_demangler.write_text("".join(lines), encoding="utf-8")
    make_executable(fake_demangler)
    if no_calc:
        return


def main() -> int:
    parser = argparse.ArgumentParser(
        description="Conditional Ghidra Swift demangler path ACE calc PoC."
    )
    parser.add_argument("--run", action="store_true", help="execute the fake demangler")
    parser.add_argument("--no-calc", action="store_true", help="create marker only")
    parser.add_argument("--out-dir", type=Path, default=default_out_dir())
    args = parser.parse_args()

    out_dir = args.out_dir.resolve()
    fake_swift_dir = out_dir / "fake-swift-bin"
    fake_swift_dir.mkdir(parents=True, exist_ok=True)
    marker = out_dir / "swift_demangler_calc_marker.txt"
    fake_demangler = fake_swift_dir / fake_demangler_name()

    build_fake_demangler(fake_demangler, marker, args.no_calc)

    print("Purpose: conditional Swift demangler path ACE calc PoC.")
    print(f"Fake Swift binary directory: {fake_swift_dir}")
    print(f"Fake demangler: {fake_demangler}")
    print(f"Marker file: {marker}")
    print("Simulated Ghidra command shape: swift-demangle --version")
    print("Classification: conditional ACE, not default/open-only RCE.")

    if not args.run:
        print("Dry run only. Re-run with --run to execute the fake demangler.")
        print("Use --no-calc with --run to create only the marker file.")
        return 0

    subprocess.run([str(fake_demangler), "--version"], check=True)
    if not marker.exists():
        raise RuntimeError("Expected marker was not created")

    if args.no_calc:
        print("Calc launch disabled by --no-calc.")
    else:
        launched = launch_calc()
        if launched:
            print("Local calculator launch requested.")
        else:
            print("No platform calculator command was found; marker proves execution.")

    print(f"[created] {marker}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())