Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 SACK

admin 2024年7月23日12:19:44评论23 views字数 5199阅读17分19秒阅读模式

选择的方向能够让自己乐在其中

实验目的

基于 packetdrill TCP 三次握手脚本,测试 TCP options 中 SACK 字段的由来,此次构造模拟的是客户端场景。

对于 TCP options,各类介绍资料已经数不胜数,本篇就不再赘述。

基础脚本

  1. # cat tcp_3hs_007.pkt // TCP 基础之三次握手0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0+0 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
  2. +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
  3. +0 > S 0:0(0) <...>+0.01 < S. 0:0(0) ack 1 win 10000 <mss 1000>+0 > . 1:1(0) ack 1

实验测试一

因为 >  表示预期协议栈会发送的数据包,所以内核协议栈自动构建发送 SYN 数据包。

  1. +0 > S 0:0(0) <...>// +0 本行代码执行时间相对于上一行代码的偏移时间。// > ,表示预期协议栈会发送的数据包。// 0:0(0) ,表示开始序号:结束序号(数据包长度)。// <> 表示 TCP options,... 表示默认值。

模拟的是客户端场景,SYN 数据包自动构建的情况下,各字段因此无需自定义。

  1. 1.执行脚本# packetdrill tcp_3hs_007.pkt # 执行完成后退出。
  2. 2.捕获数据包# tcpdump -i any port 8080 -nn tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes15:49:36.529121 tun0 Out IP 192.168.174.54.50762 > 192.0.2.1.8080: Flags [S], seq 1691568983, win 64240, options [mss 1460,sackOK,TS val 329810675 ecr 0,nop,wscale 7], length 015:49:36.629222 ? In IP 192.0.2.1.8080 > 192.168.174.54.50762: Flags [S.], seq 0, ack 1691568984, win 10000, options [mss 1000], length 015:49:36.629256 ? Out IP 192.168.174.54.50762 > 192.0.2.1.8080: Flags [.], ack 1, win 64240, length 015:49:36.629427 ? Out IP 192.168.174.54.50762 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 64240, length 015:49:36.629444 ? In IP 192.0.2.1.8080 > 192.168.174.54.50762: Flags [R.], seq 1, ack 1, win 10000, length 0#

观察 tcpdump 抓包结果可以看到客户端 SYN TCP Options 中包含 SACK 字段 ,因为此时在客户端开启了 SACK 支持,所以如上结果。

  1. # sysctl -a | grep tcp_sacknet.ipv4.tcp_sack = 1#

而服务器端响应的 SYN/ACK 不包含 SACK 字段,因为此时服务器端属于 < 自行构造的数据包,在 <> TCP options 中只有 mss 1000,并没注入 SACK,所以此时 TCP 三次握手的结果,表明之后的 TCP 通讯将不支持 SACK,因为 SYN/ACK 并不支持。

实验测试二

此时修改 SYN/ACK 的 TCP options ,同样增加 SACK 支持,如下:

  1. # cat tcp_3hs_options_sack_001.pkt 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0+0 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
  2. +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)+0 > S 0:0(0) <...>+.1 < S. 0:0(0) ack 1 win 10000 <mss 1000, nop, nop, sackOK>+0 > . 1:1(0) ack 1## packetdrill tcp_3hs_options_sack_001.pkt #

观察 tcpdump 抓包结果可以看到确实  SYN TCP Options 中包含 SACK 字段 ,且服务器端响应的 SYN/ACK 同样也包含 SACK 字段,所以此时 TCP 三次握手的结果,表明之后的 TCP 通讯将支持 SACK,因为双方均支持。

  1. # tcpdump -i any port 8080 -nn tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes16:36:34.089125 tun0 Out IP 192.168.59.18.36452 > 192.0.2.1.8080: Flags [S], seq 3396072839, win 64240, options [mss 1460,sackOK,TS val 3180330847 ecr 0,nop,wscale 7], length 016:36:34.189239 tun0 In IP 192.0.2.1.8080 > 192.168.59.18.36452: Flags [S.], seq 0, ack 3396072840, win 10000, options [mss 1000,nop,nop,sackOK], length 016:36:34.189277 tun0 Out IP 192.168.59.18.36452 > 192.0.2.1.8080: Flags [.], ack 1, win 64240, length 016:36:34.189485 tun0 Out IP 192.168.59.18.36452 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 64240, length 016:36:34.189522 tun0 In IP 192.0.2.1.8080 > 192.168.59.18.36452: Flags [R.], seq 1, ack 1, win 10000, length 0#

实验测试三

此时如果将客户端 SACK 支持关闭,则:

  1. # sysctl -q net.ipv4.tcp_sack=0## sysctl -a | grep tcp_sacknet.ipv4.tcp_sack = 0#

仍然执行如下脚本,那么可以看到 tcpdump 抓包结果中客户端所发送的 SYN 不再包含 SACK 字段,那么不管服务器端本地的 net.ipv4.tcp_sack 是否启用(对于真实环境),在响应的 SYN/ACK 中都不会包含 SACK 字段。此时 TCP 三次握手的结果,也表明之后的 TCP 通讯将不支持 SACK。

  1. # packetdrill tcp_3hs_007.pkt #
  2. # tcpdump -i any port 8080 -nn tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes16:45:28.581127 tun0 Out IP 192.168.146.240.52106 > 192.0.2.1.8080: Flags [S], seq 92066967, win 64240, options [mss 1460,nop,nop,TS val 2690206826 ecr 0,nop,wscale 7], length 016:45:28.681231 tun0 In IP 192.0.2.1.8080 > 192.168.146.240.52106: Flags [S.], seq 0, ack 92066968, win 10000, options [mss 1000], length 016:45:28.681260 tun0 Out IP 192.168.146.240.52106 > 192.0.2.1.8080: Flags [.], ack 1, win 64240, length 016:45:28.681482 tun0 Out IP 192.168.146.240.52106 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 64240, length 016:45:28.681508 tun0 In IP 192.0.2.1.8080 > 192.168.146.240.52106: Flags [R.], seq 1, ack 1, win 10000, length 0#
测试脚本的服务器端 < 属于手工模拟,所以即便是注入了 SACK 字段,也非真实场景。

SYN SACK

SYN 中 TCP options 的 SACK,代码中是通过 tcp_syn_options 函数确定的,相关的代码流程简要说明如下:

  1. sys_connect |--inet_stream_connect | |--tcp_v4_connect | |--tcp_connect | |--tcp_transmit_skb   |           |--tcp_syn_options

tcp_connect -> tcp_transmit_skb -> __tcp_transmit_skb -> tcp_syn_options 构造 SYN 的 Options 各字段,其中涉及 SACK 。

  1. /* Build a SYN and send it off. */int tcp_connect(struct sock *sk){... /* Send off SYN; include data in Fast Open. */ err = tp->fastopen_req ? tcp_send_syn_data(sk, buff) : tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); if (err == -ECONNREFUSED) return err;...}EXPORT_SYMBOL(tcp_connect);
  1. static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, gfp_t gfp_mask){ return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, tcp_sk(sk)->rcv_nxt);}
  2. static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, gfp_t gfp_mask, u32 rcv_nxt){... if (unlikely(tcb->tcp_flags & TCPHDR_SYN)) { tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5); } ...}

如果启用了 TCP SACK(ipv4.sysctl_tcp_sack),则设置 SACK 允许选项标志。

  1. static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, struct tcp_out_options *opts, struct tcp_md5sig_key **md5){... if (likely(sock_net(sk)->ipv4.sysctl_tcp_sack)) { opts->options |= OPTION_SACK_ADVERTISE; if (unlikely(!(OPTION_TS & opts->options))) remaining -= TCPOLEN_SACKPERM_ALIGNED; }...}

原文始发于微信公众号(Echo Reply):Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 SACK

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月23日12:19:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 SACKhttp://cn-sec.com/archives/2986756.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息