Python网络扫描脚本无有效输出问题排查及修正需求
问题分析
你的脚本执行后无有效端口结果,核心原因是ARP扫描仅适用于局域网环境,而你扫描的是公网IP段(18.177.16.0/24属于AWS公网地址),ARP无法跨路由获取响应,导致没有发现存活主机,后续端口扫描自然无法执行。此外,原端口扫描的判断逻辑也未考虑防火墙过滤SYN包的情况。
修正后的代码
import scapy.all as scapy import argparse import json def get_arguments(): parser = argparse.ArgumentParser(description="Network Scanner") parser.add_argument("target", help="Target IP address or range (CIDR notation)") parser.add_argument("-p", "--ports", default="1-1024", help="Ports to scan (default: 1-1024)") parser.add_argument("-o", "--output", choices=["json", "csv"], help="Output format (json/csv)") return parser.parse_args() def scan_port(ip, port): src_port = 12345 try: # 发送SYN包 response = scapy.sr1(scapy.IP(dst=ip)/scapy.TCP(sport=src_port, dport=port, flags="S"), timeout=1, verbose=False) if not response: # 无响应,可能被防火墙过滤 return port, "filtered" elif response.haslayer(scapy.TCP): if response.getlayer(scapy.TCP).flags == 0x12: # 收到SYN-ACK,端口开放,发送RST关闭连接 scapy.send(scapy.IP(dst=ip)/scapy.TCP(sport=src_port, dport=port, flags="R"), verbose=False) return port, "open" elif response.getlayer(scapy.TCP).flags == 0x14: # 收到RST,端口关闭 return port, "closed" return port, "unknown" except Exception as e: return port, f"error: {str(e)}" def scan_host(ip, ports): open_ports = [] for port in range(ports[0], ports[1] + 1): port_num, status = scan_port(ip, port) if status == "open": open_ports.append(port_num) return {ip: open_ports} def scan_network(target, ports_range): print("Scanning network for live hosts...") # 用ICMP ping探测存活主机(适用于公网/局域网) ping_packet = scapy.IP(dst=target)/scapy.ICMP() answered_list = scapy.sr(ping_packet, timeout=2, verbose=False)[0] scan_results = {} for element in answered_list: ip = element[1].src print(f"Found live host: {ip}, starting port scan...") scan_results.update(scan_host(ip, ports_range)) print("Scan completed.") return scan_results def main(): args = get_arguments() target = args.target ports_range = list(map(int, args.ports.split("-"))) print(f"Scanning target: {target}") print(f"Scanning ports: {ports_range[0]}-{ports_range[1]}") print(f"Output format: {args.output}") scan_results = scan_network(target, ports_range) print("Scan results:", scan_results) if args.output == "json": with open("scan_results.json", "w") as file: json.dump(scan_results, file, indent=4) print("Results saved to 'scan_results.json'") elif args.output == "csv": with open("scan_results.csv", "w") as file: file.write("IP Address,Open Ports\n") for ip, ports in scan_results.items(): file.write(f"{ip},{','.join(map(str, ports))}\n") print("Results saved to 'scan_results.csv'") else: for ip, ports in scan_results.items(): print(f"IP: {ip}\tOpen Ports: {', '.join(map(str, ports)) if ports else 'None'}") if __name__ == "__main__": main()
关键修改说明
- 替换网络探测方式:将ARP扫描改为ICMP ping,适配公网和局域网环境,能正确发现存活主机
- 优化端口扫描逻辑:
- 区分开放(SYN-ACK响应)、关闭(RST响应)、过滤(无响应)三种状态
- 发现开放端口后主动发送RST包关闭半连接,避免资源占用
- 输出格式优化:CSV文件增加表头,无开放端口时显示
None,提升可读性 - 超时调整:延长ping超时到2秒,提升公网主机探测成功率
内容的提问来源于stack exchange,提问作者Gabriel D
相关产品推荐
相关产品推荐

