lwIP更新记04:TCP 初始序列号生成算法可以自定义了

从 lwIP-2.0.0 开始,可以自定义 TCP 报文段的初始序列号。

初始序列号

TCP 报文段首部有一个序列号字段(见下图),它是一个32位的计数器,从 0 到 4294967295,它的值为当前报文段中第一个数据的字节序号。在建立连接之初,通信双方都会各自选择一个序列号,称之为初始序列号(Initial Sequence Number:ISN),在建立连接时,通信双方通过 SYN 报文交换彼此的初始序列号。

在这里插入图片描述

初始序列号的生成方式可能会因实现而异,但是大多数实现都会选择一个随机数或者根据某些特定的算法生成。TCP 报文段的初始序列号是由 TCP 协议栈函数生成的。在 lwIP 中,协议栈为每个新的 TCP 连接生成一个 TCP 初始序列号,tcp.c 中的函数 tcp_next_iss 用于这个目的。

lwIP 1.4.1 版本初始序列号实现

在1.4.1版本中,这个函数长这样:

/**
 * Calculates a new initial sequence number for new connections.
 * @return u32_t pseudo random sequence number
 */
u32_t tcp_next_iss(void)
{
  static u32_t iss = 6510;
  iss += tcp_ticks;
  return iss;
}

这个算法很简单,一个固定值(6510)加上系统启动到当前的时间。这是一个常见的在 TCP 协议中为新连接生成初始序列号的方法。但是这个算法产生的值是可以预测的,以至于 lwIP 的 TCP 连接可能成为 TCP 欺骗攻击的目标。

对初始序列号的准确预测是 IP 欺骗、数据注入和会话劫持能成功的先决条件。举一个TCP Reset 攻击例子:

如果能准确预测初始序列号,就可以假冒客户端向服务器发送 RST 包,要求复位连接。由于 RST 包并不需要向应用层提交,服务器端的 TCP 协议栈只要接到该包就立即终止此次 TCP 连接,这将让真正的客户端连不上服务器,导致了拒绝服务攻击。

根据研究结果表明,Windows 2000、Windows XP SP1 的初始序列号都是可以预测的,从 Windows XP SP2 开始,初始序列号才能难以预测。

lwIP 2.1.3 版本初始序列号实现

RFC6528 规定了 TCP 发送方在建立连接时如何选择初始序列号,这个文档描述了如何避免在因特网中针对TCP连接的大量 off-path 攻击。但是,RFC6528 中的算法需要高分辨率计时器和加密散列函数。这远远超出了 lwIP 本身的范围。所以 lwIP 增加了 LWIP_HOOK_TCP_ISN ,这是一个钩子函数,可以让开发者根据自己的硬件平台实现自己的初始序列号生成算法。该钩子函数提供了很大的灵活性,既可以用简单的随机数生成初始序列号,也可以实现完整的 RFC 6528 规定的算法。在 lwIP-2.1.3,新的 tcp_next_iss 函数为:

u32_t tcp_next_iss(struct tcp_pcb *pcb)
{
#ifdef LWIP_HOOK_TCP_ISN
  LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL);
  return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port);
#else /* LWIP_HOOK_TCP_ISN */
  static u32_t iss = 6510;
  LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL);
  LWIP_UNUSED_ARG(pcb);
  
  iss += tcp_ticks;
  return iss;

如果定义了宏 LWIP_HOOK_TCP_ISN,则需要这个钩子函数来生成初始序列号,你需要在外部实现这个函数。如果没有定义宏 LWIP_HOOK_TCP_ISN,则还是使用 lwip-1.4.1 版本中简单算法。总之,新的 lwIP 版本给出了生成初始序列号的另一种途径,不同的硬件可以选择不同的算法。






读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
千金难买知识,但可以买好多奶粉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值