1 背景
如果只知道服务器的地址,不知道其提供服务端口号,可以通过扫描所有端口方式发现服务器提供哪些端口。下面使用Python编写脚本扫描服务器端口。
2 代码
服务器有效端口1-65535
2.1 单线程扫描
import socket
import sys
def find_port(ip, timeout, start, end, ports):
for port in range(start, end):
try:
s = socket.socket()
ip_port = (ip, port)
s.settimeout(timeout)
print(ip_port, end='\r')
s.connect(ip_port)
s.close()
ports.append(port)
print(ip_port, " is found")
except ConnectionRefusedError:
pass
except TimeoutError:
pass
print()
if __name__ == "__main__":
ip = "20.20.20.109"
timeout = 0.1
start = 1
end = 65535
if len(sys.argv) > 1:
ip = sys.argv[1]
if len(sys.argv) > 2:
timeout = float(sys.argv[2])
if len(sys.argv) > 3:
start = int(sys.argv[3])
if len(sys.argv) > 4:
end = int(sys.argv[4])
print("Finding, please wait...")
ports = []
find_port(ip, timeout, start, end, ports)
print("Found ports: ")
print(ports)
说明:
- 脚本支持命令参数:
- ip 地址
- timeout 每次连接超时时间
- start 开始端口
- end 结束端口
运行结果:
Finding, please wait...
('20.20.20.109', 22) is found
('20.20.20.109', 902) is found
('20.20.20.109', 5900) is found
('20.20.20.109', 65534)
Found ports:
[22, 902, 5900]
采用单线程扫描1-65535时间比较长,可以缩小搜索范围例如(1-10000)或采样下面多线程方式。
2.2 多线程扫描
import socket
import sys
import threading
def find_port(ip, timeout, start, end, ports = []):
for port in range(start, end):
try:
s = socket.socket()
ip_port = (ip, port)
s.settimeout(timeout)
print(ip_port, end='\r')
s.connect(ip_port)
s.close()
ports.append(port)
print(ip_port, " is found")
except ConnectionRefusedError:
pass
except TimeoutError:
pass
def multi_find_port(ip, timeout, step):
threads = []
ports = []
port = 0
for _ in range(5):
t = threading.Thread(target=find_port, args=(ip, timeout, port + 1, port + step, ports))
threads.append(t)
t.start()
port += step
for t in threads:
t.join()
print()
return ports
if __name__ == "__main__":
ip = "20.20.20.109"
timeout = 0.1
step = 13107
if len(sys.argv) > 1:
ip = sys.argv[1]
if len(sys.argv) > 2:
timeout = float(sys.argv[2])
if len(sys.argv) > 3:
step = int(sys.argv[3])
print("Finding, please wait...")
ports = multi_find_port(ip, timeout, step)
print("Found ports: ")
print(ports)
说明:
- 该脚本启动5个线程来扫描端口
- 命令上参数
- ip 地址
- timeout 每次连接超时时间
- step 每个线程扫描范围
运行结果:
Finding, please wait...
('20.20.20.109', 22) is found
('20.20.20.109', 902) is found
('20.20.20.109', 5900) is found
('20.20.20.109', 65534)
Found ports:
[22, 902, 5900]