第233篇:TCP 劫持与序列号预测攻击

关键词

TCP劫持、序列号预测、TCP RST攻击、会话劫持、中间人攻击、盲攻击、TCP安全


一、TCP 协议的安全弱点

1.1 TCP 头部关键字段

TCP 协议设计时并未考虑安全性,关键字段可被预测和伪造:

TCP 段头部格式:

源端口 目的端口
序列号(SEQ):32 位 初始值 ISR 随机,但后续 = SEQ + 数据长度
确认号(ACK):32 位 期望收到的下一个 SEQ
标志 窗口 校验和

容易伪造的关键信息: SEQ/ACK:如果可预测 → 伪造 TCP 段 Source IP:只靠 SYN/ACK 隐式验证 无身份认证:不验证发送者的真实身份

1.2 为什么 TCP 劫持可行

TCP 劫持的基本条件:

条件 1:知道 TCP 连接的 SEQ/ACK
  如果攻击者能预测或嗅探到序列号
  就可以伪造合法的 TCP 段

条件 2:能够发送 IP 包
  攻击者可以伪造源 IP 发送数据包
  网络层不验证源 IP 真实性

条件 3:目标能够接收攻击包
  攻击包需要在正确的时机到达
  和合法数据包竞争

TCP 劫持的两种形态:

形态 1:主动劫持(在路径上)
  攻击者在通信路径上
  可以嗅探数据包
  可以阻断或篡改

形态 2:盲劫持(不在路径上)
  攻击者不在通信路径上
  需要猜测序列号
  难度更高

二、序列号预测攻击

2.1 历史背景

历史上多个操作系统使用可预测的序列号生成算法:

易受攻击的序列号生成方式:

早期 Linux(< 2.6):
  ISN = 时间戳 × 250 + 随机增量
  时间戳可预测 → ISN 可预测

早期 Windows(XP/2000):
  ISN = 基于系统启动时间的线性递增
  预测成功率极高

早期 Cisco IOS(< 12.0):
  ISN 基于内部计数器
  可预测性较高

2.2 序列号预测攻击步骤

攻击者 A 对客户端 C 到服务器 S 的连接进行盲劫持:

初始状态:客户端 C 与服务器 S 建立 TCP 连接

  C ──────────────────── S
     SEQ=100, ACK=200

攻击者 A 不在路径上,但要注入伪造数据:

Step 1:猜测序列号
  A 观察到 C 发了一个 50 字节的数据包
  A 猜测 S 的下一 ACK = 150 (100+50)
  A 猜测 C 的下一 SEQ = 200 (当前 ACK)

Step 2:伪造 TCP RST(断开连接)
  A → S: [源IP=C, 源端口=12345, SEQ=200, RST]
  ↓
  S 收到 RST,SEQ=200 匹配 → 断开连接

Step 3:伪造 TCP 数据
  A → S: [源IP=C, SEQ=200, ACK=150, PUSH, 恶意数据]
  ↓
  S 接收 "恶意数据" 并正常确认

Step 4:维持连接(避免 C 发数据引起混乱)
  A → C: [源IP=S, SEQ=150, ACK=450, PUSH, 虚假响应]
  ↓
  C 接收虚假响应

注意:序列号窗口为 2^32,如果猜测在窗口内即可接受
TCP 接收窗口通常是 64K,大大降低了猜测难度

2.3 现代系统的防护

现代 TCP 栈的序列号保护:

RFC 6528 建议:
  ISN = M(时间戳, 源IP, 源端口, 目的IP, 目的端口)
  M 是一个加密哈希函数

  确保:相同的五元组产生不同的 ISN
        ISN 对外不可预测

Linux 实现(/proc/sys/net/ipv4/tcp_seq):
  # 查看当前序列号随机化
  sysctl net.ipv4.tcp_timestamps = 1
  # 内核使用 MD5 哈希生成 ISN

Windows 实现:
  Windows 8+ 使用安全随机数生成 ISN
  序列号递增规律不可预测

防序列号预测的有效性:
  现代系统 ISN 几乎不可预测
  (但局域网嗅探仍然可以获取序列号)

三、TCP RST 攻击

3.1 RST 攻击原理

RST 攻击是最简单的 TCP 劫持形式——直接断开连接:

RST 攻击场景:

合法连接: PC (10.0.0.1:50001) ──── RST? ──── Server (1.2.3.4:80)

攻击者发送伪造 RST 包:

攻击者发送: 源IP: 10.0.0.1 (伪造) 源端口: 50001 (猜测或嗅探) 目的IP: 1.2.3.4 目的端口: 80 SEQ: 尽量在接收窗口内 RST 标志: 1 服务器收到后:SEQ 在窗口内 → 立即断连

真实案例:Great Cannon(防火长城) 对特定目标发送大量 RST 包 阻断所有对该目标的 TCP 连接 大规模 DDoS 性质的 RST 攻击

3.2 RST 攻击的变种

变种 1:TCP 重置注入(中间网络设备)
  位于网络路径上的设备注入 RST
  常用于:网络审查、内容过滤

  网络管理设备 → RST 包 → 断连
  对端收到 RST → 认为对方主动断开

  检测:
    tcpdump 显示 RST 与之前数据包序列号不连续
    两侧连接状态不一致

变种 2:欺骗性 RST(伪装对端)
  攻击者猜测或嗅探序列号
  伪装成通信一方发送 RST

  防护:TCP MD5 Option(RFC 2385)
    # Cisco 路由器配置
    router bgp 100
     neighbor 10.0.0.1 password BGP@123

    TCP MD5 选项为 TCP 段添加 MD5 摘要
    伪造的 RST 包没有正确摘要 → 被丢弃

  局限:仅 BGP 等少数协议支持
      计算开销大,不适合高速环境

四、TCP 会话劫持

4.1 主动中间人劫持

攻击者在路径上的 TCP 会话劫持:

客户端             攻击者               服务器
  │                  │                    │
  │── SYN ──────────►│── SYN ────────────►│
  │◄── SYN/ACK ─────│◄── SYN/ACK ────────│
  │── ACK ──────────►│── ACK ────────────►│
  │                  │                    │
  │                  │  连接建立后:       │
  │── GET /login ───►│── GET /login ─────►│
  │                  │  记录 SEQ/ACK      │
  │                  │◄── 200 OK ─────────│
  │◄── 篡改响应 ────│                    │
  │                  │  或注入恶意内容     │

篡改方式:
  1. 延迟原数据包 → 先发恶意数据包
  2. 修改数据包内容(修改 JS、替换下载文件)
  3. 注入额外数据(插入广告、恶意脚本)

防护:TLS(HTTPS)
  TLS 加密整个 TCP 载荷
  攻击者无法看到明文内容
  无法篡改

4.2 盲劫持(Blind Hijacking)

不在路径上的 TCP 劫持:

攻击者不在客户端和服务器的网络路径上
只能猜测序列号

盲劫持的困难:
  需要猜测正确的 SEQ(32 位)
  需要在接收窗口内(通常 64KB)
  窗口滑动后要持续猜测

盲劫持的成功条件:
  1. 知道客户端和服务器 IP:PORT
  2. 知道数据包往返的时间
  3. 猜测到当前的 SEQ
  4. 攻击包在合法包之前到达

实际成功率:
  现代系统:极低(ISN 随机化 + 窗口随机化)
  局域网环境:有可能(更容易观察流量模式)

盲劫持的常见应用:
  DNS 投毒(DNS ID 预测)
  BGP 会话攻击
  都不是纯粹的 TCP 劫持

五、防护措施

5.1 网络层防护

网络层防护措施:

1. IP 源地址验证(uRPF)
   # 华为交换机配置
   interface GigabitEthernet0/0/1
    ip urpf strict                   # 严格模式反查源地址

   检查:入站数据包的源 IP 是否可通过该接口到达
   防止:使用伪造 IP 的 TCP 劫持攻击包

2. TCP 拦截(防火墙)
   # 华为防火墙配置
   firewall tcp-intercept
    # 拦截并验证 TCP 连接
    # 代理完成三次握手
    # 验证通过后建立真实连接

3. 加密传输(TLS/IPsec)
   所有敏感通信使用 TLS
   防劫持最有效的措施

5.2 主机层防护

主机层防护措施:

1. 启用 TCP 时间戳(tcp_timestamps)
   # Linux 系统
   sysctl -w net.ipv4.tcp_timestamps=1

   效果:接收端可检测 SEQ 是否在正确的时间顺序
   防护:旧包(或伪造包)的 SEQ 时间戳不匹配

2. TCP 窗口随机化
   # Windows 系统
   netsh int tcp set global autotuninglevel=normal

   随机化窗口大小,增加盲攻击的猜测难度

3. TCP Challenge ACK
   收到可疑 RST 时,发送 Challenge ACK
   检查对端是否真的发送了 RST

   流程:
     A 收到 RST(SEQ=X)
     A 发送 Challenge ACK(ACK=Y) 检查
     如果对端确实发送 RST → 回复 RST(ACK=Y)
     否则 → 忽略

5.3 安全协议层防护

应用层防护:

1. 使用 TLS/HTTPS 代替 HTTP
   最有效的防护
   TLS 加密后 TCP 载荷不可读
   防止篡改和注入

2. TCP MD5 签名(RFC 2385)
   用于 BGP 等关键协议
   配置共享密码
   验证每个 TCP 段的完整性

   # BGP TCP MD5 配置
   router bgp 65001
    neighbor 10.0.0.1 password MySecret123

   攻击者不知道密码 → 无法伪造 TCP 段

3. TCP-AO(TCP Authentication Option,RFC 5925)
   替代 TCP MD5 的更现代方案
   支持多密钥轮换
   更好的安全性

六、检测与监控

6.1 异常检测

TCP 劫持的异常特征:

1. 序列号异常
   观察:多个相同 SEQ 的数据包
   观察:SEQ 跳跃异常(不是正常的数据长度增量)

   # tcpdump 检测
   tcpdump -i eth0 'tcp[4:4] = tcp[4:4]'  # 重复 SEQ

2. 双向流量不对称
   服务器确认的 SEQ 与客户端发送的不一致
   一侧看到已发送数据,另一侧看到未发送数据

3. RST 风暴
   短时间内大量 RST 包
   异常 IP 发送的 RST 包

4. 连接状态不一致
   服务器认为连接存在,客户端认为断开
   反之亦然

6.2 防火墙防护配置

# 华为防火墙 TCP 劫持防护配置

# TCP 异常检测
firewall defend tcp-syn-flood enable
firewall defend tcp-fin-flood enable
firewall defend tcp-rst-flood enable

# TCP 连接防护
tcp-state-check
 rfc-compliant-check enable
 # 检查 SEQ 合法性
 seq-check enable
 # 检查 ACK 合法性
 ack-check enable
 # RST 包检查
 rst-check enable
  # 验证 RST 的 SEQ 是否准确
  # 不在窗口内的 RST 丢弃
!

# 防 IP 伪造
interface GigabitEthernet1/0/0
 ip urpf strict

# TCP 代理(可选)
tcp-proxy
 server 10.0.0.1 80
  proxy enable                              # 代理 TCP 连接
  intercept-mode passive                     # 只代理可疑连接

七、总结

知识点 核心要点
TCP 劫持原理 伪造 TCP 段,利用可预测的序列号
序列号预测 猜测或嗅探 SEQ/ACK,伪造合法数据包
RST 攻击 伪造 RST 包断开连接,最简单但有效
主动劫持 vs 盲劫持 在路径上可嗅探,不在路径上需猜测
防护措施 TLS加密、TCP MD5、uRPF、时间戳
检测方法 异常 SEQ、流量不对称、RST 风暴
现代安全性 ISN 随机化 + 窗口随机化提升防护

八、思考

  1. TCP 劫持攻击的基本原理是什么?攻击者需要知道哪些信息才能成功?
  2. 序列号预测攻击在早期系统中为什么可行?现代系统如何防御?
  3. TCP RST 攻击如何工作?它可能造成什么后果?
  4. 主动中间人劫持和盲劫持有什么不同?各自需要什么条件?
  5. 除了使用 TLS/HTTPS,还有哪些防护措施可以有效防御 TCP 劫持攻击?

下篇预告:第234篇《DHCP 饿死攻击与防护》——分析 DHCP Starvation 攻击原理,耗尽 IP 地址池、伪造 DHCP 服务器的攻击手段。