freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

Java安全红队面试详解 | servlet 内存马原理分析和POC编写和查杀
pony686 2025-03-25 09:54:42 55136
所属地 北京

1.什么是内存马

以Tomcat为例,内存马主要利用了Tomcat的部分组件会在内存中长期驻留的特性,只要将我们的恶意组件注入其中,就可以一直生效,直到容器重启。
Java内存shell有很多种,大致分为:
1动态注册filter
2动态注册servlet
3动态注册listener
4基于Java agent拦截修改关键类字节码实现内存shell

2.什么是Servlet

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,它早期的名称为catalina,后来由Apache、Sun 和其他一些公司及个人共同开发而成,并更名为Tomcat。Tomcat 是一个小型的轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选,因为Tomcat 技术先进、性能稳定,成为目前比较流行的Web 应用服务器。Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展,但它是独立运行的。
从宏观上来看,Tomcat其实是Web服务器和Servlet容器的结合体。
Web服务器:通俗来讲就是将某台主机的资源文件映射成URL供给外界访问。(比如访问某台电脑上的图片文件)
Servlet容器:顾名思义就是存放Servlet对象的东西,Servlet主要作用是处理URL请求。(接受请求、处理请求、响应请求)
Tomcat由四大容器组成,分别是Engine、Host、Context、Wrapper。这四个组件是负责关系,存在包含关系。只包含一个引擎(Engine):
Engine(引擎):表示可运行的Catalina的servlet引擎实例,并且包含了servlet容器的核心功能。在一个服务中只能有一个引擎。同时,作为一个真正的容器,Engine元素之下可以包含一个或多个虚拟主机。它主要功能是将传入请求委托给适当的虚拟主机处理。如果根据名称没有找到可处理的虚拟主机,那么将根据默认的Host来判断该由哪个虚拟主机处理。
Host (虚拟主机):作用就是运行多个应用,它负责安装和展开这些应用,并且标识这个应用以便能够区分它们。它的子容器通常是 Context。一个虚拟主机下都可以部署一个或者多个Web App,每个Web App对应于一个Context,当Host获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理。主机组件类似于Apache中的虚拟主机,但在Tomcat中只支持基于FQDN(完全合格的主机名)的“虚拟主机”。Host主要用来解析web.xml。
Context(上下文):代表 Servlet 的 Context,它具备了 Servlet 运行的基本环境,它表示Web应用程序本身。Context 最重要的功能就是管理它里面的 Servlet 实例,一个Context代表一个Web应用,一个Web应用由一个或者多个Servlet实例组成。
Wrapper(包装器):代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。Wrapper 是最底层的容器,它没有子容器了,所以调用它的 addChild 将会报错。

1742805109_67e11875984a2c020c504.png!small?1742805110237
2.1 前置知识

我们知道的Tomcat创建Servlet的过程分为五部

  1. 加载:当Tomcat第一次访问Servlet的时候,Tomcat会负责创建Servlet的实例
  2. 初始化:当Servlet被实例化后,Tomcat会调用init()方法初始化这个对象
  3. 处理服务:当浏览器访问Servlet的时候,Servlet 会调用service()方法处理请求
  4. 销毁:当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法,让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁
  5. 卸载:当Servlet调用完destroy()方法后,等待垃圾回收。如果有需要再次使用这个Servlet,会重新调用init()方法进行初始化操作

所以我们的内存马要写到service这个地方才方便我们调用,有了前面两个内存马的学习,servlet内存马跟两个内存马也大同小异,所以这里我们就大概的看一下一些重要的不同的地方

2.2 创建过程分析

在Tomcat的机制中我们知道三件套加载的顺序是Listener-----filter-----servlet这样的加载机制,确定一下吧,把断点打在init这个点

2.3 tomcat调式分析servlet

当前的tomcat版本是 9.0.68
在pom.xml 添加依赖

<dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>9.0.68</version>
        </dependency>

1742805126_67e11886325993530adb5.png!small?1742805127660
helloServlet 这个Servlet是创建的时候自动有的

package com.example.ncm;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
    private String message;

    public void init() {
        message = "Hello World!";
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html");

        // Hello
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>" + message + "</h1>");
        out.println("</body></html>");
    }

    public void destroy() {
    }
}

在org/apache/catalina/startup/ContextConfig.java 在此处下一个断点

private void configureContext(WebXml webxml) {
        // As far as possible, process in alphabetical order so it is easy to
        // check everything is present
        // Some validation depends on correct public ID
        context.setPublicId(webxml.getPublicId());

在这个地方设置一个断点 可以看到webxml这个类中有三个 serlvet 其中有一个就是helloServet 前两个是系统自带的。服务器自动的时候自动加载进来。

1742805556_67e11a349d99323039355.png!small?17428055574441742805563_67e11a3bf06b277b9775d.png!small?1742805564747遍历servlet 用 wrapper 进行装载

for (ServletDef servlet : webxml.getServlets().values()) {
   
可试读前30%内容
¥ 19.9 全文查看
9.9元开通FVIP会员
畅读付费文章
最低0.3元/天
# 渗透测试 # web安全 # 系统安全 # 数据安全 # 网络安全技术
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 pony686 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
pony686 LV.6
公众号:亿人安全
  • 64 文章数
  • 427 关注者
记一次域内渗透实战之Cragty
2025-03-10
JAVA安全——红队面试常问问题之Shrio漏洞详解
2025-03-06
记一次对CVE-2024-20656(VS提权漏洞)的复现与分析
2025-02-25
文章目录