输出型爱好
基于 packetdrill TCP 三次握手脚本,通过构造模拟服务器端场景,测试无 SACK 下的 TCP Dup ACK 现象。
基础脚本
# cat tcp_dupack_000.pkt
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1000>
+0 > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 10000
+0 accept(3, ..., ...) = 4
#
TCP Dup ACK
TCP Dup ACK 简单来说是指 TCP 发送了相同 ACK 序号的 ACK 数据包,即重复 ACK,触发的原因可能是丢包或者乱序。实际在 Wireshark TCP 分析中,关于 TCP Dup ACK 的定义也相对来说简单,包括如下:
TCP 段大小为 0; 窗口大小非零且没有改变,或者有有效的 SACK 数据; 下一个期望的 Seq Num 和 LastACK Num 是非 0 的(即连接已经建立); 没有设置 SYN、FIN、RST。
Set when all of the following are true:
The segment size is zero.
The window size is non-zero and hasn’t changed, or there is valid SACK data.
The next expected sequence number and last-seen acknowledgment number are non-zero (i.e., the connection has been established).
SYN, FIN, and RST are not set.
基础测试
因缺失中间一段数据,在收到后一段数据后,就会触发产生 TCP Dup ACK 数据包。
# cat tcp_dupack_001.pkt
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1000>
+0 > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 10000
+0 accept(3, ..., ...) = 4
+0 < P. 1:101(100) ack 1 win 10000
+0 < P. 201:301(100) ack 1 win 10000
#
# packetdrill tcp_dupack_001.pkt
#
# tcpdump -i any -nn port 8080
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
17:00:01.578944 tun0 In IP 192.0.2.1.60795 > 192.168.188.154.8080: Flags [S], seq 0, win 10000, options [mss 1000], length 0
17:00:01.578961 tun0 Out IP 192.168.188.154.8080 > 192.0.2.1.60795: Flags [S.], seq 1320734975, ack 1, win 64240, options [mss 1460], length 0
17:00:01.589110 ? In IP 192.0.2.1.60795 > 192.168.188.154.8080: Flags [.], ack 1, win 10000, length 0
17:00:01.589298 ? In IP 192.0.2.1.60795 > 192.168.188.154.8080: Flags [P.], seq 1:101, ack 1, win 10000, length 100: HTTP
17:00:01.589341 ? Out IP 192.168.188.154.8080 > 192.0.2.1.60795: Flags [.], ack 101, win 64140, length 0
17:00:01.589360 ? In IP 192.0.2.1.60795 > 192.168.188.154.8080: Flags [P.], seq 201:301, ack 1, win 10000, length 100: HTTP
17:00:01.589368 ? Out IP 192.168.188.154.8080 > 192.0.2.1.60795: Flags [.], ack 101, win 64140, length 0
17:00:01.589468 ? Out IP 192.168.188.154.8080 > 192.0.2.1.60795: Flags [R.], seq 1, ack 101, win 64140, length 0
17:00:01.589503 ? In IP 192.0.2.1.60795 > 192.168.188.154.8080: Flags [R.], seq 301, ack 1, win 10000, length 0
#
经 Wireshark 展示如下,可以看到满足判断条件后,No.7 标识 [TCP Dup ACK 5#1]
,意味着 No.7 与 No.5 重复 ACK,发生一次。
如果想触发多次重复的 Dup ACK,可增加几次后续数据段即可,如下
# cat tcp_dupack_002.pkt
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1000>
+0 > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 10000
+0 accept(3, ..., ...) = 4
+0 < P. 1:101(100) ack 1 win 10000
+0 < P. 201:301(100) ack 1 win 10000
+0 < P. 301:401(100) ack 1 win 10000
+0 < P. 401:501(100) ack 1 win 10000
#
# packetdrill tcp_dupack_002.pkt
#
# tcpdump -i any -nn port 8080
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
17:05:08.106952 tun0 In IP 192.0.2.1.36083 > 192.168.142.207.8080: Flags [S], seq 0, win 10000, options [mss 1000], length 0
17:05:08.106979 tun0 Out IP 192.168.142.207.8080 > 192.0.2.1.36083: Flags [S.], seq 3830404217, ack 1, win 64240, options [mss 1460], length 0
17:05:08.117054 ? In IP 192.0.2.1.36083 > 192.168.142.207.8080: Flags [.], ack 1, win 10000, length 0
17:05:08.117130 ? In IP 192.0.2.1.36083 > 192.168.142.207.8080: Flags [P.], seq 1:101, ack 1, win 10000, length 100: HTTP
17:05:08.117142 ? Out IP 192.168.142.207.8080 > 192.0.2.1.36083: Flags [.], ack 101, win 64140, length 0
17:05:08.117151 ? In IP 192.0.2.1.36083 > 192.168.142.207.8080: Flags [P.], seq 201:301, ack 1, win 10000, length 100: HTTP
17:05:08.117154 ? Out IP 192.168.142.207.8080 > 192.0.2.1.36083: Flags [.], ack 101, win 64140, length 0
17:05:08.117158 ? In IP 192.0.2.1.36083 > 192.168.142.207.8080: Flags [P.], seq 301:401, ack 1, win 10000, length 100: HTTP
17:05:08.117160 ? Out IP 192.168.142.207.8080 > 192.0.2.1.36083: Flags [.], ack 101, win 64140, length 0
17:05:08.117164 ? In IP 192.0.2.1.36083 > 192.168.142.207.8080: Flags [P.], seq 401:501, ack 1, win 10000, length 100: HTTP
17:05:08.117167 ? Out IP 192.168.142.207.8080 > 192.0.2.1.36083: Flags [.], ack 101, win 64140, length 0
17:05:08.117238 ? Out IP 192.168.142.207.8080 > 192.0.2.1.36083: Flags [R.], seq 1, ack 101, win 64140, length 0
17:05:08.117262 ? In IP 192.0.2.1.36083 > 192.168.142.207.8080: Flags [R.], seq 501, ack 1, win 10000, length 0
#
经 Wireshark 展示如下,No.7 标识 [TCP Dup ACK 5#1]
,No.9 标识 [TCP Dup ACK 5#2]
,No.11 标识 [TCP Dup ACK 5#3]
,共重复三次。
通常如果发送端在收到三次 Dup ACK 数据包,则会触发出基础的快速重传,此处暂且不表。
因中间一段数据乱序后至,在收到乱序数据后,就会触发产生 TCP Dup ACK 数据包。
# cat tcp_dupack_003.pkt
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1000>
+0 > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 10000
+0 accept(3, ..., ...) = 4
+0 < P. 1:101(100) ack 1 win 10000
+0 < P. 201:301(100) ack 1 win 10000
+0 < P. 101:201(100) ack 1 win 10000
#
# packetdrill tcp_dupack_003.pkt
#
# tcpdump -i any -nn port 8080
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
15:28:41.218948 tun0 In IP 192.0.2.1.47103 > 192.168.241.42.8080: Flags [S], seq 0, win 10000, options [mss 1000], length 0
15:28:41.218977 tun0 Out IP 192.168.241.42.8080 > 192.0.2.1.47103: Flags [S.], seq 3953882990, ack 1, win 64240, options [mss 1460], length 0
15:28:41.229046 tun0 In IP 192.0.2.1.47103 > 192.168.241.42.8080: Flags [.], ack 1, win 10000, length 0
15:28:41.229120 tun0 In IP 192.0.2.1.47103 > 192.168.241.42.8080: Flags [P.], seq 1:101, ack 1, win 10000, length 100: HTTP
15:28:41.229134 tun0 Out IP 192.168.241.42.8080 > 192.0.2.1.47103: Flags [.], ack 101, win 64140, length 0
15:28:41.229139 tun0 In IP 192.0.2.1.47103 > 192.168.241.42.8080: Flags [P.], seq 201:301, ack 1, win 10000, length 100: HTTP
15:28:41.229142 tun0 Out IP 192.168.241.42.8080 > 192.0.2.1.47103: Flags [.], ack 101, win 64140, length 0
15:28:41.229145 tun0 In IP 192.0.2.1.47103 > 192.168.241.42.8080: Flags [P.], seq 101:201, ack 1, win 10000, length 100: HTTP
15:28:41.229148 tun0 Out IP 192.168.241.42.8080 > 192.0.2.1.47103: Flags [.], ack 301, win 63940, length 0
15:28:41.229240 tun0 Out IP 192.168.241.42.8080 > 192.0.2.1.47103: Flags [R.], seq 1, ack 301, win 63940, length 0
15:28:41.229267 tun0 In IP 192.0.2.1.47103 > 192.168.241.42.8080: Flags [R.], seq 201, ack 1, win 10000, length 0
#
经 Wireshark 展示如下,可以看到满足判断条件后,同样 No.7 标识 [TCP Dup ACK 5#1]
,意味着 No.7 与 No.5 重复 ACK,之后乱序的 No.8 数据包后至补充上空洞,提示 [TCP Out-Of-Order],接收端响应 ACK 数据包 ACK Num 301。
同样乱序触发多次重复 Dup ACK,一样增加几次后续数据段即可,如下
# cat tcp_dupack_004.pkt
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1000>
+0 > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 10000
+0 accept(3, ..., ...) = 4
+0 < P. 1:101(100) ack 1 win 10000
+0 < P. 201:301(100) ack 1 win 10000
+0 < P. 301:401(100) ack 1 win 10000
+0 < P. 401:501(100) ack 1 win 10000
+0 < P. 101:201(100) ack 1 win 10000
#
# packetdrill tcp_dupack_004.pkt
#
# tcpdump -i any -nn port 8080
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
15:38:05.898973 tun0 In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [S], seq 0, win 10000, options [mss 1000], length 0
15:38:05.898998 tun0 Out IP 192.168.190.243.8080 > 192.0.2.1.56293: Flags [S.], seq 710034056, ack 1, win 64240, options [mss 1460], length 0
15:38:05.909158 ? In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [.], ack 1, win 10000, length 0
15:38:05.909284 ? In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [P.], seq 1:101, ack 1, win 10000, length 100: HTTP
15:38:05.909310 ? Out IP 192.168.190.243.8080 > 192.0.2.1.56293: Flags [.], ack 101, win 64140, length 0
15:38:05.909317 ? In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [P.], seq 201:301, ack 1, win 10000, length 100: HTTP
15:38:05.909321 ? Out IP 192.168.190.243.8080 > 192.0.2.1.56293: Flags [.], ack 101, win 64140, length 0
15:38:05.909324 ? In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [P.], seq 301:401, ack 1, win 10000, length 100: HTTP
15:38:05.909327 ? Out IP 192.168.190.243.8080 > 192.0.2.1.56293: Flags [.], ack 101, win 64140, length 0
15:38:05.909330 ? In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [P.], seq 401:501, ack 1, win 10000, length 100: HTTP
15:38:05.909333 ? Out IP 192.168.190.243.8080 > 192.0.2.1.56293: Flags [.], ack 101, win 64140, length 0
15:38:05.909347 ? In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [P.], seq 101:201, ack 1, win 10000, length 100: HTTP
15:38:05.909350 ? Out IP 192.168.190.243.8080 > 192.0.2.1.56293: Flags [.], ack 501, win 63740, length 0
15:38:05.909571 ? Out IP 192.168.190.243.8080 > 192.0.2.1.56293: Flags [R.], seq 1, ack 501, win 63740, length 0
15:38:05.909614 ? In IP 192.0.2.1.56293 > 192.168.190.243.8080: Flags [R.], seq 201, ack 1, win 10000, length 0
#
经 Wireshark 展示如下,No.7 标识 [TCP Dup ACK 5#1]
,No.9 标识 [TCP Dup ACK 5#2]
,No.11 标识 [TCP Dup ACK 5#3]
,共重复三次,之后乱序的 No.12 数据包后至补充上空洞,接收端响应 ACK 数据包 ACK Num 501。
往期推荐
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...