这两天有没有被 Log4j 爆出的漏洞给惊到!
作为一个行业人的角度来看(小白),我是在知道漏洞的第一时间看了一下相关的新闻也大概是知道这个漏洞是怎么一个来龙去脉了。
先来看看官方漏洞描述:
Apache Log4j2 是一个基于 Java 的日志记录工具。该工具重写了 Log4j 框架,并且引入了大量丰富的特性。该日志框架被大量用于业务系统开发,用来记录日志信息。
在大多数情况下,开发者可能会将用户输入导致的错误信息写入日志中。攻击者利用此特性可通过该漏洞构造特殊的数据请求包,最终触发远程代码执行。
该漏洞危害等级:严重
影响范围:2.0 <= Apache log4j2 <= 2.14.1
解释起来就是,当系统使用 log4j 通过 ${} 形式将用户输入的信息打印到日志时,那这就会出现安全问题
演示
1、新建一个基本 maven 项目
2、添加如下依赖
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.14.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.14.0</version> </dependency>
3、编写 Java 代码
public class Log4jErrorTest { private static final Logger logger = LogManager.getLogger(); public static void main(String[] args) { // 注意这个变量 String error = "${java:vm}"; logger.error("==============危险打印,{}", error); } }
4、结果
当然看到这里是不是觉得,这好像也没啥太危险的呀,那我想对于这样的获取系统参数值的好像确实没啥危险的顶多就是日志信息不一样而已。
看到这是,我们是不是要细思极恐一下
那,如果有黑客把 error 变量的值变为一个可访问的链接,log4j 是不是也会像执行参数一样,去执行它呢!
答案是显然的,会。
现在我们细思极恐一下,将一个类似 ${jndi:rmi//危险链接} 的字符串往目标程序中输入,那是不是就可以在受攻击服务器中执行。
如果真那样,随便注入一个数据库操作进行数据的修改是不是一下就飞黄腾达,人生巅峰,当然我不建议这样做哈。
原理
我们重点关注的就是字符串替换,log4j 根据占位符的原理将 {} 替换为需要占位的变量,而实现这一功能就是 log4j 中的一个 Lookup 功能。
官方 Lookup 文档地址:https://logging.apache.org/log4j/2.x/manual/lookups.html
而,我了解到这个功能是依据 JNDI 的,所以漏洞就是实现一个我们自定义的JNDI程序,往目标服务器程序发送,如果他们有打印我们输入的字符串,那么就会中招而在他们的系统中执行我自定义的程序。
注意,是我们的程序会在他们的服务器运行,这是最大的危险。(阿里定义危险系数10,好像已经是满级危险了)
解决方式
方式一:简单粗暴点,就是不用 log4j 日志
方式二:升级版本,直接升到 2.15.0 版本
如果,项目没有用 log4j 日志而引入 Maven 依赖的时候又被关联进项目了,那可以使用 Maven 依赖排除功能。
来看看我的项目是怎么查是否存在 log4j 依赖的把!
本人维护的项目:https://gitee.com/j3_baiqi/communication
1、通过搜索项目 jar 包发现本人项目还真有 log4j 依赖,但我本人非常清楚我是没有引入 log4j 相关依赖的,那就只有一种可能了,被其他依赖给关联进来了。
2、Maven help 插件查询 jar 包依赖关系
首先要安装该插件
3、进入要分析 pom.xml 文件,点击下面我标注的就可以看到所有依赖关系了。
4、接着就是找到log4j 的依赖,就可以看到依赖关系,如图
5、右键log4j 依赖选择排除,最后刷新 maven 就可以发现项目没有 log4j 相关依赖啦,非常安全,完美解决。
好了,今天的内容到这里就结束了,关注我,我们下期见