如果谁有旋转升降座椅爆炸的短视频,麻烦提供给我。


按照昨天文章里写的那个思路:
https://blog.csdn.net/dog250/article/details/95252740
刚刚复现并录制了一个SACK Panic的POC动画,我用两台直连虚拟机测试的结果:

复现率超过90%,每次重试次数几乎不超过3次即可使机器panic。

然而在实际网络环境中测试,复现率必然会降低。

和一位仁兄讨论的结果,所见略同,大概的问题基本就是一对矛盾:

  • 长肥管道和丢包

若想憋准大于64KB段数的的skb,保证17*32768字节的长度在发送缓冲区未被确认,就要BDP很大,即长肥管道,但是长肥管道丢包代价太大且难恢复。我在虚拟机网络,内网以及家庭路由器网络测试的复现率大致分别是90%,50%,30%,这些都是 好网络 ,可想而知,公网上很难触发这个漏洞。

公网上很多限速,清洗,丢包率无法保证,并且你也很难算出来。此外,即便你营造了一个长肥管道,如果服务器端没有做cork,skb还是容易细水长流走,也就是说你很难积累判断发送端是否积累了足够的未确认数据,如果pacing rate控制不好,细水长流走是难免的。这个可以通过采用burst积累ack的方式模拟发送端的cork,但是时序还是很难控制。

也许是我这个POC不好吧,如果谁有更好的,欢迎一起探讨。不过我还是只提供思路,详见:https://blog.csdn.net/dog250/article/details/95252740
另一个POC等过段时间再拿出来。

不过,我觉得以上这些技术困难都不是问题,本来这种DDoS漏洞就不是用来精准狙击的,既然近距离有中枪的概率,那意味着互联网上扫一波,总有机器中招,有点类似古代攻城战前盲射的那一波弓箭。至少起到 让你害怕 的作用就足够了,这非常像街头的那些铁链子纹身花衬衫光头的小混混,就是吓唬作用,大的他们也搞不来,反而那些温文尔雅的长袍礼帽的喝茶大叔更可怕一些。


下面该解药了。

Netflix&Redhat官方以及社区给出的方案都是 限制合并frags的总大小不要超过65535 。参见下面的patch:
https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001/PATCH_net_1_4.patch
其核心是增加了这么一个限定函数:

+int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from,
+        int pcount, int shiftlen)
+{+  /* TCP min gso_size is 8 bytes (TCP_MIN_GSO_SIZE)
+   * Since TCP_SKB_CB(skb)->tcp_gso_segs is 16 bits, we need
+   * to make sure not storing more than 65535 * 8 bytes per skb,
+   * even if current MSS is bigger.
+   */
+  if (unlikely(to->len + shiftlen >= 65535 * TCP_MIN_GSO_SIZE))
+      return 0;
+  if (unlikely(tcp_skb_pcount(to) + pcount > 65535))
+      return 0;
+  return skb_shift(to, from, shiftlen);
+}

但是在我看来,这是不对的!

这种解法根本就没有踩到问题的根源!

由于总量超过65535了,所以溢出,那么不让总量超过65535不就行了吗?

无可厚非,能解决问题,算紧急补救措施吧,是个人第一个想到的都是这个方案,没啥问题。

但是,若想彻底解决这个问题,不妨刨下根源。

内核有两个限制性的设定:

  1. 一个frag在x86至多是32KB字节的大小。
  2. 一个skb至多有17个frags。

现在让我们简单算一下17个32768字节的数据总量一共是多少,很简单, 17 × 32768 17\times 32768 17×32768字节。而gso_segs字段的类型是u16,即最多65535个segs。

问题是, 当初为什么人们认为gso的segs最多65535就够了? 我想用u16表示segs字段,他们是为了节省内存吧。按照常规的mss,65535确实够了,但是精算起来,如果raw data的mss为8的话,u16就要溢出了,而我们看下,u16,mss为8,17个段,最大表示65535个segs,这四者之间确实有点微妙的关系:

  • 32768 × 2 = 65536 32768\times 2=65536 32768×2=65536
  • 17 2 = 8 + 1 \dfrac{17}{2}=8+1 217​=8+1

如果想到mss可能是8的话,就差那么一点点就不溢出了!是的,就差一点!8已经是最小的raw data的mss了,当然,如果有新的TCP option可能会更小,但现如今,常规情况下,能凑出的比较小的raw data mss就是8了。这样算来, 17 × 32768 8 = 65536 + 32768 8 \dfrac{17\times 32768}{8}=65536+\dfrac{32768}{8} 817×32768​=65536+832768​,就差这么一点点。选择gso_segs用u16真的比较合适,但是溢出了 32768 8 \dfrac{32768}{8} 832768​的数据,就是错了。

但是现实中,mss会为8吗?很少,但是理论上确实会存在!

所以问题的根源在于 gso_segs字段选型错误!它应该用u32来表示,而不是u16!

内核规定每一个frag最多32KB没有错,内核每一个skb最多携带17个非线性frags也没有错,这些是体系结构相关的约定俗成,mss可以是48字节且携带40字节options更是没有错,这是网络的约定俗成,是gso_segs没有适配它们,而不是反过来啊!

一个是系统的约定,一个是编程的失误,为什么程序员们总是修改代码去适配约定而不喜欢修改数据类型呢?!

嗯?修改数据类型的话,每一个skb多了2个字节!是的,多了两个字节!那么100万个包就多了2M个字节,关键是内存贱啊,2M怕什么!为什么程序员总是喜欢改代码呢?改一个数据类型不就好了吗?明显就是gso_segs定义的有问题啊。

噢,对了,紧急修复必须是kpatch,而kpatch不支持结构体数据类型的修改。嗯,很不错的自我安慰…可是我在最新版的mainline上看到的gso_segs依然是u16啊!

如果程序员(特别是那么David Miller,没啥了不起的)如此执着,就是不改数据类型,那么也不要增加if逻辑啊,代码多了不是好事。既然gso_segs字段溢出了,那就让tcp_shifted_skb的pcount参数也溢出呗,将它定义成u16而不是int,问题就解决了。我们知道,计算机里的数字,就是一个环,大家都同样回绕,相对大小关系不会发生任何改变。

所以,我的patch建议,要么如下:

- unsigned short gso_segs;
+ unsigned int gso_segs;

要么就这样:

static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,struct tcp_sacktag_state *state,
-               unsigned int pcount, int shifted, int mss,
+               unsigned short pcount, int shifted, int mss,bool dup_sack)

而不是去添加什么限制代码,那样只会越来越乱!别忘了糟糕的RFC5961。


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

SACK Panic的POC演示与修复建议相关推荐

  1. TCP SACK panic漏洞的解释和思考

    最近几天一直在和CVE-2019-11477 SACK panic漏洞进行纠缠,挺有意思的. 细节就不多说了,给出几个链接自己看吧: https://access.redhat.com/securit ...

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

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

  3. QEMU CVE-2020-14364 漏洞分析(含 PoC 演示)

     聚焦源代码安全,网罗国内外最新资讯! 作者:奇安信代码安全实验室研究员张子明(@Ezrak1e) 奇安信代码安全实验室研究员为Red Hat发现六个漏洞(CVE-2020-14364.CVE-202 ...

  4. 前脚修复,后脚放 PoC:马上修复这个严重的SAP Recon 漏洞!

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 就在 SAP 刚刚发布 NetWeaverAS JAVA 远程代码执行漏洞补丁后,PoC exploit 就已现身且各种漏洞扫描活动变 ...

  5. CNVD-2022-03672/CNVD-2022-10270:向日葵简约版/向日葵个人版for Windows命令执行漏洞复现及修复建议

    CNVD-2022-03672/CNVD-2022-10270:向日葵简约版/向日葵个人版for Windows命令执行漏洞复现及修复建议 本文仅为验证漏洞,在本地环境测试验证,无其它目的 漏洞编号: ...

  6. 漏洞介绍及修复建议(漏洞汇总,建议收藏后期会不断更新)

    目录 未分类 Host 头攻击(高危) 域名访问限制不严格(高危) URL 重定向(中危) 会话劫持漏洞(中危) 会话固定漏洞(中危) DNS 域传送漏洞(中危) 检测到网站被黑痕迹(高危) 传输层保 ...

  7. 网站安全检测 漏洞检测 对thinkphp通杀漏洞利用与修复建议

    thinkphp在国内来说,很多站长以及平台都在使用这套开源的系统来建站,为什么会这么深受大家的喜欢,第一开源,便捷,高效,生成静态化html,第二框架性的易于开发php架构,很多第三方的插件以及第三 ...

  8. 常见WEB漏洞描述及修复建议(可收藏写报告用)-句芒安全实验室

    注:以下内容部分摘自网络,部分工作总结. 一.明文传输 漏洞描述: 用户登录过程中使用明文传输用户登录信息,若用户遭受中间人攻击时,攻击者可直接获取用户密码. 修复建议: 1.用户登录信息时使用加密传 ...

  9. Web常见漏洞修复建议

    一.SQL注入修复建议 1.过滤危险字符,例如:采用正则表达式匹配union.sleep.and.select.load_file等关键字,如果匹配到则终止运行. 2.使用预编译语句,使用PDO需要注 ...

最新文章

  1. 关于量子计算,你应该知道的七个事实
  2. 面向初级 Web 开发人员的 Tomcat
  3. rust大油田分解机_油田泥浆泵油田环保罐车配套泥浆泵
  4. c#与WMI使用技巧集
  5. 11.23关于微信JSAPI缺少参数的问题解决
  6. sql分区-纵向分表与横向分区表(转)
  7. BFS+状态压缩 hdu-1885-Key Task
  8. oracleasm 建立时出错
  9. Java DO到DTO转换利用spring 的BeanUtils.copyProperties
  10. 硬件基础:电脑当中各个硬件的作用介绍
  11. JavaScript基于对象编程
  12. iris数据集 测试集_IRIS数据集的探索性数据分析
  13. java nio doug_深入的聊聊 Java NIO
  14. 命令启动jar包_java项目打jar包,一句命令搞定
  15. Spring Boot + Activiti 工作流框架搭建
  16. java实现单向链表的增、删、改、查
  17. BZOJ5343[Ctsc2018]混合果汁——主席树+二分答案
  18. 瑞利衰落(Rayleigh Fading)
  19. 181231每日一句
  20. Chrome驱动对应chrome浏览器版本

热门文章

  1. SECURITY06 - Zabbix报警机制、Zabbix进阶操作、自定义监控案例
  2. 蒙特卡洛树搜索方法介绍——Q规划与Dyna-Q算法
  3. Java反射03 : 获取Class的注解、修饰符、父类、接口、字段、构造器和方法
  4. 北京Uber优步司机奖励政策(4月4日)
  5. java 按钮添加音乐_Java运行窗体/程序添加自定义背景音乐
  6. [深度学习概念]·深度学习中人脸识别开发解析
  7. dpdk SR-IOV 创建VF失败
  8. CSS之字体属性的设置
  9. 学习笔记-ARIMA模型
  10. 考研计算机考多少算高分,考研究生需要多少分才能录取 考多少算高分