使用Scapy设置TCP标志为FPU时sr1返回None的问题求助
Xmas扫描时Scapy的sr1返回None的问题
问题描述
想用Scapy实现Xmas扫描,当TCP标志设为"SA"时能正常获取结果,但改成"FPU"后,tryXMas()里的sr1总是返回None,不管用什么IP或端口都这样,测试环境是VirtualBox里的Metasploitable虚拟机。
代码示例
from scapy.all import IP, ICMP, TCP, sr1 import sys def probe_scan(ip): probe_packet = IP(dst=ip) / ICMP() return sr1(probe_packet, timeout=10) != None def tryXMas(ip, port): xMas_packet = IP(dst=ip) / TCP(dport=int(port), flags="FPU") Xmas_resp = sr1(xMas_packet, timeout=5) return Xmas_resp if __name__ == "__main__": ip = "127.0.0.1" # sys.argv[1] port = 21 # sys.argv[2] if probe_scan(ip): xMas_packet = tryXMas(ip, port) """This line calls error due to sr1 return None type!! """ xMas_packet.summary() else: print("Prove Scan Failed")
原因及解决方法
核心原因:Xmas数据包被过滤或无符合规则的响应
Xmas扫描属于隐蔽扫描,带FIN、PSH、URG(即"FPU")标志的TCP包不符合常规TCP连接逻辑,很多系统或防火墙会直接丢弃这类包,不会返回任何响应;另外按照RFC标准,开放端口收到Xmas包后也不会返回数据,只有关闭端口应返回RST包,但部分系统会静默丢弃,这两种情况都会导致sr1超时后返回None。解决方法1:添加空值判断,兼容无响应场景
修改主逻辑,在调用summary()前先检查返回值是否为None,避免报错,同时根据Xmas扫描的规则输出合理判断:
if __name__ == "__main__": ip = "127.0.0.1" # sys.argv[1] port = 21 # sys.argv[2] if probe_scan(ip): xMas_resp = tryXMas(ip, port) if xMas_resp: xMas_resp.summary() else: # 无响应通常意味着端口开放或数据包被过滤 print(f"Port {port} is likely open or packet filtered") else: print("Probe Scan Failed")
- 解决方法2:换用send+sniff组合捕获响应
sr1的包匹配规则可能存在限制,改用手动发包+嗅探的方式,更灵活地捕获目标返回的数据包:
from scapy.all import IP, ICMP, TCP, send, sniff def tryXMas(ip, port): xMas_packet = IP(dst=ip) / TCP(dport=int(port), flags="FPU") send(xMas_packet) # 过滤来自目标IP的TCP包,超时5秒 resp = sniff(filter=f"src host {ip} and tcp", timeout=5) return resp[0] if resp else None
- 解决方法3:调整测试环境配置
- 将VirtualBox的网络模式改为桥接或仅主机,避免NAT模式下的数据包过滤;
- 在Metasploitable中关闭iptables(执行
service iptables stop),排除防火墙拦截的可能。
内容的提问来源于stack exchange,提问作者Artem Lysenko
相关产品推荐
相关产品推荐

