利用 instrument API 简单实现的 Java RASP.
特性:
- Hook 大部分的方法
- 检查, 替换方法的参数
- 检查, 替换方法的返回值
- Hook
org.springframework.web.servlet.FrameworkServlet.service
获得请求的参数. - Hook
java.lang.ProcessImpl.<init>
得到实际执行的命令, 只是一个 demo, 仅能防御 Runtime.exec() 直接跑一个参数的情况 (逃 - Hook
java.io.ObjectInputStream.readClassDesc
的返回值, 阻止恶意类反序列化. - Hook
javax.naming.spi.NamingManager.getObjectFactoryFromReference
阻止 LDAP 注入. - Hook
sun.rmi.server.LoaderHandler.lookupLoader
阻止远程设置恶意 codebase. - Hook
com.sun.org.apache.xerces.internal.impl.XMLEntityManager.expandSystemId
避免 XML 外部实体注入.
hook 声明基于注解, 示例:
@HookHandler(hookClass = "org.springframework.web.servlet.FrameworkServlet", hookMethod = "service")
public static Object[] requestHook(Object self, Object[] params) {
currRequest.set(params[0]);
return params;
}
默认的 hook 类型是在真正的代码运行前. 如果 hook 的目标方法是非 static
传入的参数为 Object self, Object[] params
,
如果是 static
则为 Object[] params
, params 为函数的实参, self 为被调用方法所属的对象. 其中返回值会被用于替换原来的参数.
还有两种为在代码运行后, 传入的参数为 Object ret
, 为函数的返回值, 对于 AFTER_RUN, 返回值会被用于替换原返回值.
而对 AFTER_RUN_FINALLY, 即使 hook 的方法运行中抛出异常, 也会被运行, 因此无法替换原返回值.
更多示例可以看 hooks 文件夹下的代码.
java -javaagent:easyrasp-1.0-SNAPSHOT-jar-with-dependencies.jar target_class