2. 端口扫描技术:原理、实战与避坑指南
端口扫描,说白了就是敲门。你想知道目标主机开了哪些门(端口),哪些门关着,哪些门后面有人盯着。搞网络安全的用它做资产发现,搞运维的用它做服务巡检,搞攻击的……嗯,你懂的。
我个人习惯把端口扫描分成两类:基于TCP的和基于UDP的。TCP扫描花样多,UDP扫描就一个套路但特别慢。今天咱们把这几种主流扫描技术掰开揉碎了讲,顺便聊聊我在项目中踩过的坑。
核心观点:没有完美的扫描技术。TCP Connect最可靠但最容易被发现,SYN半开扫描又快又隐蔽但需要root权限,UDP扫描慢得像蜗牛但不得不做。选哪种,取决于你的场景和风险承受能力。
2.1 TCP Connect扫描:最基础,也最“吵”
TCP Connect扫描,就是完整走一遍TCP三次握手。你想想看,正常客户端连服务器是不是也得这么干?
客户端 → SYN → 服务端
客户端 ← SYN+ACK ← 服务端 (端口开放)
客户端 → ACK → 服务端
连接建立,然后立刻发RST断开
如果端口关闭,服务端会直接回一个RST包。整个过程完全符合TCP协议规范,所以叫“Connect”扫描——它用的是操作系统自带的connect()系统调用。
优点:
- 不需要特殊权限,普通用户就能跑
- 结果准确,不会误判
- 实现简单,Nmap的
-sT就是它
缺点:
- 太容易被发现了。服务端会记录完整连接日志,IDS/IPS一眼就能识别
- 速度慢。每次扫描都要等超时,全端口扫描可能要几分钟
- 容易被防火墙拦截。很多防火墙会直接丢弃SYN包
我的经验:有一次在内网做资产盘点,我用Connect扫描被安全组的人找上门了。他们说“你这IP在疯狂连我们服务器,是不是被入侵了?”从那以后,内网扫描我尽量用SYN半开,除非对方明确授权。
2.2 SYN半开扫描:又快又隐蔽,但需要root
SYN半开扫描,也叫“隐蔽扫描”。它只走两步握手,不完成第三次握手。流程是这样的:
客户端 → SYN → 服务端
客户端 ← SYN+ACK ← 服务端 (端口开放,判定为开放)
客户端 → RST → 服务端 (不等ACK,直接断开)
如果收到RST,说明端口关闭
如果没响应,说明被过滤了
为什么说它隐蔽?因为服务端没完成连接,很多应用层日志不会记录。但底层网卡和防火墙还是能看到的——别太迷信“隐蔽”二字。
优点:
- 速度快。不需要等超时,半开就判定
- 相对隐蔽。很多应用层服务不会记录半开连接
- 能区分开放、关闭、过滤三种状态
缺点:
- 需要root权限。因为要构造原始SYN包
- 某些防火墙会检测并拦截SYN洪水
- 对老旧系统可能造成连接表溢出
注意:SYN半开扫描在Windows上效果不好。Windows的TCP栈实现跟Linux不一样,收到SYN+ACK后如果直接发RST,某些版本会记录异常。我在一次跨平台扫描中就吃过这个亏——Windows服务器上扫出来的结果比实际少了30%的开放端口。
2.3 UDP扫描:慢,但不得不做
UDP扫描是最让人头疼的。为什么?因为UDP是无连接的,你发个包过去,对方可能回数据,也可能什么都不回。
UDP扫描的原理很简单:
客户端 → UDP包(空数据) → 服务端
客户端 ← UDP数据 ← 服务端 (端口开放)
客户端 ← ICMP Port Unreachable ← 服务端 (端口关闭)
客户端 ← 无响应 ← 服务端 (可能开放,可能被过滤)
问题就出在“无响应”上。UDP端口开放时,很多服务不会主动回包,除非你发的数据恰好符合协议格式。比如DNS服务,你发个空UDP包过去,它理都不理你。
优点:
- 能发现UDP服务(DNS、SNMP、DHCP等)
- 某些场景下必须用(比如发现SNMP服务)
缺点:
- 慢!非常慢!ICMP不可达消息可能被限速,超时时间通常设3-5秒
- 结果不可靠。无响应可能是开放,也可能是被过滤
- 需要构造应用层数据才能提高准确率
我的建议:UDP扫描别用默认设置。我一般会加--max-retries 1 --min-rate 100来提速,同时配合-sV做服务探测。另外,先扫常见UDP端口(53, 161, 500, 4500等),别上来就全端口——全端口UDP扫描能跑一整天。
2.4 FIN扫描:绕过防火墙的“暗器”
FIN扫描利用了TCP协议的一个特性:如果收到一个FIN包,而端口是关闭的,系统会回RST;如果端口是开放的,系统会忽略这个FIN包(因为没建立连接)。
客户端 → FIN → 服务端
客户端 ← RST ← 服务端 (端口关闭)
客户端 ← 无响应 ← 服务端 (端口可能开放)
这招对某些防火墙特别有效。很多防火墙只检查SYN包,对FIN包直接放行。但注意,Windows系统不遵守这个RFC——无论端口开没开,收到FIN都会回RST。
优点:
- 能绕过部分只检测SYN的防火墙
- 更隐蔽,日志里看起来像正常连接终止
缺点:
- 只对Linux/Unix系统有效,Windows无效
- 结果不可靠。无响应可能是开放,也可能是被过滤
- 现代防火墙基本都能识别FIN扫描
避坑指南:我曾经在渗透测试中用FIN扫描扫一个Windows Server 2016,结果所有端口都显示“开放”。当时我还纳闷,后来查资料才发现Windows不按RFC来。从那以后,我扫Windows只用Connect或SYN扫描。
2.5 四种扫描技术对比
我把这四种扫描技术整理成了一张表,方便你对比选择:
| 扫描类型 | 原理 | 速度 | 隐蔽性 | 权限要求 | 适用场景 |
|---|---|---|---|---|---|
| TCP Connect | 完整三次握手 | 慢 | 低 | 无 | 授权测试、内网资产盘点 |
| SYN半开 | 仅SYN+SYN+ACK | 快 | 中 | root | 日常渗透测试、外网扫描 |
| UDP扫描 | 发送UDP包 | 极慢 | 高 | root | 发现UDP服务、SNMP探测 |
| FIN扫描 | 发送FIN包 | 快 | 高 | root | 绕过SYN检测防火墙 |
2.6 扫描技术选择决策流程
说了这么多,到底该用哪种?我画了个流程图,帮你快速决策:
2.7 实战建议
最后,分享几条我在实战中总结的经验:
- 先快后慢。先用SYN半开扫常见端口(Top 1000),再针对发现的服务做深度探测。别上来就全端口,浪费时间。
- UDP扫描要加协议探测。比如扫DNS端口时,发个DNS查询包,比发空包准确得多。Nmap的
-sUV就是干这个的。 - 注意扫描频率。别把目标扫挂了。我一般设
--min-rate 50 --max-rate 200,既保证速度又不触发防护。 - 结果要交叉验证。SYN扫出来的结果,再用Connect扫一遍确认。两种方法结果一致,基本就稳了。
- 记录扫描参数。每次扫描都记下用了什么参数、什么时间、目标是什么。出了问题好回溯——我曾经因为没记参数,被客户质疑扫描结果,花了三天才复现。
一句话总结:SYN半开是主力,Connect做兜底,UDP看需求,FIN当奇招。没有银弹,只有最适合当前场景的技术。