Repository navigation
Expand file tree
/
Copy pathHackerSolver1.1.0.py
More file actions
452 lines (436 loc) · 19.7 KB
/
Copy pathHackerSolver1.1.0.py
File metadata and controls
452 lines (436 loc) · 19.7 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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
import socket
import threading
import subprocess
import argparse
import ipaddress
import os
import sys
import json
import signal
import ctypes
import random
from ctypes import wintypes
def display_banner():
print("888 888 888 .d8888b. 888 ")
print("888 888 888 d88P Y88b 888 ")
print("888 888 888 Y88b. 888 ")
print("8888888888 8888b. .d8888b 888 888 \"Y888b. .d88b. 888 888 888 .d88b. 888d888 ")
print("888 888 \"88b d88P\" 888 .88P \"Y88b. d88\"88b 888 888 888 d8P Y8b 888P\" ")
print("888 888 .d888888 888 888888K \"888 888 888 888 Y88 88P 88888888 888 ")
print("888 888 888 888 Y88b. 888 \"88b Y88b d88P Y88..88P 888 Y8bd8P Y8b. 888 ")
print("888 888 \"Y888888 \"Y8888P 888 888 \"Y8888P\" \"Y88P\" 888 Y88P \"Y8888 888 ")
print(" ")
print(" ")
print(" ")
LEGAL_DISCLAIMER = """
====================================================================================================
【中华人民共和国网络安全合规法律声明】
1. 本工具仅限计算机网络安全课堂教学、个人自有虚拟机靶场练习使用,禁止任何未授权网络探测、远程连接、漏洞扫描行为。
2. 未经设备所有者书面许可,对Windows/macOS/Linux设备执行端口扫描、远程Shell连接、漏洞检测,属于非法侵入计算机信息系统行为。
3. 《刑法》第二百八十五条:非法侵入计算机信息系统,处三年以下有期徒刑或者拘役;造成严重后果的,处三年以上七年以下有期徒刑。
4. 内置低危漏洞字典仅输出风险科普提示,不含漏洞利用、数据窃取、文件破坏、权限提升等攻击性载荷,无实际破坏能力。
5. 远程PowerShell/Bash连接仅支持目标设备主动启动监听服务,不存在静默植入、后台驻留、开机自启等木马功能。
6. 使用者需自行承担全部违规操作带来的民事赔偿、行政处罚、刑事责任;代码作者不承担任何连带法律责任。
7. 若不满足「完全自有/书面授权」使用条件,请立即关闭程序,禁止调用任何功能。
====================================================================================================
"""
FIRST_RUN_FLAG = True
GLOBAL_SOCKETS = []
# ====================== Ctrl+C 中断处理 ======================
def signal_handler(signum, frame):
print("\n\n[!] 捕获 Ctrl+C,正在关闭所有网络连接并安全退出程序...")
for s in GLOBAL_SOCKETS:
try:
s.close()
except Exception:
pass
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
# ====================== 新增:VIRUS端口特征校验 4位 1xx9 ======================
def check_virus_port(port: int) -> bool:
"""端口规则:4位数字,第一位1,最后一位9,中间两位任意"""
port_str = str(port)
# 必须4位
if len(port_str) != 4:
return False
# 首位1,末位9
if port_str[0] == "1" and port_str[-1] == "9":
return True
return False
def random_virus_port() -> int:
"""随机生成符合1xx9规则的4位端口"""
mid1 = random.randint(0,9)
mid2 = random.randint(0,9)
port_num = int(f"1{mid1}{mid2}9")
return port_num
# ====================== 管理员提权工具 ======================
class WinPrivilegeTool:
@staticmethod
def is_admin() -> bool:
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except Exception:
return False
@staticmethod
def run_as_admin():
if WinPrivilegeTool.is_admin():
return True
print("[+] 检测到无管理员权限,拉起管理员权限进程...")
if hasattr(sys, "_MEIPASS"):
exe_path = sys.executable
else:
exe_path = sys.argv[0]
params = " ".join(sys.argv[1:])
class SHELLEXECUTEINFO(ctypes.Structure):
_fields_ = [
("cbSize", wintypes.DWORD),("fMask", wintypes.ULONG),("hwnd", wintypes.HWND),
("lpVerb", ctypes.c_wchar_p),("lpFile", ctypes.c_wchar_p),("lpParameters", ctypes.c_wchar_p),
("lpDirectory", ctypes.c_wchar_p),("nShow", wintypes.INT),("hInstApp", wintypes.HINSTANCE),
("lpIDList", ctypes.c_void_p),("lpClass", ctypes.c_wchar_p),("hKeyClass", wintypes.HKEY),
("dwHotKey", wintypes.DWORD),("hIconOrHBitmap", ctypes.c_void_p),("hProcess", wintypes.HANDLE),
]
SEE_MASK_NOCLOSEPROCESS = 0x00000040
SW_SHOW = 5
sei = SHELLEXECUTEINFO()
sei.cbSize = ctypes.sizeof(SHELLEXECUTEINFO)
sei.fMask = SEE_MASK_NOCLOSEPROCESS
sei.lpVerb = "runas"
sei.lpFile = exe_path
sei.lpParameters = params
sei.nShow = SW_SHOW
ret = ctypes.windll.shell32.ShellExecuteEx(ctypes.byref(sei))
if not ret:
print("[!] UAC提权失败,请右键手动以管理员运行")
input("按回车关闭...")
sys.exit(1)
ctypes.windll.kernel32.WaitForSingleObject(sei.hProcess, 0xFFFFFFFF)
ctypes.windll.kernel32.CloseHandle(sei.hProcess)
sys.exit(0)
@staticmethod
def allow_firewall_port(port: int):
if sys.platform != "win32":
return
rule_name = "HackerSolver_VirusPort"
cmd = (
f'netsh advfirewall firewall show rule name="{rule_name}" >nul 2>&1 || '
f'netsh advfirewall firewall add rule name="{rule_name}" dir=in action=allow protocol=TCP localport={port} enable=yes profile=any'
)
subprocess.call(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
print(f"[+] 防火墙放行特征端口 {port}")
# ====================== 全局配置 ======================
THREAD_COUNT = 50
DEFAULT_TIMEOUT = 0.3
FILE_TRANSFER_BUFFER = 4096
COMMON_PORTS = [21,22,23,80,443,3306,3389,5985,5986,8080,8443,135,139,445]
VULN_DICT = {
"3389":"RDP未开NLA,暴力枚举风险",
"445":"SMB存在历史RCE漏洞",
"22":"SSH弱口令风险",
"80":"Web后台弱口令/目录遍历",
"3306":"MySQL允许远程root"
}
# ====================== CMD工具集 ======================
class CmdTool:
@staticmethod
def run_cmd(cmd:str) -> str:
try:
return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, text=True)
except subprocess.CalledProcessError as e:
return f"命令失败:{e.output}"
# ====================== 网络扫描 ======================
class NetScanner:
@staticmethod
def scan_single_port(ip, port, open_list):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
GLOBAL_SOCKETS.append(sock)
if sock.connect_ex((ip,port)) == 0:
open_list.append(port)
sock.close()
@staticmethod
def port_scan(ip, ports=None):
ports = ports or COMMON_PORTS
open_p = []
threads = []
for p in ports:
t = threading.Thread(target=NetScanner.scan_single_port, args=(ip,p,open_p))
t.start()
threads.append(t)
if len(threads)>=THREAD_COUNT:
[t.join() for t in threads]
threads.clear()
[t.join() for t in threads]
open_p.sort()
return open_p
@staticmethod
def scan_lan(net):
alive = []
net_obj = ipaddress.IPv4Network(net, strict=False)
def ping(ip):
cmd = f"ping -n 1 -w 200 {ip}" if sys.platform=="win32" else f"ping -c1 -W2 {ip}"
res = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if "TTL=" in res.stdout:
alive.append(ip)
threads = []
for host in net_obj.hosts():
ip_str = str(host)
t = threading.Thread(target=ping, args=(ip_str,))
t.start()
threads.append(t)
if len(threads)>=THREAD_COUNT:
[t.join() for t in threads]
threads.clear()
[t.join() for t in threads]
alive.sort(key=lambda x:int(x.split(".")[-1]))
return alive
# ====================== 文件传输模块(增加端口校验) ======================
class FileDropTool:
@staticmethod
def send_file(target_ip, target_port, local_file, save_name):
if not check_virus_port(target_port):
print(f"[错误]{target_port}不符合特征端口规则(4位1xx9),拒绝连接")
return False
if not os.path.exists(local_file):
print(f"[错误]本地文件不存在:{local_file}")
return False
WinPrivilegeTool.allow_firewall_port(target_port)
try:
s = socket.socket()
GLOBAL_SOCKETS.append(s)
s.settimeout(5)
s.connect((target_ip, target_port))
print(f"[+]连接 {target_ip}:{target_port} 开始传输")
s.sendall(save_name.encode("utf-8"))
s.recv(1024)
with open(local_file, "rb") as f:
while chunk := f.read(FILE_TRANSFER_BUFFER):
s.sendall(chunk)
s.sendall(b"__FILE_END__")
print("[+]文件发送完成")
s.close()
return True
except Exception as e:
print(f"传输失败:{e}")
return False
@staticmethod
def start_listen(listen_port):
if not check_virus_port(listen_port):
print(f"[错误]{listen_port}不符合特征端口规则(4位1xx9),无法启动监听")
return
WinPrivilegeTool.allow_firewall_port(listen_port)
s = socket.socket()
GLOBAL_SOCKETS.append(s)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("0.0.0.0", listen_port))
s.listen(1)
print(f"[+]文件监听启动,特征端口 {listen_port},Ctrl+C关闭")
while True:
conn, addr = s.accept()
GLOBAL_SOCKETS.append(conn)
print(f"接入客户端 {addr[0]}:{addr[1]}")
fname = conn.recv(1024).decode("utf-8")
conn.send(b"OK")
with open(fname, "wb") as f:
while True:
data = conn.recv(FILE_TRANSFER_BUFFER)
if b"__FILE_END__" in data:
f.write(data.replace(b"__FILE_END__",b""))
break
f.write(data)
print(f"接收文件:{fname}")
conn.close()
# ====================== 远程Shell(强制校验1xx9端口) ======================
class RemoteShellTool:
@staticmethod
def shell_listen(listen_port, os_type):
if not check_virus_port(listen_port):
print(f"[错误]{listen_port}非法,仅支持4位1开头9结尾端口,示例:1239")
return
WinPrivilegeTool.allow_firewall_port(listen_port)
sock = socket.socket()
GLOBAL_SOCKETS.append(sock)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("0.0.0.0", listen_port))
sock.listen(1)
print(f"[+]{os_type.upper()} Shell监听启动,特征端口 {listen_port}")
print("[Ctrl+C 终止服务]")
while True:
try:
conn, addr = sock.accept()
GLOBAL_SOCKETS.append(conn)
print(f"客户端 {addr[0]} 接入")
while True:
cmd_data = conn.recv(4096)
if not cmd_data:
print("客户端断开")
break
cmd = cmd.decode("utf-8").strip()
if cmd.lower() == "exit":
conn.send("会话关闭")
break
if os_type == "win":
out = subprocess.check_output(["powershell","-Command",cmd],shell=True,stderr=subprocess.STDOUT,text=True)
else:
out = subprocess.check_output(cmd,shell=True,stderr=subprocess.STDOUT,text=True)
buf = out.encode("utf-8")
pos = 0
while pos < len(buf):
conn.send(buf[pos:pos+4096])
pos += 4096
except ConnectionAbortedError:
print("连接中断,等待新客户端")
continue
except Exception:
continue
@staticmethod
def shell_connect(target_ip, target_port):
if not check_virus_port(target_port):
print(f"[拒绝]{target_port}非1xx9特征端口,无法建立远控连接")
return
WinPrivilegeTool.allow_firewall_port(target_port)
try:
s = socket.socket()
GLOBAL_SOCKETS.append(s)
s.settimeout(5)
s.connect((target_ip, target_port))
print(f"[+]成功连接 {target_ip}:{target_port},exit退出会话")
while True:
cmd = input("RemoteShell > ")
s.send(cmd.encode("utf-8"))
if cmd == "exit":
break
resp = b""
while True:
chunk = s.recv(4096)
if not chunk or len(chunk)<4096:
resp += chunk
break
resp += chunk
print(resp.decode("utf-8","replace"))
s.close()
except Exception as e:
print(f"连接失败:{e}")
@staticmethod
def vuln_scan(ip):
print(f"\n[+]扫描 {ip} 教学漏洞")
open_p = NetScanner.port_scan(ip)
print(f"开放端口:{open_p}")
print("="*60)
has = False
for p in open_p:
ps = str(p)
if ps in VULN_DICT:
print(f"端口{p}风险:{VULN_DICT[ps]}")
has = True
if not has:
print("未匹配内置漏洞提示")
print("[仅科普,无攻击载荷]\n")
# ====================== 密码自测 ======================
class CrackTool:
@staticmethod
def crack_pwd(target, dict_path="dict.txt"):
try:
with open(dict_path,"r",encoding="utf-8") as f:
for line in f:
if line.strip() == target:
return f"匹配密码:{target}"
return "字典无匹配"
except FileNotFoundError:
return "字典文件缺失"
# ====================== 主入口 ======================
def main():
global FIRST_RUN_FLAG
try:
if FIRST_RUN_FLAG:
display_banner()
print(LEGAL_DISCLAIMER)
confirm = input("确认仅自有授权设备使用,输入y继续:").strip().lower()
if confirm != "y":
print("程序终止")
return
FIRST_RUN_FLAG = False
WinPrivilegeTool.run_as_admin()
parser = argparse.ArgumentParser(description="HackerSolver 教学工具|特征端口1xx9(4位)")
sub = parser.add_subparsers(dest="mode", required=True)
# 局域网扫描
p_lan = sub.add_parser("lan", help="扫描网段存活主机")
p_lan.add_argument("--net", required=True)
# 端口扫描
p_port = sub.add_parser("port", help="单IP端口扫描")
p_port.add_argument("--ip",required=True)
p_port.add_argument("--ports",nargs="+",type=int)
# 混合扫描
p_mix = sub.add_parser("mix", help="网段批量扫描")
p_mix.add_argument("--net",required=True)
p_mix.add_argument("--ports",nargs="+",type=int)
# 文件发送
p_send = sub.add_parser("drop-send", help="文件发送(仅1xx9端口)")
p_send.add_argument("--target-ip",required=True)
p_send.add_argument("--port",type=int,required=True)
p_send.add_argument("--local-file",required=True)
p_send.add_argument("--save-name",required=True)
# 文件监听
p_droplisten = sub.add_parser("drop-listen", help="文件接收监听(1xx9端口)")
p_droplisten.add_argument("--port",type=int,required=True)
# Shell监听
p_shelllisten = sub.add_parser("shell-listen", help="远控监听 端口1xx9")
p_shelllisten.add_argument("--port",type=int,required=True)
p_shelllisten.add_argument("--os",choices=["win","mac","linux"],required=True)
# Shell连接
p_shellconn = sub.add_parser("shell-conn", help="连接远控 端口1xx9")
p_shellconn.add_argument("--target-ip",required=True)
p_shellconn.add_argument("--port",type=int,required=True)
# 漏洞扫描
p_vuln = sub.add_parser("vuln-scan", help="教学漏洞扫描")
p_vuln.add_argument("--ip",required=True)
# CMD工具
p_cmd = sub.add_parser("cmd", help="本地命令工具")
p_cmd.add_argument("--exec")
p_cmd.add_argument("--list",action="store_true")
# 密码测试
p_crack = sub.add_parser("crack", help="本地密码字典测试")
p_crack.add_argument("--pwd",required=True)
p_crack.add_argument("--dict",default="dict.txt")
# 随机生成合规端口
p_randport = sub.add_parser("rand-port", help="随机生成1xx9特征端口")
args = parser.parse_args()
if args.mode == "lan":
alive = NetScanner.scan_lan(args.net)
print(f"存活主机:{alive}")
elif args.mode == "port":
opens = NetScanner.port_scan(args.ip, args.ports)
print(f"开放端口:{opens}")
elif args.mode == "mix":
alive = NetScanner.scan_lan(args.net)
print(f"存活主机:{alive}")
for ip in alive:
op = NetScanner.port_scan(ip, args.ports)
print(f"[{ip}]开放端口:{op}")
elif args.mode == "drop-send":
FileDropTool.send_file(args.target_ip, args.port, args.local_file, args.save_name)
elif args.mode == "drop-listen":
FileDropTool.start_listen(args.port)
elif args.mode == "shell-listen":
RemoteShellTool.shell_listen(args.port, args.os)
elif args.mode == "shell-conn":
RemoteShellTool.shell_connect(args.target_ip, args.port)
elif args.mode == "vuln-scan":
RemoteShellTool.vuln_scan(args.ip)
elif args.mode == "cmd":
ct = CmdTool()
if args.list:
print("常用系统命令集合")
if args.exec:
print(ct.run(args.exec))
elif args.mode == "crack":
print(CrackTool.crack_pwd(args.pwd, args.dict))
elif args.mode == "rand-port":
rp = random_virus_port()
print(f"随机生成特征端口(1xx9):{rp}")
except Exception as err:
print(f"\n全局异常:{repr(err)}")
finally:
print("\n执行完毕,按回车关闭窗口...")
input()
if __name__ == "__main__":
main()