查看原文
其他

Struts,你为何死不悔改!

忆蓉之心 Java面试那些事儿 2019-12-19

上篇文章《诡异的字符串问题。。。》的问题已经解决了,我一直相信团队力量的重要性,虽然我不能保证加入群的每一个人都是乐于分享的同学,但我始终群里的各位同学总会慢慢被我们这种乐于分享的群氛围所影响。就以上篇文章为例,群里的 Univechige 同学专门给 IntelliJ IDEA 官方发邮件寻求原因,这便是一个好的开端,我相信有各位同学的共同维护,后面群氛围会越来越好。下面给出 IDEA 官方的答复,见下图。


像红色框内设置,便不会出现上篇文章出现的异常了,我后来去查看 IDEA 的官网反馈论坛上面,发现之前其实有人也遇到过类似问题,见下图。



看来遇到问题还是得去官网找到答案。




好了,言归正传,今天咱们来聊 Struts 安全 这个话题,肯定有很多同学会说,你一个做研发的,你讲安全不是搞笑吗?我在做研发之前,已经在 XXX 单位做了多年安全,认识不少业界的安全大牛「黑灰产勿扰」


一、Struts 的发展历程


要彻底搞清楚它,你就得去了解它的历史。说起 Struts,则就要从 J2EE 的 Web 项目发展初期说起,那个时候还处于刀耕火种的时代,大家开发 Web 项目除了使用 servlet 技术外,普遍都在 jsp 源码中,采用 Html 和 Java 代码混搭模式。这种模式造成一个弊端,业务逻辑和表现层代码混合在一起,导致开发和维护的成本逐渐偏大。为了摆脱这种弊端,大家提出了 MVC 这种软件架构模型来开发 Web 项目,见下图。



由于没有开源统一的 MVC 框架,大家基本上都在各自开发各自的框架。我认识的一个朋友给我说,那个年代如果能写一个 MVC 的框架,基本上都会是公认的大牛。


刚好 2000 年,国外叫 Craig McClanahan 的哥们儿采用了 MVC 的设计模式创造了 Struts,后来一度被认为是使用最广泛、最流行 Java 的 Web 应用框架。


2006 年,Struts 与 WebWork 合并,整合各自的优点,诞生了一个新的框架,就是如今的 Struts2。原先的 Struts 版本被改名为 Struts1 ,于 13 年 4 月停止开发。



这里不得不提的是 Struts2 的 OGNL 表达式,由于功能过于强大,极易产生远程执行漏洞,而开发组成员对漏洞的处理能力不足,导致应急响应修复一等再等,逐渐失去自己的市场份额,给了类似于 Spring MVC 等框架更多的机会。。。


二、CVE-2018-11776 漏洞成因


聊这个漏洞,主要是在朋友圈看到我的一个安全圈的好朋友称得上是黑客江湖的老侠客了 发了一个最新 Structs 漏洞,编号 CVE-2018-11776 。


这到底是一个什么样的漏洞呢?


该漏洞在开发人员未设置 namespace 值且上层动作配置 Action Configuration 也未设置 namespace 值或使用通配符时可能会导致远程代码执行漏洞,见下图。



我下面通过 lgtm 网站提供的漏洞演示视频来看一下它的危害。


https://v.qq.com/txp/iframe/player.html?vid=w1347tgt5wc&width=500&height=375&auto=0


其实对于了解 Struts 安全的读者来说,它已经不是第一次爆远程代码执行漏洞了,各位读者看看它的漏洞列表便明白了。



说实话,每次对 Struts 的应急响应时间感到捉急,就以这次来说吧。。。


2018年4月10日:Man Yue Mo 首次向 Struts 安全团队通报此漏洞详情。


2018年6月25日: Struts 团队发布补丁,修复此漏洞。


2018年8月22日:Struts 新版本发布「2.3.35和2.5.17」,Struts 团队和Semmle 安全研究团队共同发布公告。


这么慢的响应时间,给那些黑产留下充足的作案时间。


比如,2017年9月,美国3大老牌征信企业之一的 Equifax 公司网站遭遇黑客攻击,1.43亿美国公民的个人信息泄露,危及用户的社会保障号码、出生日期、住址以及部分驾驶执照号码等,事后溯源发现是由于该网站未修复的 Struts 漏洞「CVE-2017-5638」引起的。


很多同学可能会问怎么防范?


最直接暴力的方式禁用JVM执行外部命令,这个我们之前的一篇安全漏洞分析文章提过『Java安全之反序列化漏洞分析』。


三、那些年挖框架漏洞的一点心得


就像我一个做安全的朋友曾说过的,黑客攻击的最高境界就 9 个字「进得去,站的住,出得来」。在我看来,安全最重要的因素还是人,因此,我也一直认为社会工程学是最牛掰的。


那我先来说怎么通过社会工程学让别人中招呢,其实很简单,因为很多逗逼会不假思索的去照着教程去做,如果写教程的人留下一些后门,中招就再所难免了。这只是一点,其实还有很多,说白了还是人的问题,不是流行这一句话「傻子太多,骗子不够用」,建议大家去读一本书《社会工程:安全体系中的人性漏洞》。


我觉得对于你要挖掘一个网站的漏洞,你首先要知道它用了什么框架?也就是我们常说的嗅探「即信息收集的过程」。一般来说,我们可以通过后缀名或路径来判断,比如 .action、.do、/action/xxx、.form、.vm、.jsf 等,相信读此文的大多数读者都是开发者,一看到这样的后缀,多半就能猜测出来是用了什么框架。


但是,这也不是绝对的,有的开发者还是很聪明的,会重写 URL ,如果重写了怎么办呢?我这里给各位读者提供两种思路。


  • 利用一些框架的特殊性,比如 struts2 在 URL 请求后面加一个参数 ?actionErrors=aaaaa ,就会让页面报错;又比如,Spring MVC 的<form:checkbox path='ids' value='1'/> 会生成一个隐藏域  <input type='hidden' name='_ids' value='on'/>;等等。

  • 可以想办法让页面报错,通过报错信息来判断。


我觉得最重要的还是经验,熟悉各大漏洞的成因,比如 common-io 的拒绝服务漏洞、Java浮点漏洞、反序化漏洞、xxe漏洞、Java Hash碰撞的拒绝服务漏洞 等等。


由于 Java 强大的开源社区,各个框架都会多多少少依赖一些开源组件,如果一个组件出现了问题,则会影响一大片框架。比如之前的 CommonsCollections 组件的反序列化漏洞导致JBOSS,weblogic等中间件跟着受影响,这又能怪谁呢?如果你是团队的 Leader,建议统一规范化团队的组件,定期更新。


最后,我觉得对于一个框架而言,最重要的是做到「大道至简」。既然 OGNL  表达式总是出问题,为何不把 OGNL 作为一个插件,把选择权交给用户,让自己的核心功能更加稳定健壮呢?为什么不多招募一些安全爱好者加入自己的团队?你真的该好好反思了,无语。。。


如果觉得此文对你有帮助,欢迎点击右上角进行分享和转发。


参考

https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000622624--skipped-breakpoint-at-because-it-happened-inside-debugger-evaluation-

https://lgtm.com/blog/apache_struts_CVE-2018-11776

https://cve.mitre.org/cgi-bin/cvename.cgi?name=2018-11776

https://zh.wikipedia.org/wiki/Struts




最后,打一个小广告,我建了一个微信群,群规非常严格,在这个群里你得要懂得分享,我会不定期清理群,目前已经踢了不少吃白食的!



要想进群学习分享经验的话,请读一下上面的群规,看看自己适不适合,如果觉得自己是一个乐于分享的人,便可以加我微信 lamb978 入群,备注「加群」。


—————END—————

看更多技术好文

请长按下方图片扫码关注

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存