1. Java内存马
最早17年n1nty的《Tomcat源码调试笔记-看不见的shell》系列文章,介绍无文件webshell,早些年讨论范围较小,之后 20/21/22年的hw,将内存马逐步发扬光大。
Java内存马,大致分为:
1.2 Filter/Servlet/Listener机制
Filter
Filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter无法产生一个请求或者响应,它只能针对某一资源的请求或者响应进行修改。
Servlet
Servlet是一种运行服务器端的java应用程序,具有独立于平台和协议的特性,并且可以动态的生成Web页面,它工作在客户端请求与服务器响应的中间层。Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。
Listener
通过Listener可以监听web服务器中某一个执行动作,并根据其要求作出相应的响应。
1.3 Java内存马类型
Filter类型内存马
-
中间件内存马注入&冰蝎连接(附更改部分代码)https://mp.weixin.qq.com/s?__biz=MzU5NDgxODU1MQ==&mid=2247491241&idx=1&sn=3dc54d10191661620437cb8409ab1755&scene=21#wechat_redirect
-
filter内存马技术https://blog.csdn.net/localhost01/article/details/107340698
-
基于Tomcat无文件Webshell研究https://mp.weixin.qq.com/s?__biz=MzI0NzEwOTM0MA==&mid=2652474966&idx=1&sn=1c75686865f7348a6b528b42789aeec8&scene=21#wechat_redirect
-
Tomcat内存马学习 (一)http://wjlshare.com/archives/1529
-
Tomcat 内存马学习(二):结合反序列化注入内存马http://wjlshare.com/archives/1541
-
Java安全之基于Tomcat实现内存马https://www.cnblogs.com/nice0e3/p/14622879.html
Servlet类型内存马
-
Java内存马综述-servlet和listener型https://mp.weixin.qq.com/s?__biz=MzIxMjEwNTc4NA==&mid=2652991099&idx=1&sn=a6c34bb344f105eb98fc6943c7439331&scene=21#wechat_redirect
Listener类型内存马
-
Tomcat下基于Listener的内存Webshell分析http://foreversong.cn/archives/1547
Spring controller类型内存马
-
基于内存 Webshell 的无文件攻击技术研究https://www.anquanke.com/post/id/198886#h2-6
-
针对Spring MVC的controller内存马https://www.cnblogs.com/bitterz/p/14820898.html
Spring Interceptor类型内存马
-
利用 intercetor 注入 spring 内存 webshellhttps://landgrey.me/blog/19/
-
针对Spring MVC的Interceptor内存马https://www.cnblogs.com/bitterz/p/14859766.html
Tomcat注入内存马
-
基于tomcat的内存 Webshell 无文件攻击技术https://xz.aliyun.com/t/7388
-
Tomcat中一种半通用回显方法https://xz.aliyun.com/t/7348
Weblogic注入内存马
-
中间件内存马注入&冰蝎连接(附更改部分代码)https://mp.weixin.qq.com/s?__biz=MzU5NDgxODU1MQ==&mid=2247491241&idx=1&sn=3dc54d10191661620437cb8409ab1755&scene=21#wechat_redirect
-
weblogic 无文件webshell的技术研究https://www.cnblogs.com/potatsoSec/p/13162792.html
Java agent类型内存马
-
利用“进程注入”实现无文件复活 WebShellhttps://www.freebuf.com/articles/web/172752.html
Java 内存马查杀
-
Tomcat 内存马检测https://www.anquanke.com/post/id/219177
-
查杀Java web filter型内存马https://gv7.me/articles/2020/kill-java-web-filter-memshell/
-
Filter/Servlet型内存马的扫描抓捕与查杀https://gv7.me/articles/2020/filter-servlet-type-memshell-scan-capture-and-kill/
-
基于javaAgent内存马检测查杀指南https://www.77169.net/html/278275.html
Java 内存马取证工具
-
https://github.com/alibaba/arthas
-
https://github.com/LandGrey/copagent
-
https://github.com/c0ny1/java-memshell-scanner
-
https://syst1m.com/post/memory-webshell/
-
https://github.com/4ra1n/shell-analyzer/releases/tag/0.1
2. Java内存马取证与处置
2.1 Java instrumentation机制
Java Instrumentation最早于Java SE5 引入,Java SE6之后的机制相对于Java SE5有较大改进。
Java Instrumentation指的是可以用独立于应用程序之外的代理(agent)程序来监测和协助运行在JVM上的应用程序。这种监测和协助包括但不限于获取JVM运行时状态,替换和修改类定义等。Java Instrumentation可以在JVM启动后,动态修改已加载或者未加载的类,包括类的属性、方法。
Java Instrumentation可以理解为Java一种热加载/补丁,利用该机制可以,将webshell字节码直接注入到JVM中的Java应用中,实现拦截/篡改发送到应用的网络请求,实现无文件攻击。
2.1 Java内存马取证思路
利用Java Instrumentation机制不仅仅可以注入内存马,我们也可以利用该机制,检查加载到jvm中的类是否异常,对内存马进行检测/取证和处置。
整体思路为:
-
获取jvm中所有加载的类
-
遍历每个类,判断是否为风险类。可能被新增/修改内存中的类,标记为风险类(比如实现了Filter/Servlet的类)
-
遍历风险类,检查是否为webshell
-
检查高风险类的class文件是否存在
-
反编译风险类字节码,分析Java文件中是否包含恶意代码
取证时需要关注的风险类以及方法,包括但不限于:
下面先介绍,Java内存马取证和处置常用的工具。
2.2.1 arthas
Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
Arthas
支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab
自动补全功能,进一步方便进行问题的定位和诊断。
我们可以利用这个工具对jvm的所有类进行取证分析。
- wget https://github.com/alibaba/arthas/releases/download/arthas-all-3.7.0/arthas-bin.zip;
- unzip arthas-bin.zip
- java -jar arthas-boot.jar
某些系统报错找不到tools.jar,需要下载对应的tools.jar放置到jdk目录的jre/lib下
arthas附加到指定java进程中
arthas 常用命令
- dashboard:显示当前应用程序的实时运行状况,包括 CPU 使用率、内存使用情况、线程情况等
- jvm:查看和管理 JVM 的相关信息,包括堆内存、GC 状态、类加载情况等
- sc:查看和搜索类信息,包括加载的类、类的字段和方法等。
- sm:查看和搜索方法信息,可以查看方法的字节码、参数、返回值等
- jad:反编译指定类的字节码,查看类的实现代码。
- classloader:显示当前应用程序中所有的类加载器及其层次结构。可以查看每个类加载器的名称、父加载器和已加载的类数量
- heapdump 生成 Java 应用程序的堆转储(Heap Dump)文件
2.2.2 heapdump
利用arthas工具的heapdump 生成 Java 应用程序的堆转储(Heap Dump)文件hprof
分析hprof文件中可疑的字符串
2.2.3 Java memshell scanner
https://github.com/c0ny1/java-memshell-scanner
将java-memshell-scanner.jsp上传到tomcat应用目录下,访问此jsp,会自动查找可疑内存马,可dump class文件下来分析,也可直接kill掉该类。
2.2.4 Shell Analyzer
https://github.com/4ra1n/shell-analyzer
注意:在真实环境/生产环境下使用,存在打崩业务的可能
服务端上传agent.jar
和remote.jar
客户端执行java -jar gui.jar
即可
2.3 Tomcat环境部署
Linux环境下部署Tomcat8,首先安装openjdk 1.8
- sudo add-apt-repository ppa:openjdk-r/ppa
- sudo apt-get update
- sudo apt-get install openjdk-8-jdk
- sudo update-alternatives --config java
下载安装Tomcat8
- wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.91/bin/apache-tomcat-8.5.91.tar.gz
- sudo tar zxvf apache-tomcat-8.5.91.tar.gz
- sudo mv apache-tomcat-8.5.91 /opt
- sudo ln -s /opt/apache-tomcat-8.5.91/ /opt/tomcat8
启动Tomcat8
- /opt/tomcat8/bin/startup.sh
访问服务器8080端口
将其upload-demo.war包,上传到tomcat8/webapps/ROOT目录下,配置tomcat8/conf/server.xml文件
- <Context path="/upload" docBase="/opt/tomcat8/webapps/ROOT/upload-demo.war" reloadable="true"></Context>
重启Tomcat,访问文件上传路径
2.4 Behinder内存马
2.4.1 Behinder注入内存马
首先了解一下,Behinder memShell的整个植入流程:
-
将inject.jar和agent.jar上传至目标Web Server任意目录下。
-
以tomcat进程启动的系统用户执行java -jar inject.jar。
-
inject.jar会通过一个循环遍历查找Web Server上的JVM进程,并把agent.jar注入到JVM进程中,直到注入成功后,inject.jar才会退出。
-
注入成功后,agent.jar执行agentmain方法:
(a) 遍历所有已经加载的类,查找“org.apache.catalina.core.ApplicationFilterChain”,并对该类的internalDoFilter方法进行修改。
(b)将磁盘上的inject.jar和agent.jar读进tomcat内存中。
(c) 对memShell做初始访问,为了初始化,有两种方法初始化类,第一是把需要的类手动加载一次,第二是模拟做一次初始化访问,memShell采用的后者。在删除之前如果没有访问过memShell的话,memShell相关的一些类就不会加载进内存,这样后续访问memShell时会报ClassNotFound异常。
(d) 删除落地的inject.jar和agent.jar。Linux系统下,正常删除文件即可。Windows系统下,由于有文件锁定机制,当一个文件被其他程序占用时,这个文件是处于锁定状态不可删除的,inject.jar正在被JVM所占用。要删除这个jar包,需要先打开该进程,遍历该进程的文件句柄,通过DuplicateHandle来关闭文件句柄,然后再执行删除,Behinder将这个查找句柄、关闭句柄的操作编译为exe,memShell判断为Windows系统时,会下发exe文件来关闭句柄,再删除agent.jar。
-
memShell注入完毕,正常接收请求,通过访问http://xxx/anyurl?show_the_world=password
-
当JVM关闭时,会首先执行我们注册的ShutdownHook:
(a)把第4步(b)中我们读进内存的inject.jar和agent.jar写入JVM临时目录。
(b)执行java -jar inject.jar,此后返回上述第3步。
对漏洞环境上传webshell并注入内存马
2.4.2 内存马取证分析
使用arthas工具附加到tomcat进程中
2.4.2.1 Behinder webshell取证
分析Servlet信息
- sc *.Servlet
发现一个可疑的Servlet,org.apache.jsp.Upload.shell_jsp,这个是我们上传的webshell
利用jad命令,反编译指定类的字节码
- jad org.apache.jsp.Upload.shell_jsp
查看webshell代码,明显为Behinder的webshell代码
2.4.2.2 memShell类型内存马取证
分析 org.apache.jsp.Upload.*下所有的类
- sc org.apache.jsp.Upload.*
发现一个可疑的org.apache.jsp.Upload.shell_jsp$U类
反编译org.apache.jsp.Upload.shell_jsp$U类的字节码
- jad org.apache.jsp.Upload.shell_jsp$U
发现使用 super.defineClass 方法将字节数组转换为一个 Class 对象并加载
Behinder memShell是Servlet类型的,直接分析风险类的反编译代码
- jad javax.servlet.http.HttpServlet
发现在javax.servlet.http.HttpServlet类的service方法中,被注入了 内存马
其中base64解码后为class文件,class文件反编译后的源码为Behinder webshell(最终实现功能的内存马)
利用arthas工具的heapdump 生成 Java 应用程序的堆转储(Heap Dump)文件hprof
分析hprof文件中可疑的字符串
2.4.3 内存马处置
将java-memshell-scanner.jsp上传到tomcat应用目录下,访问此jsp,会自动查找可疑内存马,可dump class文件下来分析,也可直接kill掉该类。
服务端上传agent.jar
和remote.jar
客户端执行java -jar gui.jar
即可
- java -cp jdk1.8.0_202/lib/tools.jar:gui-0.1.jar com.n1ar4.Application
- java -cp gui-0.1.jar com.n1ar4.Application
2.5 Godzilla内存马
2.5.1 Godzilla注入内存马
反编译org.apache.coyote.type.ArrayType类
- jad org.apache.coyote.type.ArrayType
继承了加载器Class Loader和过滤器Filter的接口
添加一个过滤器,拦截的uri路径"/*",并将过滤器配置和过滤器映射添加到Context标准上下文中,然后对过滤器进行排序,确保为最高的优先级,最先触发此过滤器
2.5.3 内存马处置
将java-memshell-scanner.jsp上传到tomcat应用目录下,访问此jsp,会自动查找可疑内存马,可dump class文件下来分析,也可直接kill掉该类。
服务端上传agent.jar
和remote.jar
客户端执行java -jar gui.jar
即可
- java -cp jdk1.8.0_202/lib/tools.jar:gui-0.1.jar com.n1ar4.Application
- java -cp gui-0.1.jar com.n1ar4.Application
原文始发于微信公众号(TahirSec):Java | 内存马取证与处置浅析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论