Simple Java Rasp
基于 Java Instrumentation + Javaassist
@RaspHandler
标记一个用于处理的 Handler 类, 参数用于定位被 Hook 的方法或构造函数
- className: 类名
- methodName: 方法名 (可选)
- isConstructor: 是否为构造函数 (默认为 false)
- parameterTypes: 方法/构造函数的参数类型
@RaspBefore
标记一个在目标方法刚开始调用时进行处理的方法, 对应 Javaassist 中的 insertBefore
方法签名: public static Object[] handleBefore(Object obj, Object[] params)
- obj: 当目标方法为非静态方法时, 该值为目标对象本身 (this), 为静态方法时该值为 null
- params: 目标方法的参数列表
- 返回值: 默认为 params, 用于替代目标方法原来的参数
@RaspAfter
标记一个在目标方法 return 之前进行处理的方法, 对应 Javaassist 中的 insertAfter
方法签名: public static Object handleAfter(Object obj, Object result)
- obj: 同上
- result: 目标方法 return 的值, 如果方法返回类型为 void, 则该值为 null
- 返回值: 默认为 result, 用于替代目标方法原来的返回值
拦截 Runtime.exec 方法
package com.simplerasp.handlers; import com.simplerasp.annotations.RaspAfter; import com.simplerasp.annotations.RaspBefore; import com.simplerasp.annotations.RaspHandler; import com.simplerasp.exceptions.RaspException; import sun.misc.IOUtils; @RaspHandler(className = "java.lang.Runtime", methodName = "exec", parameterTypes = {String.class}) public class RuntimeExecHandler { @RaspBefore public static Object[] handleBefore(Object obj, Object[] params) { System.out.println("before"); String cmd = (String) params[0]; System.out.println("try to exec: " + cmd); if (cmd.contains("Calculator")) { throw new RaspException("Reject malicious command execution attempts"); } return params; } @RaspAfter public static Object handleAfter(Object obj, Object result) throws Exception{ System.out.println("after"); Process p = (Process) result; String output = new String(IOUtils.readAllBytes(p.getInputStream())); if (output.contains("uid=")) { throw new RaspException("Reject malicious command execution output"); } return result; } }
拦截 ProcessBuilder 构造函数
package com.simplerasp.handlers; import com.simplerasp.annotations.RaspBefore; import com.simplerasp.annotations.RaspHandler; import com.simplerasp.exceptions.RaspException; @RaspHandler(className = "java.lang.ProcessBuilder", isConstructor = true, parameterTypes = {String[].class}) public class ProcessBuilderHandler { @RaspBefore public static Object[] handleBefore(Object obj, Object[] params) { System.out.println("before"); String cmd = String.join(" ", (String[])params[0]); System.out.println("try to exec: " + cmd); if (cmd.contains("Calculator")) { throw new RaspException("Reject malicious command execution attempts"); } return params; } }
拦截 Log4j2 JNDI 注入
package com.simplerasp.handlers; import com.simplerasp.annotations.RaspBefore; import com.simplerasp.annotations.RaspHandler; import com.simplerasp.exceptions.RaspException; @RaspHandler(className = "org.apache.logging.log4j.core.net.JndiManager", methodName = "lookup", parameterTypes = {String.class}) public class JndiManagerLookupHandler { @RaspBefore public static Object[] handleBefore(Object obj, Object[] params) { System.out.println("before"); String name = (String) params[0]; String[] blacklist = new String[]{"ldap", "jndi"}; for (String s : blacklist) { if (name.toLowerCase().contains(s)) { throw new RaspException("Reject malicious jndi lookup attempt"); } } return params; } }
Modified some code from the following repos