-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpycat.py
More file actions
executable file
·207 lines (152 loc) · 5.1 KB
/
Copy pathpycat.py
File metadata and controls
executable file
·207 lines (152 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#!/usr/bin/env python
# PyCat is a very basic netcat type tool
import socket
import sys
import argparse
import threading
import subprocess
options = {
"listen": False,
"command": False,
"upload": False,
"execute": "",
"target": "",
"upload": "",
"port": 0}
def client_handler(client_socket):
# Check for file upload
if len(options['upload']):
# read in the file as a byte stream
file_buffer = ""
# read data until there is none
while True:
data = client_socket.recv(1024)
if len(data):
file_buffer += data
else:
break
# write data to a file
try:
with open(options['upload'], "wb") as f:
f.write(file_buffer)
client_socket.send("Successfully saved file to {}\r\n".format(options['upload']))
except:
client_socket.send("Failed to save file {}\r\n".format(options['upload']))
# Check for command execution
if len(options['execute']):
# Run the command
output = exe_command(options['execute'])
client_socket.send(output)
# Now go into another loop if a command shell was requested
if options['command']:
while True:
# Show a simple prompt
client_socket.send("#~ ")
# Receive until we see a linefeed
cmd_buffer = ""
while '\n' not in cmd_buffer:
cmd_buffer += client_socket.recv(1024)
# Send back the cmd output
response = exe_command(cmd_buffer)
# Send back the response
client_socket.send(response)
def exe_command(cmd):
cmd = cmd.strip()
# Run command and check output for errors
try:
output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
except:
output = "[!] Error executing command"
# Return output to client
return output
def server_loop():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# bind server
server.bind((options['target'], options['port']))
server.listen(5)
print("[*] Server listening on {}:{}".format(options['target'], options['port']))
# Accept new clients and spin them off into their own threads
while True:
client_socket, addr = server.accept()
print("[*] {}:{} connected".format(addr[0], addr[1]))
client_thread = threading.Thread(target=client_handler, args=(client_socket,))
client_thread.start()
def client_send_recv(data):
# open a socket to the target host
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
client.connect((options['target'], options['port']))
# Send our data
if len(data):
client.send(data)
while True:
# Wait for response data
recv_len = 1
response = ""
# recv data and append to response string until
# it stops coming in
while recv_len:
remote_data = client.recv(4096)
recv_len = len(remote_data)
response += remote_data
if recv_len < 4096:
break
print(response),
# Wait for more input
data = raw_input("") + "\n"
# Send it off
client.send(data)
except:
print("[!] Exception: connection error")
# close socket
client.close()
def main():
# read in the buffer from the commandline
# this will block, so send CTRL-D if not sending input
# to stdin
if options["listen"] is False:
data = sys.stdin.read()
client_send_recv(data)
# we are going to listen and potentially
# upload files, execute commands, and drop into a shell
# depending on our command line options above
else:
server_loop()
def parse_arguments():
parser = argparse.ArgumentParser(usage=usage())
parser.add_argument("-t", "--target", type=str, help="the target host", default="0.0.0.0")
parser.add_argument("-p", "--port", type=int, help="the target port", default=8888)
parser.add_argument("-l", "--listen", help="listen on [host]:[port] for incoming connections",
action="store_true")
parser.add_argument("-e", "--execute", type=str,
help="execute the given file upon receiving a connection", default="")
parser.add_argument("-c", "--command", help="initialize a command shell",
action="store_true")
parser.add_argument("-u", "--upload", type=str,
help="upon receiving connection, upload file and write to [destination]", default="")
args = parser.parse_args()
# store user options in global dict
for arg in vars(args):
if arg is not False and arg is not None:
options[arg] = getattr(args, arg)
### DEBUG ###
print(''.join([arg, ': ', str(getattr(args, arg))]))
def usage():
return """
PyCat Net Tool
Usage: pycat.py -t target_host -p port
-l --listen - listen on [host]:[port] for incoming connections
-e --execute=file_to_run - execute the given file upon receiving a connection
-c --command - initialize a command shell"
-u --upload=destination - upon receiving connection upload file and write to [destination]
Examples:
pycat.py -t 192.168.0.1 -p 5555 -l -c
pycat.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe
pycat.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\"
echo 'ABCDEFGHI' | ./pycat.py -t 192.168.11.12 -p 135
"""
if __name__ == "__main__":
parse_arguments()
main()