Skip to content

Commit 31bd9b3

Browse files
WillowSauceRWillowSauceR
authored andcommitted
Dramatically increase the speed of scanning ports
1 parent 9e410f0 commit 31bd9b3

File tree

4 files changed

+141
-149
lines changed

4 files changed

+141
-149
lines changed

api.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,15 @@ def getLocalHostIP():
1212
return localHostIP
1313

1414
def getTime():
15-
return time.strftime('%H:%M:%S')
15+
return time.strftime('%H:%M:%S')
16+
17+
def log(*content, level: str = "INFO", info: str = ""):
18+
date = time.strftime('%H:%M:%S')
19+
strs = ""
20+
for string in content:
21+
strs += str(string)
22+
content = strs[0:]
23+
if info != "":
24+
print(f"[{date} {info}] {content}")
25+
else:
26+
print(f"[{date}] {content}")

motd.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from random import randint
22
import socket
33
import sys
4-
from api import getLocalHostIP, getTime
4+
from api import getLocalHostIP, getTime, log
55
localHostIP = getLocalHostIP()
66

77

@@ -20,27 +20,27 @@ def recvPacket(sk_send):
2020
infos = []
2121
data1 = data.split(b"MCPE")
2222
infos_byte = data1[1].split(b";")
23-
# print(data)
24-
# print(data1)
25-
# print(infos_byte)
23+
# log(data)
24+
# log(data1)
25+
# log(infos_byte)
2626
for info in infos_byte:
2727
try:
2828
context = info.decode()
2929
except:
3030
context = str(info)[2:-1]
3131
infos.append(context)
32-
print(f"[{getTime()}] Motd: {infos[1]}")
33-
print(f"[{getTime()}] Versin: {infos[3]}/{infos[2]}")
34-
print(f"[{getTime()}] Online: {infos[4]}/{infos[5]}")
32+
log(f"Motd: {infos[1]}")
33+
log(f"Versin: {infos[3]}/{infos[2]}")
34+
log(f"Online: {infos[4]}/{infos[5]}")
3535
try:
36-
print(f"[{getTime()}] Map: {infos[7]}/{infos[8]}")
36+
log(f"Map: {infos[7]}/{infos[8]}")
3737
except:
38-
print(f"[{getTime()}] Map info is unavailable.")
38+
log(f"Map info is unavailable.")
3939
try:
40-
print(f"[{getTime()}] Port(v4/v6): {infos[10]}/{infos[11]}")
40+
log(f"Port(v4/v6): {infos[10]}/{infos[11]}")
4141
except:
42-
print(f"[{getTime()}] Port info is unavailable.")
43-
print(f"[{getTime()}] Source: {addr[0]}:{addr[1]}")
42+
log(f"Port info is unavailable.")
43+
log(f"Source: {addr[0]}:{addr[1]}")
4444

4545
sk_send.close()
4646

@@ -55,5 +55,4 @@ def recvPacket(sk_send):
5555
try:
5656
sendPacket(ip, port)
5757
except:
58-
print(
59-
f"[{getTime()}] Timeout! Server may be offline or blocked motd request.")
58+
log(f"Timeout! Server may be offline or blocked motd request.")

requirements.txt

-28 Bytes
Binary file not shown.

scan.py

Lines changed: 116 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
import sys
33
import threading
44
import time
5-
from os import _exit
5+
import os
6+
import re
67
from random import randint
78

8-
from scapy.all import *
9-
from scapy.layers.inet import IP, UDP
10-
11-
from api import getLocalHostIP
9+
from api import getLocalHostIP, log
1210

1311
localHostIP = getLocalHostIP()
1412
localHostPort = randint(1024, 65535)
1513

14+
socketSendRecv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
15+
socketSendRecv.bind((localHostIP, localHostPort))
16+
1617
try:
1718
TargetAddr = sys.argv[1]
1819
portRange = sys.argv[2]
@@ -25,7 +26,7 @@
2526
try:
2627
timeout = int(sys.argv[4])
2728
except:
28-
timeout = None
29+
timeout = 0
2930

3031
try:
3132
fileName = str(sys.argv[5])
@@ -41,7 +42,8 @@ def getIpList(ip: str):
4142
if os.path.exists(TargetAddr):
4243
with open(TargetAddr, "r") as file:
4344
for ip in file.readlines():
44-
ipList.append(ip[:-1])
45+
ipList.append(ip.split(" | ")[2])
46+
# ipList.append(ip[:-1])
4547
return ipList
4648
try:
4749
int(ip[-1])
@@ -71,154 +73,134 @@ def getIpList(ip: str):
7173
return [ip]
7274

7375

74-
def sendPacket(startPort, count, ip):
75-
port = startPort
76+
def sendPacket(portStart, portEnd, dstAddr):
77+
dstPort = portStart
7678
while True:
7779
if stopThread:
7880
break
79-
Time = time.strftime('%H:%M:%S')
80-
if port % int(count / 5) == 0 and verboseMode == "y":
81-
print(f"[{Time} I] Scaning port: {str(port)} ~ {str(port + int(count / 5))}")
82-
send(IP(src=localHostIP, dst=ip) / UDP(sport=localHostPort, dport=port) /
83-
motdData,
84-
verbose=False)
85-
if port == startPort + count - 1:
81+
if dstPort % int(portEnd / 5) == 0 and verboseMode == "y":
82+
log(f"Scaning port: {str(dstPort)} ~ {str(dstPort + int(portEnd / 5))}", info = "I")
83+
socketSendRecv.sendto(motdData, (dstAddr, dstPort))
84+
if dstPort == portStart + portEnd - 1:
8685
if verboseMode == "y":
87-
print(f"[{Time} I] Port {startPort} ~ {startPort + count} Done")
86+
log(f"Port {portStart} ~ {portStart + portEnd} Done", info = "I")
8887
break
89-
port += 1
88+
dstPort += 1
9089

9190

9291
def startThreads():
9392
global stopThread
9493
if "-" in portRange:
95-
portRangeStart = int(portRange.split("-")[0])
96-
portRangeEnd = int(portRange.split("-")[1])
94+
portStart = int(portRange.split("-")[0])
95+
portEnd = int(portRange.split("-")[1])
9796
else:
98-
portRangeStart = 0
99-
portRangeEnd = 65535
100-
portCount = portRangeEnd - portRangeStart
101-
if portCount < 7:
102-
portCount += 7
103-
singleThreadProcPort = (portCount - (portCount % 7)) / 7
104-
portStartList = []
105-
for i in range(7):
106-
portStartList.append(int(portRangeStart))
107-
portRangeStart += singleThreadProcPort
97+
portStart = 0
98+
portEnd = 65535
10899
ipList = getIpList(TargetAddr)
109-
for ip in ipList:
100+
for dstAddr in ipList:
110101
stopThread = False
111102
print()
112-
print(
113-
f"[{time.strftime('%H:%M:%S')} I] Scaning target: {ip}")
103+
log(f"Scaning target: {dstAddr}", info = "I")
114104
print()
115-
for portStart in portStartList:
116-
if portStart == portStartList[-1]:
117-
t1 = threading.Thread(target=sendPacket, args=(portStart, int(singleThreadProcPort + (portCount % 7)), ip))
118-
else:
119-
t1 = threading.Thread(target=sendPacket, args=(portStart, int(singleThreadProcPort), ip))
120-
t1.setDaemon(True)
121-
t1.start()
105+
# sendPacket(portStart, portEnd, dstAddr)
106+
t1 = threading.Thread(target=sendPacket, args=(portStart, portEnd, dstAddr))
107+
t1.setDaemon(True)
108+
t1.start()
122109
tmpServerCount = serverCount
123-
if timeout:
110+
if timeout != 0:
124111
time.sleep(timeout)
125112
if tmpServerCount == serverCount:
126113
stopThread = True
127114
while threading.enumerate().__len__() != 2: # main and itself
128115
time.sleep(1)
129116

130-
print("BE Server Count: " + str(serverCount))
131-
print("BDS Count: " + str(bdsCount))
132-
print("NK Count: " + str(nkCount))
133-
print("Geyser Count: " + str(geyserCount))
134-
print("Skipped Count: " + str(skipped))
135-
print("Error Count: " + str(error))
136-
print("Total Player Count: " + str(totalPlayerCount))
137-
_exit(0)
138-
139-
140-
t = threading.Thread(target=startThreads)
141-
t.setDaemon(True)
142-
t.start()
143-
144-
bdsCount = 0
145-
nkCount = 0
146-
geyserCount = 0
147-
skipped = 0
148-
error = 0
149-
payloads = []
150-
totalPlayerCount = 0
151-
while True:
152-
try:
153-
sk_rec = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
154-
sk_rec.bind((localHostIP, localHostPort))
155-
data, addr = sk_rec.recvfrom(10240)
156-
date = time.strftime('%H:%M:%S')
157-
if len(data) <= 30:
158-
skipped += 1
159-
print(
160-
f"[{date} R] data length <= 30, may not motd packet, skipped. Source: {addr[0]}:{addr[1]}")
161-
continue
162-
if b"MCPE" not in data:
163-
skipped += 1
164-
print(
165-
f"[{date} R] metadata \"MCPE\" not in packet, may not motd packet, skipped. Source: {addr[0]}:{addr[1]}")
166-
continue
167-
if addr[1] not in payloads:
168-
payloads.append(addr[1])
169-
else:
170-
skipped += 1
171-
print(
172-
f"[{date} R] Duplicate server found, skipped. Source: {addr[0]}:{addr[1]}")
173-
continue
174-
infos = []
175-
data1 = data.split(b"MCPE")
176-
# print("----------------------------------------------------")
177-
# print(data1)
178-
# print()
179-
infos_byte = data1[1].split(b";")
180-
for info in infos_byte:
117+
log("BE Server Count: " + str(serverCount), info = "I")
118+
log("BDS Count: " + str(bdsCount), info = "I")
119+
log("NK Count: " + str(nkCount), info = "I")
120+
log("Geyser Count: " + str(geyserCount), info = "I")
121+
log("Skipped Count: " + str(skipped), info = "I")
122+
log("Error Count: " + str(error), info = "I")
123+
log("Total Player Count: " + str(totalPlayerCount), info = "I")
124+
os._exit(0)
125+
126+
if __name__ == "__main__":
127+
t = threading.Thread(target=startThreads)
128+
t.setDaemon(True)
129+
t.start()
130+
131+
bdsCount = 0
132+
nkCount = 0
133+
geyserCount = 0
134+
skipped = 0
135+
error = 0
136+
payloads = []
137+
totalPlayerCount = 0
138+
while True:
139+
try:
140+
data, addr = socketSendRecv.recvfrom(10240)
141+
date = time.strftime('%H:%M:%S')
142+
if len(data) <= 30:
143+
skipped += 1
144+
log(f"data length <= 30, may not motd packet, skipped. Source: {addr[0]}:{addr[1]}", info = "R")
145+
continue
146+
if b"MCPE" not in data:
147+
skipped += 1
148+
log(f"metadata \"MCPE\" not in packet, may not motd packet, skipped. Source: {addr[0]}:{addr[1]}", info = "R")
149+
continue
150+
if addr not in payloads:
151+
payloads.append(addr)
152+
else:
153+
skipped += 1
154+
log(f"Duplicate server found, skipped. Source: {addr[0]}:{addr[1]}", info = "R")
155+
continue
156+
infos = []
157+
data1 = data.split(b"MCPE")
158+
# log("----------------------------------------------------")
159+
# log(data1)
160+
# log()
161+
infos_byte = data1[1].split(b";")
162+
for info in infos_byte:
163+
try:
164+
context = info.decode()
165+
except:
166+
context = str(info)[2:-1]
167+
infos.append(context)
168+
# log(len(infos))
169+
log(f"Motd: {infos[1]}", info = "R")
170+
log(f"Versin: {infos[3]}/{infos[2]}", info = "R")
171+
log(f"Online: {infos[4]}/{infos[5]}", info = "R")
181172
try:
182-
context = info.decode()
173+
log(f"Map: {infos[7]}/{infos[8]}", info = "R")
183174
except:
184-
context = str(info)[2:-1]
185-
infos.append(context)
186-
print("")
187-
# print(len(infos))
188-
print(f"[{date} R] Motd: {infos[1]}")
189-
print(f"[{date} R] Versin: {infos[3]}/{infos[2]}")
190-
print(f"[{date} R] Online: {infos[4]}/{infos[5]}")
191-
try:
192-
print(f"[{date} R] Map: {infos[7]}/{infos[8]}")
193-
except:
194-
print(f"[{date} R] Map info is unavailable.")
195-
try:
196-
print(f"[{date} R] Port(v4/v6): {infos[10]}/{infos[11]}")
197-
except:
198-
print(f"[{date} R] Port info is unavailable.")
199-
print(f"[{date} R] Source: {addr[0]}:{addr[1]}")
200-
serverCount += 1
201-
totalPlayerCount += int(infos[4])
202-
print(f"[{date} C] {str(serverCount)}")
203-
print(f"[{date} P] {totalPlayerCount}")
204-
if fileName:
205-
with open(fileName, "a+") as file:
206-
file.write(
207-
f"{date} | {serverCount} | {addr[0]} | {addr[1]} | {infos[1]} | {infos[3]} | {infos[4]}\n")
208-
if len(infos) == 10 or len(infos) == 6:
209-
nkCount += 1
210-
elif re.search(b"edicated", data):
211-
bdsCount += 1
212-
elif re.search(b"nukkit", data):
213-
nkCount += 1
214-
elif re.search(b"eyser", data):
215-
geyserCount += 1
216-
sk_rec.close()
217-
except OSError as info:
218-
if verboseMode == "y":
219-
print(f"[{time.strftime('%H:%M:%S')} R] {info}, skipped.")
220-
error += 1
221-
except Exception as info:
222-
print(f"[{time.strftime('%H:%M:%S')} R] {info}, skipped.")
223-
error += 1
224-
pass
175+
log(f"Map info is unavailable.", info = "R")
176+
try:
177+
log(f"Port(v4/v6): {infos[10]}/{infos[11]}", info = "R")
178+
except:
179+
log(f"Port info is unavailable.", info = "R")
180+
log(f"Source: {addr[0]}:{addr[1]}", info = "R")
181+
serverCount += 1
182+
totalPlayerCount += int(infos[4])
183+
log(f"{str(serverCount)}", info = "C")
184+
log(f"{totalPlayerCount}", info = "P")
185+
print("")
186+
if fileName:
187+
with open(fileName, "a+") as file:
188+
file.write(
189+
f"{date} | {serverCount} | {addr[0]} | {addr[1]} | {infos[1]} | {infos[3]} | {infos[4]}\n")
190+
if len(infos) == 10 or len(infos) == 6:
191+
nkCount += 1
192+
elif re.search(b"edicated", data):
193+
bdsCount += 1
194+
elif re.search(b"nukkit", data):
195+
nkCount += 1
196+
elif re.search(b"eyser", data):
197+
geyserCount += 1
198+
#socketSendRecv.close()
199+
except OSError as errorInfo:
200+
if verboseMode == "y":
201+
log(f"{errorInfo}, skipped.", info = "R")
202+
error += 1
203+
except Exception as errorInfo:
204+
log(f"{errorInfo}, skipped.", info = "R")
205+
error += 1
206+
pass

0 commit comments

Comments
 (0)