Python安全工具开发实战:编写端口扫描器
项目概述
本文将开发一个命令行端口扫描工具,支持以下功能:
- 单IP/IP段扫描
- 常用端口/全端口扫描
- 多线程并发
- 服务版本识别
- 结果输出(JSON/CSV)
基础版本
import socket import threading from queue import Queuedef scan_port(ip, port): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1) result = sock.connect_ex((ip, port)) if result == 0: print(f"[+] {ip}:{port} OPEN") sock.close() except: pass
def main(): target = "192.168.1.1" ports = range(1, 1025) threads = [] for port in ports: t = threading.Thread(target=scan_port, args=(target, port)) threads.append(t) t.start() for t in threads: t.join()
if __name__ == "__main__": main()
优化:异步IO版本
使用asyncio提高扫描效率:
import asyncio import socketasync def scan_port_async(ip, port): try: _, writer = await asyncio.wait_for( asyncio.open_connection(ip, port), timeout=1 ) writer.close() await writer.wait_closed() return port except: return None
async def main(): target = "192.168.1.1" ports = range(1, 65536) tasks = [scan_port_async(target, port) for port in ports] results = await asyncio.gather(*tasks) open_ports = [p for p in results if p is not None] print(f"Open ports: {open_ports}")
asyncio.run(main())
服务识别
通过Banner抓取识别服务版本:
def get_banner(ip, port):
try:
sock = socket.socket()
sock.settimeout(2)
sock.connect((ip, port))
sock.send(b"HEAD / HTTP/1.1\r\nHost: " + ip.encode() + b"\r\n\r\n")
banner = sock.recv(1024).decode(errors='ignore')
sock.close()
return banner.strip()
except:
return ""
完整项目结构
port_scanner/
├── scanner.py # 核心扫描逻辑
├── banner.py # 服务识别
├── output.py # 结果输出
├── cli.py # 命令行接口
└── requirements.txt
使用示例
python cli.py -t 192.168.1.1 -p 1-1000 -T 100 -o result.json