Agent MemShell

0x01 Preface

利用Java Agent可以动态修改类的字节码,由于实际环境中都是启动着的JVM,所以premain并不适用,而是利用agentmain来注入内存马。

接下来就得思考要修改哪个类的字节码了,对于这个类应该有如下要求:

  • 类中的方法一定会被执行

  • 改动后不影响正常业务

前面Filter内存马的Filter组件就挺不错

每次请求到达Servlet前都会经过FilterChain来对请求进行过滤,ApplicationFilterChain#doFilter一定会被调用

0x02 Env Build

SpringBoot搭建一个Commons Collections反序列化漏洞环境,再通过CC11把内存马打进去

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>
package com.example.agent.controllers;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ObjectInputStream;

@RestController
public class Vul {
    @PostMapping("/cc11")
    public String cc11(HttpServletRequest request, HttpServletResponse response) throws Exception {
        java.io.InputStream inputStream =  request.getInputStream();
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
        objectInputStream.readObject();
        return "Hello,World";
    }

    @GetMapping("/hello")
    public String hello(){
        return "hello agent";
    }
}

创建Agent:

mvn clean package

Evil.class 为用于注入jar的字节码

发现一个问题:loadAgent只能寻找本地的Agent jar包吗?

  • 如果是,那么打Agent内存马还得先上传jar

  • 如果不是,能否加载远程的jar包

试了一下,好像真不能加载远程jar。。。。

Error opening zip file or JAR manifest missing: http://127.0.0.1:9999/MyAgent.jar

CC11 序列化数据生成:

curl -v "http://192.168.0.106:8080/cc11" --data-binary "@./ser.bin"

image-20230203212742399

控制台打印这些说明注入成功!

image-20230203234313144

0x03 Trap

刚开始发现内存马没打进去,通过sout大法发现问题出现在ClassPool pool = ClassPool.getDefault(); ,根据之前的经验感觉可能是jar包里没依赖。

SpringBoot项目添加javassist依赖,发现内存马注入成功

原来用Maven的package没有把第三方依赖打进jar包,加入下面的插件就可以带上依赖

打包后有两个jar包,一个带jar-with-dependencies标签。

但又有新问题了

com.sun.tools.attach.AgentLoadException: Agent JAR not found or no Agent-Class attribute

去看一眼META-INF/MENIFEST.MF,果然里面没有Agent-Class字段

仿照上一个插件,<configuration>下添加<archive>元素,指定manifestEntries

0x04 Summary

前面三种内存马(ListenerFilterServlet)是传统的Web应用型内存马,基于原生Servlet API实现的动态注册内存马。

而Agent内存马是通过Hook并修改关键方法添加恶意逻辑,需要落地Jar,再通过Attach API动态注入Agent到JVM中。

后面可能还要学习一下中间件型内存马ValveUpgradeExecutor,探索Tomcat的设计模式,以及框架型内存马Spring ControllerSpring Interceptor,体会Spring MVC对Servlet API的封装。

Last updated

Was this helpful?