0x00 前言

有点回到学习Java反序列化的时光了,Java内存马的体量也很大。但我必须要提速了。

本文先认识一下Java内存马,并且再分析一次Tomcat的架构。

0x01 内存马概述

在内存马之前,主要是文件马。随着查杀技术的发展,大部分文件马的生存空间逐渐缩小,而内存马并无文件实体,只存在于内存之中,隐蔽性强,故而愈发盛行。

其实内存马由来已久,早在17年n1nty师傅的《Tomcat源码调试笔记-看不见的shell》中已初见端倪,但一直不温不火。后经过rebeyong师傅使用agent技术加持后,拓展了内存马的使用场景,然终停留在奇技淫巧上。在各类hw洗礼之后,文件shell明显气数已尽。内存马以救命稻草的身份重回大众视野。特别是今年在shiro的回显研究之后,引发了无数安全研究员对内存webshell的研究,其中涌现出了LandGrey师傅构造的Spring controller内存马

内存马种类繁多,主要是三种类型:

  1. servlet-api类
    • filter型
    • servlet型
  2. spring类
    • 拦截器
    • controller型
  3. Java Instrumentation类
    • agent型

在讲内存马的原理之前,需要先了解一下jsp。

0x02 JSP概述

jsp是什么

JSP(Java Server Pages)是Java的一种动态网页技术,可以看作一个Java Servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。当第一次访问JSP页面时,Tomcat服务器会将JSP页面翻译成一个java文件,并将其编译为.class文件。JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。

jsp环境搭建

看这篇师傅的文章:Servlet 项目搭建 | Drunkbaby’s Blog

也可以去看白日梦组长的:java内存马专题1-servlet内存马_哔哩哔哩_bilibili

jsp语法

不妨先看一下这篇教程,对jsp语法有个大致的了解:JSP 语法 | 菜鸟教程

可能还是不太理解,没关系,用到再说。

0x03 JSP文件马

在内存马之前,是传统的文件马。现在打入内存马,也往往要依靠jsp文件马。

下面是一个简单的jsp文件马,直接运行会在浏览器上会弹calc:

1
2
3
4
5
6
7
8
<%@ page import="java.io.IOException" %>
<%
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
%>

但是如何把马放入内存中呢,有两个思路:

  • 利用Java Web组件:动态添加恶意组件,如Servlet、Filter、Listener等。在Spring框架下就是Controller、Intercepter。
  • 修改字节码:利用Java的Instrument机制,动态注入Agent,在Java内存中动态修改字节码,在HTTP请求执行路径中的类中添加恶意代码,可以实现根据请求的参数执行任意代码。

其实核心思路就是在服务的必经之路