端口敲门(Port Knocking)探测与利用
端口敲门(Port Knocking) 是一种通过在防火墙外动态开启访问权限的防御机制。目标服务器的默认防火墙策略将敏感管理端口(如 22/SSH、3389/RDP 或内部 Web 端口)设为 DROP 或 REJECT,不对外直接暴露。服务端守护进程(如 knockd)监听底层网卡原始报文,当检测到来自特定源 IP、按照预定顺序与协议敲击的一组端口序列后,动态调用防火墙规则(如 iptables)放行该 IP 的访问请求。
在渗透测试与靶场攻防中,当高价值服务端口未开放,但在 Web 页面、配置文件、隐写载荷或源码注释中发现一组有规律的端口列表时,应优先考虑端口敲门机制。
识别特征与线索来源
端口敲门属于主动隐蔽机制,常规端口扫描(如 Nmap 全端口扫描)通常无法直接发现规则背后的隐藏服务。常见发现线索包括:
| 线索来源 | 典型表现 | 审计关注点 |
|---|---|---|
| Web 源码与注释 | HTML/JS 注释中残留数字列表,如 7000, 8000, 9000 | 敲门端口序列及对应协议 |
| 本地配置文件 | /etc/knockd.conf、/etc/default/knockd | sequence、seq_timeout、command |
| 流量包分析 (PCAP) | 发现来自同一源 IP 连续发送的 SYN 包或 UDP 试探包 | 端口顺序、协议类型与间隔时间 |
| 隐写与文本线索 | 图片 EXIF、隐写提取出的文本包含顺序序列 | 敲门指令或端口参数 |
| 异常服务列表 | Nmap 扫描发现一组看似无业务意义的高位关闭端口 | 是否配置了 knockd 监听 |
knockd 配置审计与原理
典型的 Linux knockd 配置文件格式如下:
[options]
logfile = /var/log/knockd.log
interface = eth0
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
sequence:指定触发规则必须按序敲击的端口号。支持混合协议标记,例如7000:tcp,8000:udp,9000:tcp。未标明时通常默认为 TCP。seq_timeout:序列超时时间(秒)。整组敲门动作必须在该时间内完成,超时则状态机重置。tcpflags:匹配的 TCP 标志位,绝大多数场景要求为syn。command:命中完整序列后由 root 执行的系统命令,%IP%会被自动替换为发起敲门的主机 IP。
常用敲门方法与命令
方法 A:使用 knock 工具(推荐)
在 Kali Linux 或测试机中安装官方客户端:
sudo apt-get install knockd
向目标按序发送敲门报文:
# 默认 TCP SYN 报文敲门
knock -v <target-ip> 7000 8000 9000
# 指定 UDP 协议敲门
knock -v -u <target-ip> 7000 8000 9000
# 针对混合协议序列(需在端口后加 :protocol)
knock -v <target-ip> 7000:tcp 8000:udp 9000:tcp
方法 B:使用 Bash 循环与 Nmap / Nc
当测试环境未安装 knock 工具时,可使用内置工具快速发起探测:
# 使用 Nmap 快速发送单个 SYN 包(避免全连接握手耗时)
for port in 7000 8000 9000; do
nmap -Pn --host-timeout 100 --max-retries 0 -p $port <target-ip> >/dev/null 2>&1
done
# 使用 netcat (nc) 快速探测
for port in 7000 8000 9000; do
nc -z -w 1 <target-ip> $port
done
# 使用 bash 伪设备 /dev/tcp
for port in 7000 8000 9000; do
timeout 1 bash -c "echo > /dev/tcp/<target-ip>/$port" 2>/dev/null
done
敲门后状态验证
敲门报文发送完毕后,应立即对目标目标端口(如 22/tcp)发起定向探测验证规则是否生效:
# 定向检查目标端口状态
nmap -Pn -p 22 -sV <target-ip>
若原先为 filtered 或 closed 的端口变为 open,说明敲门成功,随后可继续进行服务探测、认证登录或漏洞利用。
常见变体与防坑要点
- 时延与超时设置:
seq_timeout通常较短(310 秒)。如果使用多线程并发或工具扫描,各端口报文可能乱序到达导致敲门失败。建议设置较小的单包间隔(如 100300ms)。 - 协议不匹配:部分序列可能混合了 UDP 或 ICMP 协议。若纯 TCP 敲门无反应,注意检查线索中是否包含
udp标记。 - NAT 与源 IP 不一致:
knockd记录的是网络层捕获到的源 IP。如果通过代理(如 HTTP/Socks 代理)或者多层内网 NAT,敲门源 IP 与后续连接服务的出网 IP 可能不一致,导致防火墙放行了错误地址。 - 反向关闭机制(Close Sequence):部分靶机设置了自动关闭定时器(如放行 30 秒后恢复),或单独的关闭序列。完成任务或需要重置状态时,可敲击对应的关闭序列。
防御建议与现代替代方案
- 迁移至 SPA(单包授权,Single Packet Authorization):传统 Port Knocking 容易遭受中间人重放攻击与端口嗅探。推荐使用 fwknop 等单包授权方案,对敲击报文进行强加密(AES/GPG)与防重放哈希验证。
- 强化 SSH 安全基线:即便配置了端口敲门,后置服务(如 SSH)仍必须禁用密码登录,全面启用公钥认证或多因素认证(MFA)。
- 限制敲门失败重试率:配置 iptables 限速与 fail2ban,对频繁穷举端口序列的源 IP 执行黑名单阻断。
来源案例
- HackMyVM Yulian:通过 Web 提示发现敲门序列,使用 knock 解锁被防火墙阻断的 SSH 端口。