Skip to content

Commit 8c12b3a

Browse files
ExtcanaRyExtcanaRy
authored andcommitted
feat: Implemented port range scanning feature
1 parent d8bebb2 commit 8c12b3a

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111

1212
## scan.py
1313

14-
### 使用方法: ``python3 scan.py [目标地址] -i [可选:发包间隔] -p [可选:本地端口] -t [可选:使用的线程数,默认为CPU核心数减一] -do [可选:只显示玩家在线数量大于或等于此数值的服务器] -e [在扫描到服务器后立刻执行的cmd命令,需要用双引号包含,具体使用请使用 -h 参数获取帮助] -v6 [使用IPv6协议]``
15-
14+
### 使用方法: ``python3 scan.py [目标地址] -i [可选:发包间隔] -p [可选:本地端口] -t [可选:使用的线程数,默认为CPU核心数减一] -do [可选:只显示玩家在线数量大于或等于此数值的服务器] -e [在扫描到服务器后立刻执行的cmd命令,需要用双引号包含] -v6 [使用IPv6协议] -r [可选:端口范围]``
1615
#### 描述: 扫描IP上的所有BE协议服务器
17-
18-
#### 注意:目标地址可以填域名,IP或者IP段。如 mc.163.com,11.4.5.14,191.191.81-255.0-255
16+
#### 注意:
17+
* 目标地址可以填域名,IP或者IP段。如 mc.163.com,11.4.5.14,191.191.81-255.0-255
18+
* 端口范围格式为:起始端口-结束端口,默认为1-65535
19+
* -e 参数的具体使用请使用 -h 参数获取帮助
1920

2021
## send.py
2122

scan.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ def split_list(total: int, num_splits: int) -> list:
2222
return split_list
2323

2424

25-
def send_packet(udp_skt: socket.socket, ip: str, port_range: list, interval: float, conn):
25+
def send_packet(udp_skt: socket.socket, ip: str, port_range: list, port_start: int, interval: float, conn):
2626
for port in range(port_range[0], port_range[1]):
27+
port += port_start
2728
try:
2829
udp_skt.sendto(MOTD_PKT, (ip, port))
2930
time.sleep(interval)
@@ -36,14 +37,14 @@ def send_packet(udp_skt: socket.socket, ip: str, port_range: list, interval: flo
3637

3738

3839
prog_mon = 0
39-
def progerss_monitor(conn):
40+
def progerss_monitor(conn, port_count: int):
4041
global prog_mon
4142
prog_mon = 0
4243
while True:
4344
prog_mon_tmp = prog_mon
4445
time.sleep(1)
4546
if prog_mon == prog_mon_tmp:
46-
for i in range(65536-prog_mon):
47+
for i in range(port_count-prog_mon):
4748
try:
4849
conn.send(1)
4950
except BrokenPipeError:
@@ -52,35 +53,39 @@ def progerss_monitor(conn):
5253

5354

5455
is_recving = False
55-
def scanner(udp_skt: socket.socket, addr: str, interval: float, threads: int):
56+
def scanner(udp_skt: socket.socket, addr: str, interval: float, threads: int, port_start: int, port_count: int):
5657
global is_recving, prog_mon
57-
pbar = tqdm(iterable=range(65536), desc="Scaning progress",
58+
pbar = tqdm(iterable=range(port_count), desc="Scaning progress",
5859
leave=False, unit="Port", unit_scale=False)
59-
60+
61+
pbar.write(f"Scanning: {addr}")
62+
6063
if not is_recving:
6164
is_recving = True
6265
threading.Thread(target=recv_packets, args=(
6366
udp_skt, pbar), daemon=True).start()
64-
65-
port_ranges = split_list(65536, threads)
67+
68+
port_ranges = split_list(port_count, threads)
6669

6770
parent_conn, child_conn = mp.Pipe()
6871

6972
threading.Thread(target=progerss_monitor, args=(
70-
child_conn,), daemon=True).start()
73+
child_conn, port_count), daemon=True).start()
7174

7275
for port_range in port_ranges:
7376
mp.Process(target=send_packet, args=(udp_skt, addr,
74-
port_range, interval, child_conn), daemon=True).start()
75-
77+
port_range, port_start, interval, child_conn), daemon=True).start()
78+
7679
for p in pbar:
7780
parent_conn.recv()
7881
prog_mon += 1
7982

80-
time.sleep(3)
83+
time.sleep(1)
84+
85+
pbar.close()
8186

8287

83-
def recv_packets(udp_skt, pbar):
88+
def recv_packets(udp_skt, pbar: tqdm):
8489
server_count = 0
8590
while True:
8691
try:
@@ -101,6 +106,9 @@ def recv_packets(udp_skt, pbar):
101106
f"[Count ] {server_count}",
102107
""]
103108
pbar.write("\n".join(values))
109+
os.makedirs("scan-result", exist_ok=True)
110+
with open(f"scan-result/{time.strftime('%Y-%d-%m-%H-%M')}.txt", "a+") as file:
111+
pbar.write("\n".join(values), file)
104112
if exec_cmd:
105113
threading.Thread(target=exec_cmd_async, args=(exec_cmd, infos), daemon=True).start()
106114
except socket.timeout:
@@ -141,6 +149,8 @@ def exec_cmd_async(cmd: str, variables: dict = [None]) -> None:
141149
+ "version, online, max_player, unique_id, map, gamemode, source_port_v4, source_port_v6, addr and ip")
142150
parser.add_argument("-v6", "--use-ipv6", action="store_true", default=False,
143151
help="use IPv6 instead of IPv4")
152+
parser.add_argument("-r", "--port-range", default="1-65535", type=str,
153+
help="port range to scan, format: start-end")
144154

145155
args, unparsed = parser.parse_known_args()
146156

@@ -151,8 +161,9 @@ def exec_cmd_async(cmd: str, variables: dict = [None]) -> None:
151161
exec_cmd = args.exec_cmd
152162
use_ipv6 = args.use_ipv6
153163
threads = args.threads
164+
port_range = args.port_range.split("-")
154165

155166
udp_skt = get_udp_socket(local_port, use_ipv6=use_ipv6)
156167

157168
for addr in get_ip_list(addr):
158-
scanner(udp_skt, addr, interval, threads)
169+
scanner(udp_skt, addr, interval, threads, int(port_range[0]), int(port_range[1]) - int(port_range[0]))

0 commit comments

Comments
 (0)