你好呀,我是歪歪。
上周大家应该都被 log4j 的日志破绽给刷屏了吧?
我看到这个破绽的时候留神到它有“影响范畴十分广,且上手难度低”的特点。
我就想验证一下上手难度到底有多低,于是我翻了很多文章,都是大同小异,说出破绽了,很牛逼,连忙修吧,晚了就玩完啦。而后配上一个唤起了计算器的截图,就完结了,也没有人通知我到底怎么玩啊。
我也想唤起计算器,学(装)习(装)(逼)下。
于是我在网上查了一系列材料,到处摸索。从找材料到实现攻打大略花了一个小时左右的工夫。
过后我就震惊了:这玩意上手难度的确很低啊!
原本开始我还是想写写对于破绽的复现,然而写着写着打消了这个念头。
首先我即便复现了,也还是不太懂它的工作原理是什么。我只晓得是能够通过 JNDI 的形式加载攻击者的类,而这个类因为是攻击者编写的,外面就能够搞很多事件了。
你想想,我能在你的代码环境外面执行我写的一些代码,哪怕我再不晓得怎么攻打,我写个死循环,写个 sleep 语句也能玩死你了啊。
如果是切实想写出有价值的文章,钻研的方向能够去看看 JNDI 相干的技术。
然而我感觉我卷不动了,所以就不写了。
其次我查了一下,还不能写的太具体,毕竟是破绽,流传其复现办法也不太好,仿佛还波及到法律问题,所以大家晓得怎么防备就好。
再说了,这是平安那一帮人干的事儿啊,我不想去卷他们的饭吃。
最初,其实我发现 B 站上曾经有比拟具体的视频演示了。贴个链接,只是我不晓得这个视频还能被保留多久:
https://www.bilibili.com/vide…
因为目前给出的解决方案,就是降级 jar 包嘛,所以这篇文章我次要给大家介绍一个插件吧,能在肯定水平上晋升大家的降级速度。
我平时也用它,用棘手了后,香的一比。
sb 的日志
我没有骂人啊,我是想说 SpringBoot 的日志。
当初大家的利用都是基于 SpringBoot 去构建的,那么 SpringBoot 默认的日志框架是什么呢?
我也不晓得,所以我筹备搭建一个污浊的 SpringBoot 我的项目来看一眼。
又多污浊呢?
就是我通过 IDEA 构建新我的项目的时候,除了指定 SpringBoot 版本号为 2.6.1 外,没有引入其余的任何的包。
而后,咱们看一下 pom 文件,货色十分的少:
的确污浊啊,和纯净水似的。
接着咱们把我的项目启动起来:
你看啊,神奇的事件就呈现了,我一行代码都没动呢,什么都还没配置,日志就主动打进去了。
所以之前我素来没有留神到,然而这次的事件让我想到了这个问题:
SpringBoot 默认的日志框架是什么呢?
我想到的第一个办法是这样的:
隔着搁哪的猜啥啊,能用代码解决的问题就少哔哔,加两行日志打印一下不就完事了吗?
从输入我能够晓得,哦,原来用的是 logback 啊。
其余的办法
除了后面这个办法之外,还有什么方法能晓得是 logback 呢?
于是我紧接着想到了查看 pom 依赖图。
在 IDEA 外面,有个一键查看 pom 依赖图的形式,特地简略。
就是在 maven 标签外面点这个图标就能够了:
如果你找不到这个图标,也能够在 pom 文件外面右键,而后顺次抉择 Maven->Show Dependencies:
而后你就会看到这样的一个界面,外面有 logback-core 包,阐明引入了 logback 日志的实现:
有的小伙伴就要问了:我看依赖外面不是还有一个 log4j-api 吗?你凭什么说不是用的 log4j 呢?
老铁,只有 api 没有 core 包啊,外围实现都在 core 包外面的。
比方这次 log4j 爆出问题的代码,也就是 lookup 那块的逻辑,就都在 core 包外面。
然而为什么修复的倡议是让咱们同时排出 log4j-api 和 log4j-core 呢?
我集体通俗的认为是 core 都不必了,api 留着意义也不大吧。如果只有 log4j-api 的依赖,依据我把握的攻打原理,是不会有问题的。
好了,先不扯远了,说回这个污浊的 SpringBoot 我的项目。
我后面给你说的看依赖图的形式,其实我个别不必。
为什么呢?
因为在实在的我的项目外面,依赖关系可能是极其简单的,看起来稀稀拉拉的,你没有任何想看的欲望,比方给大家看看 dubbo 我的项目的 pom 依赖图,十分的刺激,十分的有冲击感啊:
到这里,咱们先思考一个问题:你个别关上 pom 文件是干啥?
是不是在排查 jar 包抵触或者找 jar 包的时候须要用到?
所以在后面的页面外面能够按了 Ctrl+F 之后进行搜寻,就像这样:
然而你去用的时候其实真的还是很不好用的。
于是乎,我要给你介绍的插件就来了。
https://plugins.jetbrains.com…
这个插件,香的一笔啊。
怎么装置就不介绍了,留神本人对应的 IDEA 版本就行。
次要给大家看看它怎么用的。
装置好了之后,你再次关上 pom 文件,能够看到上面有个这个货色:
外面是长这样的:
咱们次要关注这个中央,我把正文也给你写上:
这个外面,次要就是用到两个外围性能。
- 排查依赖抵触。
- 查问 jar 包依赖。
比方,咱们看一下咱们这个污浊的我的项目外面和 log 相干的包:
高深莫测,咱们也看到了后面提到的 logback-core 包。
实战演练
光说不练假把式,接下来给大家来个应用 maven-helper 的实战演练。
比方咱们就拿 Dubbo 开刀,用起来其实非常简单的。
就拿这次 log4j 破绽事件来说,咱们要排查出我的项目外面所有的 log4j-api 和 log4j-core 包。
我抉择 Dubbo 我的项目外面的这个模块来做演示吧:
比方先关上 autoconfigure 包上面的 pom 文件:
而后搜一下 log4j:
能够看到 log4j-api 是由 spring-boot-starter-logging 引入进来的。
在这里右键,而后点击 Exclude 即可排出:
刷新依赖,再次查问就没了:
就是这么的简略,其余的模块也都是这样,我就不一一演示了。
然而有个问题呈现了,Dubbo 作为中间件,排出了之后就不能不论了呀,还得引入一个新的平安版本进来。
咱们能够看一下 Dubbo 这次对于 log4j 破绽提交的 pr:
https://github.com/apache/dub…
能够看到排除了 log4j-api 同时也引入了一个新版本的 log4j-api。
版本号放在了父 pom 外面,实现了对版本的对立治理:
如果后续还须要降级 log4j-api 只须要调整父 pom 外面的版本号就行。
再来一个
再给大家来一个例子,演练一下。
这个例子借鉴于这个链接外面:
https://juejin.cn/post/694522…
首先是在后面污浊的 SpringBoot 我的项目中多引入了 Dubbo 的包,而后引入了 zookeeper 作为注册核心:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>2.7.9</version>
</dependency>
</dependencies>
同时,记得在 application.properties 文件外面加上这行配置,否则启动不起来:
dubbo.application.name=xxx
启动的时候你能够看到这样的揭示日志:
怎么样,是不是很眼生?在大多数的我的项目启动的时候都遇到过?
下面的揭示日志能够分为两组,一组是 SLF4J,一组是 log4j。
很多人都晓得这个问题必定是呈现依赖抵触,日志框架凌乱。
所以首先咱们再看一下我的项目外面的日志依赖,看到有一个 log4j 的依赖抵触:
二话不说,先右键给它排掉,在 pom 文件外面就是这样体现的:
然而须要留神的是,咱们不能间接就把 log4j 包删除了就不论了,这里援用了阐明我的项目外面应用了 log4j,因而咱们须要把 log4j 桥接到 slf4j 上,从而达到排除了 log4j,然而日志还能失常打印的目标:
<!-- 减少 log4j-slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.30</version>
</dependency>
再次启动我的项目,你就发现,只剩下 SLF4J 这一个问题了:
再次关上依赖剖析:
能够发现我的项目同时领有了 slf4j-log4j12 和 log4j-to-slf4j,另外还有个 logback 的存在。
所以,我的项目外面共存了两套 slf4j 的实现,别离是 log4j 和 logback。
其实这一点,从日志中也能够看进去:
日志揭示你了:Class path contains multiple SLF4J bindings.
两套实现,在我的项目启动的时候先加载那个就应用哪个,这是很不靠谱的事件。
基本的解决方案就是排除其中的一个。
比方咱们还是应用默认的 logback,那就排除 slf4j-log4j 这个依赖。
再次启动我的项目,之前的抵触日志都没有了,难受了:
好,那么如果我不想用 logback,就想用牛逼的 log4j 怎么办呢?
https://docs.spring.io/spring…
批改一下 maven 就行:
从日志打印就晓得了,当初的实现是 log4j。
而后,对于 log4j 这个破绽,我想说,日志就干好日志的事儿,弄这么多简单的性能干啥呢?实现 KPI 啊?
说真的,在这个破绽被爆进去之前,我都不晓得它还有这些高级的性能呢,我寻思如同也用不到啊。
感觉就很像是有人特意留下的后门,这就细思极恐了,以及脑补了一场大戏。
最初,看到一个段子,送给大家。
快过年了,不要再探讨什么 log4j、cs、bypass、流量检测之类的了。
你带你的破电脑回到家并不能给你带来任何实质性作用,敌人们兜里掏出一大把钱吃喝玩乐,你默默的在家里摆弄你的褴褛 rce。
亲戚朋友吃饭问你播种了什么,你说我装了个虚拟机,把各个工具都玩了一遍,亲戚们懵逼了,你还在心里默默讥笑他们,笑他们不懂你的主动注入,不懂你的 10 层代理、不懂你的流量混同,也笑他们连个简单点的明码都记不住。
你父母的共事都在说本人的子女一年的播种,儿子买了个房,女儿买了个车,姑娘升职加薪了,你的父母默默无言,说我的儿子搞了个破电脑,开起来嗡嗡响、家里电表走得越来越快了。
本文已收录至集体博客,欢送大家来玩。
https://www.whywhy.vip/