连接到远程主机期间的 TCP 紧急指针状态混淆 (CVE-2019-12261)
当一个运行着 VxWorks 系统的目标设备充当 TCP 服务器并且攻击者启动与该服务器的连接时,上述代码流可以实现。另外一个紧急指针漏洞的变体存在于运行着 6.7 版本或更高版本的 VxWorks 设备创建出站 VxWorks 连接时。在这种情况下,目标设备充当客户进程,在目标设备向远程 TCP 端口发送 SYN 报文段之后,TCP 套接字上的 connect() 调用期间可能会出现可利用的状态混淆。如果攻击者使用特制的 SYN/ACK 报文段响应此 SYN 报文段,则会出现与上一节中类似的紧急指针处理问题。
要利用此漏洞,攻击者需要处于以下任一位置:
- 强制目标设备创建与恶意主机的 TCP 连接。
- 处于目标设备与其连接的合法主机之间的中间人 (MiTM) 位置,这对于 LAN 上的攻击者来说很容易实现。
在运行着 VxWorks 系统上的目标设备的用户应用程序进行 connect() 调用后,会向服务器端发送一个 SYN 报文段,并且套接字进入 SYN_SENT_STATE 状态。此时,一个 SYN/ACK 报文段会被期望到达模块 iptcp_deliver 。 当一个报文段以 SYN/ACK 状态到达时,将调用函数 iptcp_deliver_state_syn_sent:
如果客户端接收到的数据包确实设置了 SYN 和 ACK 标志,则会调用函数 iptcp_process_syn,并且 tcb->recv.seq_next 被赋值为 p->seg.seq_start,这是 SYN/ACK 数据包内部的初始序列号。其值受攻击者控制,现将其表示为 sequence_a 。请注意 *new_state 现在实际上还没有改变设置的 tcb 状态。 这应该在稍后发生,在 iptcp_deliver 中。
现在,假设攻击者已将 FIN 和 URG 标志添加到 SYN/ACK 报文段中,创建了一个 SYN/ACK/FIN/URG (#1) 的响应而不是常规的 的只有 SYN/ACK 的响应。客户端收到攻击者特制的响应SYN/ACK/FIN/URG (#1) 后,上面显示的代码流的发生方式将与常规 SYN/ACK 完全相同。所以在 iptcp_deliver_state_syn_sent 中(或之前)没有检查是否存在 FIN 和 URG 标志。然后 iptcp_deliver 中的其余流程继续进行,后续会将设置 tcb->recv.urg_ptr (设置为 sequence_a + 1 ),然后流程继续,直到遇到未曾预料到的 FIN 标志,会中止对报文段的处理。至此,tcb 的状态仍没有更新,而是保持为 SYN_SENT_STATE 。
攻击者现在可以发送另一个 SYN/ACK (#2) 报文段。这一次它是一个完全有效的 SYN/ACK 报文段,但其初始序列号设置为 sequence_b 。此外,攻击者可能会在此 SYN/ACK 报文段中包含多达 64K 字节的数据,这些数据将被添加到套接字的 TCP 接收窗口中。直到现在套接字的状态才将变为 ESTABLISHED_STATE ,并且 connect() 调用将返回。
但是,此时,tcb->recv.urg_ptr(源自 sequence_a)和 tcb->recv.seq_next(源自 sequence_b)的值之间会再次存在差异。重申一下,这将导致套接字上的任何 recv() 调用以可由攻击者控制的方式破坏内存,从而导致 RCE。