heapdump深度利用之信息泄露篇

前言

Java里有一些渗透场景可以获得堆内存也即是heapdump比如有的应用存在某个功能可以获取heapdumpspringboot/actuator/heapdump也可以获取。但是网上比较多的分析文章讲的都比较浅导致挺多人不知道heapdump里到底有什么东西,这篇文章讲一讲对heapdump进行深入分析获取某些特定信息。

常规信息获取

先讲一下大多数人的分析方式。最早的时候大家都是使用MATjhatjvisualvm然后使用oql语句去查询字符串里的敏感信息。我当时刚接触的时候对这个的分析文章比较少我记得最早讲的比较清楚的文章是下面这篇
https://zen-sec.github.io/fr/java-heapdump-extraction/

这个时期的oql语句主要集中在查询配置信息,以及内存中可能存在的user|pass|email|oss|aksk|jwt|shiro-key等信息后来有人写了自动化的分析工具主要是下面两款
https://github.com/wyzxxz/heapdump_tool
https://github.com/whwlsfb/JDumpSpider

距离工具发布到现在已经有好几年的时间了,然后我发现很多朋友好像已经不会使用oql语句自定义查询信息了,都是使用这两款工具执行一下就结束然后这两款工具有的时候输出没什么敏感的东西就直接结束了不再进行深度利用,我将在下面写一下这两款工具没有覆盖的一些信息获取方式。

深度信息获取

假设我们利用上述两款工具没有获取到什么有用信息还可以使用下面的方式进行利用,这里仅列举出一些案例有其他感兴趣的东西可以自己构造语句查询。使用MAT打开heapdump,主要现在MAT的主要版本需要使用jdk17+才能使用,我jdk环境默认1.8可以使用命令行vm参数指定一个jdk17路径打开
MemoryAnalyzer.exe -vm "C:\Users\admin\.jdks\jbr-17.0.12\bin\javaw.exe"

从这里打开你下载的heapdump然后点击下面图标进行oql查询

查询依赖版本

我们首先可以查看这个应用有什么依赖以及他们具体是什么版本,直接从字符串中搜索DISTINCT用于去重(也可通过类加载器查询)。

复制代码
SELECT DISTINCT toString(s) FROM java.lang.String s WHERE (toString(s) LIKE "file.*\.jar!/")

比如这里发现fastjson依赖在漏洞范围内即可尝试fastjson漏洞。

查询session

这里以springboot默认容器为例tomcat默认的session储存在org.apache.catalina.session.StandardSession中所以可以写出如下oql语句

复制代码
SELECT * FROM org.apache.catalina.session.StandardSession

我这里因为这个网站好像是被很多人扫描了导致尝试了大量无效session总计有1w+,所以需要想办法排除掉一些无效session这种无效session的尝试大多数是扫描器直接访问一个路由然后返回包就会返回一个session这种的话比较好筛选。我们可以注意点每个session实例里都储存了以下信息

根据上面的分析我们可以加一个判断(s.lastAccessedTime - s.creationTime) > 6000也就是最后访问时间需要大于创建时间6秒钟我们即认为是有效session。但是这还不足以判断session是否被设置了访问权限。一般登陆成功后都会使用setAttributesession里设置属性加上一些其他判断我们可以写出如下oql语句直接获取有效的sessionid

复制代码
SELECT s.id.toString() FROM org.apache.catalina.session.StandardSession s WHERE ((s.isValid = true) and (s.attributes != null) and ((s.lastAccessedTime - s.creationTime) > 6000))

有的session属性里甚至会直接存放账号密码

查询http数据包

上面我们查询到了session但是有很多时候并不是使用默认的session鉴权,所有可以获取http数据作为补充。我们知道springboot默认使用tomcat作为容器,经过代码分析已经查阅资料可知可以通过org.apache.coyote.http11.Http11InputBufferorg.apache.tomcat.util.net.SocketBufferHandler分别获取我们heapdump期间或之前尚未处理完的http数据包。

获取请求包

复制代码
SELECT h.byteBuffer.hb.toString() FROM org.apache.coyote.http11.Http11InputBuffer h 

先全选然后右键COPY->Selection即可复制所有数据

获取响应包,最开始以为会记录在Http11OutputBuffer里面经过分析发现Http11OutputBuffer里只记录返回包header数据,完整数据记录需要使用下面的语句查询

复制代码
SELECT rp.writeBuffer.hb.toString() FROM org.apache.tomcat.util.net.SocketBufferHandler rp

获取某些http缓存数据段

复制代码
SELECT DISTINCT bc.buff.toString() FROM org.apache.tomcat.util.buf.ByteChunk bc WHERE (bc.buff != null)

注意这里的数据不和请求包完全重叠,有可能记录一些更早的请求数据.比如这里直接获取了登陆的user、pass从请求包那里查询是没获取到的

查询springboot路由信息

根据之前分析springboot的经验可知路由信息储存在org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#mappingRegistry中我们使用oql语句查询它的实例

复制代码
SELECT * FROM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry

成功找到路由信息

注意到他最后都储存在java.util.LinkedHashMap$Entry所以我们可以直接使用下面语句获取所有路由

复制代码
SELECT key.toString() FROM java.util.LinkedHashMap$Entry entry WHERE (key.toString() LIKE "/.*")

也可通过MappingRegistration获取路由对应的方法

可以注意到这里已经获取路由对应的方法了且包含参数个数以及参数类型,还差获取参数名研究了一下发现有的情况是可以获取到参数名的。需要之前触发过这个路由,且缓存信息没被删除。

复制代码
select * from org.springframework.web.method.support.HandlerMethodArgumentResolverComposite

总结

本文介绍了Java heapdump的深度分析方法。除了使用常规的自动化工具获取基础敏感信息外,还可以通过自定义OQL语句进行更深入的信息挖掘。这些方法能够在常规工具无法发现敏感信息时,提供更深层次的数据挖掘能力,帮助渗透测试人员获取更多有价值的信息,如登录凭据、API接口、会话数据等。掌握这些技巧可以大大提升heapdump文件的利用价值。

相关推荐
Chan169 分钟前
【智能协同云图库】第七期:基于AI调用阿里云百炼大模型,实现AI图片编辑功能
java·人工智能·spring boot·后端·spring·ai·ai作画
mitt_31 分钟前
go语言变量
开发语言·后端·golang
无限大61 小时前
二维数组搜索:从暴力地毯到二分神技的奇幻之旅
后端
bobz9652 小时前
最近玩了好多把 LOL
后端
爱欲无极2 小时前
基于Flask的微博话题多标签情感分析系统设计
后端·python·flask
Olrookie4 小时前
若依前后端分离版学习笔记(五)——Spring Boot简介与Spring Security
笔记·后端·学习·spring·ruoyi
小白的代码日记5 小时前
基于 Spring Boot 的小区人脸识别与出入记录管理系统实现
java·spring boot·后端
Chaney不会代码5 小时前
Java7/8中的HashMap深挖
后端
新程快咖员5 小时前
兄弟们,你们安装IDEA 2025.2了吗?java编辑器代码提示失效?临时解决方案新鲜出炉!
后端·intellij idea