扫描网站端口
打开命令行,扫描敲下 nmap -sT 192.168.1.1,网站回车。端口屏幕上开始一行行跳出端口状态:22 开放,扫描80 开放,网站443 过滤,端口3306 关闭。扫描整个过程不到十秒。网站这就是端口端口扫描最朴素的样貌——用数据包敲服务器的门,听它回不回应。扫描
我第一次接触端口扫描是网站给一台测试服务器做安全自查。当时以为装个防火墙就万事大吉,端口结果 nmap 一扫,扫描8080 端口赫然开着,网站跑的端口是一个早该下线的旧版 Jenkins。那个端口从没在文档里出现过,运维换人时被彻底遗忘。攻击面就是这么来的——不是你主动暴露的,而是你忘了关的。
TCP 三次握手暴露了什么
端口扫描的原理不复杂。TCP 协议建立连接需要三次握手:客户端发 SYN,服务端回 SYN-ACK,客户端再回 ACK。扫描器利用的就是前两步。发一个 SYN 过去,如果对方回 SYN-ACK,说明端口开放;回 RST,说明端口关闭;什么都不回,多半被防火墙丢了包,状态标记为 filtered。
这种扫描方式叫半开放扫描,也就是 nmap -sS。它不完成第三次握手,连接不会真正建立,因此速度更快,也不容易被应用层日志记录。相比之下,-sT 走完整的 connect() 系统调用,慢一些,但不需要 root 权限,普通用户也能跑。
UDP 扫描是另一回事。UDP 无连接,没有握手可依赖。发一个空包过去,对方回 ICMP port unreachable 说明端口关闭;没回应可能是开放,也可能是被丢了。误判率高,速度慢,很多人干脆跳过 UDP 扫描。但 DNS、SNMP、DHCP 这些服务跑在 UDP 上,漏掉它们等于漏掉半个攻击面。
一次真实的扫描记录
拿一台公网 VPS 做演示。先跑 nmap -sS -p- --open 目标IP,全端口扫描。大概三分钟后结果出来:22、80、443、8888 四个端口开放。8888 是什么?浏览器打开一看,宝塔面板的登录页。默认端口没改,登录接口没有 IP 白名单,密码策略也宽松。
再对 80 端口跑 nmap -sV -sC,版本探测加默认脚本。输出显示 nginx 1.18.0,还带出了 http-title 和 http-robots.txt 的结果。robots.txt 里写着一行 Disallow: /admin/。等于直接告诉扫描者后台路径在哪。
这不是个例。很多扫描工具默认就会抓 robots.txt、sitemap.xml、.git 目录。你不想让人看的东西,反而因为这些文件被优先发现。
扫描之后该做什么
扫描本身不是攻击,它只是信息收集。问题在于很多人扫完就停了,看到端口开放也不管,觉得“反正业务需要”。但每一个开放端口都是一次信任决策。3306 对公网开放,意味着任何人只要拿到弱口令就能直连数据库。6379 的 Redis 未授权访问漏洞,至今还能在 Shodan 上搜到大批实例。
我的习惯是扫完做三件事。第一,对照业务清单,确认每个开放端口都有明确用途。第二,对确认需要的端口加访问控制——安全组、iptables、fail2ban 都行。第三,定期复扫。服务器配置会漂移,今天关掉的端口,明天可能因为一次部署又被打开。
端口扫描不神秘,它就是把服务器不愿意主动说的事情问出来。问的方式粗暴了点,但有效。真正重要的是问完之后你做了什么。放任不管,扫描结果就是一份递给攻击者的地图。
