「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」
记修复Struts2的S2-046漏洞前后
这是2017年遇到的一件有趣的开发事故,这里和大家分享一下。(PS:之前我一直在简书上写技术文章,最近想把以前的文章搬到掘金并把这些文章好好改一下,这是第一篇)。
Struts2的这个漏洞的主要介绍:
由于上传功能的异常处理函数没有正确处理用户输入的错误信息,导致远程攻击者可通过发送恶意的数据包,利用该漏洞在受影响服务器上执行任意命令。攻击者可通过发送恶意构造的HTTP数据包利用该漏洞,在受影响服务器上执行系统命令,进一步可完全控制该服务器,造成拒绝服务、数据泄露、网站造篡改等影响。由于该漏洞利用无需任何前置条件(如开启dmi,debug等功能)以及启用任何插件,因此漏洞危害较为严重。(漏洞介绍:CVE-2017-5638)
漏洞是今年三月初爆出来的,开始的时候大家也关注了一下,但是当时每个人手上的项目都没有使用Struts2,而且也没听说公司有什么项目用Struts2然后大家就不太注意。到了3月中(估计是爆出漏洞的第3天),有人攻击进公司旗下的一个电商平台(一个有点年纪的项目了,而且没有人用)估计是白帽子黑客,只是发了段警告给我们,这个时候运维就联合我们一起修复,当时也不太重视而且其他项目很赶,就拖拖拉拉的。后面到了3月底,又有人来了这次就不是上一次那么好说话了,直接获取权限把数据清空。运维估计是一下子就慌了,数据没有完全备份的情况下,把系统重装(其实这个时候我们修复的版本已经弄好了,不知道什么原因没有上上去)。这下苦日子来了。
修复这个漏洞并不是件很复杂的事情,换换jar包轻轻松松就搞定。最严重的问题反而是来自于系统重装。
参与背景:
这次修复人员名单里面没有我(会议没有让我参加,当然责任列表中也没有我),后来实在感兴趣看了几眼给了几个建议,组长就拉进群组一起讨论(估计想叫多一点人,不至于大家被骂惨。当时一位新入职的同事也被临时加派其中),后来的经历让我觉得这次忙帮得很值!
下面介绍各个问题解决的前后的相关细节:
问题汇总:
- 重装系统之后,线上无法上传图片和文件(PS:请求完全没有提交到服务器),但是测试服和开发机器表现正常;
- 用户无法注册:提交信息之后,提示页面超时;
- 用户无法使用平台的金币买单;
- 问题1修复好之后,部分图片上传(上传图片做头像)报下面的异常:
java.lang.ClassNotFoundException: com.sun.image.codec.jpeg.JPEGCodec
复制代码
- 上面的问题都弄好之后,我们的搜索服务器:solr服务器启动不了(这里启动不了就完全用不了搜索功能);
- solr启动之后,还是用不了搜索功能。后来有同事说solr要同步索引;
- solr同步索引失败:同步时报:
400 Bad Request: unknown field 'type'
各个问题解决前后的细节:
问题1:
看起来最简单的第一个问题其实花了我们最多的时间,早上开会(还好没叫我去)领导开骂,大概10点半开始,然后下午两点多的时候才弄好。
对于这个问题大家的定位一开始有:
- a. 项目的上传路径分隔符写死;
- b. Struts2 里面有拦截器/过滤器 把提交的表单给拦截了;
- c. 为解决S2-046漏洞替换的jar在Linux下无法正常工作;
- 关于a:查看源码之后发现分隔符是使用标准的
File.separator来获取,路径是使用System.getProperty("user.dir")来获取,代码没有问题。后面怕线上的文件被替换过又拷贝一份进行对比,还是没问题———排除 - 关于b: 在定位b的时候,发现的一个很严重的问题。由于系统重装,服务器时间比标准时间慢3个多小时。这个时候顺便把后面的问题2,3完美解决掉了(因为所有关于钱的交易都在另一台服务器上,并且每一次交易都会进行时间验证。注册和登录在另一台服务器上原理大致一样)。正在我们准备把这个问题解决掉的时候,突然发现原来的代码根本没有时间验证。不死心的我们,在开发环境模拟线上这种时间错误的情况,一测还是可以上传(也就是说无法上传的问题和服务器时间错误无关)。后来发现代码有一个管理员ip限制的拦截器,以为自己最终找到了问题,打断点发现请求连这里都没进到,而且如果是这个问题测试服也会有问题。
- 关于c:直接pass(Linux测试环境中正常)
问题1 的最终结局:
后来越想越奇怪为什么测试服可以,开发机可以就线上不行呢?后来有人说有没有可能是重装导致线上的应用服务器没有上传权限。真是一眼惊醒梦中人,怎么想怎么像,而且页面跳转也是报404而不是500。写一个简单的文件上传页面,拿到线上一测。所有的问题都明了了,就是这个权限问题,运维被我们打了一顿。
问题2:
因为重装导致服务器时间不标准(相差3个小时),注册登录服务器与该项目部署到不同的机器。注册时进行时间验证不通过,所以报超时异常。
问题3:
与问题2类似
问题4:
其实这个问题也是线上才出问题。我们上网搜了一下,有人说com.sun.image.codec.jpeg.JPEGCodec人家已经不推荐使用了,后来换了ImageIO。测过之后线上线下都没问题。
问题5:
其实这个不算是问题,只不过找不到之前的solr服务器备份了。后面找了很早之前的一个备份,然后根据solr的部署规则部署在一台tomcat上。问题解决。
问题6:
原本以为部署solr之后,搜索功能就会乖乖回来。测了一下–毛线都没有!!!想打人,不过看看已经在墙角躺尸的运维忍了。这时候一直没有存在感的新同事来了一句关键的—-“solr是要同步索引的”。
问题7:
听新同事说Solr索引同步可以在Solr后台进行,登录后台之后发现这他妈是什么,整么跟百度谷歌上面长得一点都不像。弄了好久。。。后来运维做了一件事,让我深深地惭愧,运维居然找出了写在后台的一个跟新solr索引库的方法,自责!不应该对运维这么粗鲁,这么多大汉对他一个有点残忍。。。。正当我们以为可以走人的时候,方法报错了。哈哈哈!
不过好在solr服务器有明显的报错—400 Bad Request: unknown field 'hnihh'。这个时候我们居然在没有百度谷歌的情况下完全靠猜把问题解决了。当时我们是这么想的:solr估计就像个数据库,那么里面的索引估计是在什么地方有配置的(就像MySQL的表结构语句),看看配置信息估计是solr没有将字段’hnihh’没有配置进去,看了看Solr里面的文件组成,确定是xml文件配置的。
然后就将solr下面所有的xml拉下来,最后锁定在scheme.xml这里。打开一看,果然项目中的索引字段都在里面,唯独缺了”hnihh”。添加完<filed….>标签之后,重启再来,问题解决。最后搜出结果的那一刻、那一种心情,估计只有程序员才能理解。
后续问题:
所有代码、系统层面上的问题都解决之后。页面显示还是有bug–很多图片都没有,这个就是因为没备份导致图片缺失。其中各种找备份还原,其中辛苦不足为外人道。

本次漏洞修复心得:
- 对于极大多数人来说在代码面前没有什么问题是解决不了的。
很多时候代码上的一个小问题都会使得你精疲力尽、无可奈何,但其实背后的问题其实很小很小(参考问题1、2、3);
很多时候看起来很复杂的技术,其本质估计你早已知晓。花一两个小时认真学进去,不焦急不慌(参考问题5、6、7); - 许多互联网公司提倡的九九六根本就没有必要;
本次bug解决总时长12个小时,去掉不是问题的问题(问题1)花去的时间大概9个小时。参与人员:3人,这说明什么问题估计大家都明白; - 遇到漏洞一定要重视;
- 公司或组内有重大问题或事故要解决的时候,有条件的话积极参与。即使没有问你,也可以厚脸皮问他几下、看他几眼。这种事情我们不希望发生,但是确实相当好的一个机会;
- 大胆假设问题所在,通过其他方面进行联想和验证;
- 尽量不选择Struts2。























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)