热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

heapdump攻击面利用

点击上方蓝字关注我们一、heapdump案例1.1项目中的分析这个是项目中遇到的一个例子,发现了heapdump泄露,但没有找到可用session




图片

点击上方蓝字关注我们

一、heapdump案例


1.1 项目中的分析

这个是项目中遇到的一个例子,发现了heapdump泄露,但没有找到可用session,当时就想着内存中应该是有账号密码的,于是就开始找了起来。

用OQL进行搜索,先找数据库密码,很好找,但由于是内网数据库没啥用。

然后无脑直接找session id,但没有找到

图片

观察数据包,发现使用了JWT认证,但搜索JWT开头字符串依旧没有结果

图片

图片

再仔细看了一下请求包,COOKIE中的参数名为xxx_USER_COOKIEs,搜索该参数名但依旧搜索不到

select * from java.lang.String s where toString(s) like ".*_USER_COOKIEs.*"

图片

后面我又想到直接搜索类名即可得到对应字符串,所以我就直接去找java.lang.String类下面的内容

图片

但并没有找到什么东西,点击Shallow Heap和Retained Heap进行排序也没找到什么有用信息

图片

然后看着一系列的类名想起,java中并不是只有String,byte[]和char[]也可以转换为String,所以又去找byte[]和char[]的内容

图片

然后点击 Shallow Heap 按钮倒序排列,我发现了新天地

图片

PK开头的明显是压缩包,而其他的又很明显是HTTP请求包,于是我开始挨个右击->Copy->Save Value To File(注意,这里尽量不要直接复制值,因为1. 会有无法显示的字符导致看起来不够美观;2. 直接复制值仅能复制1024个字符,剩下的会被截断)

图片

保存完之后,再打开文件,某一个请求包中就有别人登录时使用的明文账号密码!!!(至于格式为什么是这样的就不清楚了)

图片


1.2 项目后的思考


1.2.1 为什么String不能倒序搜索,byte[]却可以?

做项目时,虽然找到了账号密码,但还有一些问题没有解决,想再测试一下。

简单了解了一下OQL和MAT,我们前面使用的直接搜索类的对象部分,其实是在各个对象的引用列表中穿梭查看。对于给定一个对象,通过MAT可以找到引用当前对象的对象,即入引用(Incomming References),以及当前对象引用的对象,即出引用(Outgoing References)。

图片

还记得类对象的排序吗?


  • byte[]可以按照Shallow Heap进行排序

  • java.lang.String不能按照Shallow Heap进行排序

图片

图片

这是为什么呢?浅堆(Shallow Heap)和深堆(Retained Heap)是两个非常重要的概念,它们分别表示一个对象结构所占用的内存大小和一个对象被GC回收后,可以真实释放的内存大小。

浅堆是指一个对象所消耗的内存。在32位系统中,一个对象引用会占据4个字节,一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8个字节。

下面是String对象的几个属性:

String
- value:char[]
- offset:int
- count:int
- hash:int

3个int值共占12字节,对象引用占用4字节,对象头8字节,合计24字节。浅堆的大小只与对象的结构有关,与对象的实际内容无关。也就是说,无论字符串的长度有多少,内容是什么,浅堆的大小始终是24字节。因此java.lang.String类无法使用浅堆倒序排列。

还有,当时只在byte[]中找到了HTTP请求包,String里面是不是也有未找到的HTTP请求包(可能是找的方法不对,HTTP请求包大小位于中间部分,排序无法找到)。

后面我又进行了尝试,发现在Outgoing References搜索结果的Class Name列,除了能搜索类名,也可以搜索字符串的正则表达式,因此直接搜索.*(GET|POST) /.*就能找到HTTP请求了

图片

图片

但是直接在这里搜索password关键字,还是无法直接找到可用的明文账号密码


1.2.2 可以使用OQL直接查询吗?

后面我又思考了一下,想尽量实现OQL直接搜索

# 直接搜索所有包含SESSION ID的请求
select * from byte[] s where toString(s) like ".*_USER_COOKIEs.*"
# 直接搜索GET和POST请求
select * from java.lang.String s where toString(s) like ".*(GET|POST) /.*"

图片

但是当我想搜索密码的时候,就很一言难尽了,只找到了我测试时的登录请求

select * from byte[] s where toString(s) like ".*password.*"

图片

最后发现是比较符like的问题,经过测试发现OQL的比较关键字仅能搜索前1024个字符,剩下的无法搜索到。而password正好在1024个之后,所以无法搜索到(实际测试过contains也不行)。OQL表达式仅找到了=likecontains比较关键字,找了一下也没找到字符串截断函数,所以无法使用这种方法搜索(当然,如果运气比较好password关键字在前1024个字符内,就能搜索到)

但我们其实可以换一种思路,根据登录请求包的URL特征进行搜索,搜索POST类型,包含login的字符串

select * from byte[] s where toString(s) like ".*login.*" and toString(s) like ".*POST.*"

虽然仅找到一条结果(还是有很多明文的登录账号密码没有找到),但是确实可以快速得到一个可用口令

图片


二、利用mat+OQL表达式进行分析


2.1 提取数据库账号密码

SpringBoot 1.x 2.x 都可以用(列举环境变量)

select * from org.springframework.web.context.support.StandardServletEnvironment

图片

图片

spring boot 1.x 版本 heapdump 查询结果,最终结果存储在java.util.Hashtable$Entry 实例的键值对中,所以也可以这样查询

select * from java.util.Hashtable$Entry x WHERE (toString(x.key).contains("password"))

图片

spring boot 2.x 版本 heapdump 查询结果,最终结果存储在 java.util.LinkedHashMap$Entry 实例的键值对中,所以也可以这么查找

select * from java.util.LinkedHashMap$Entry x WHERE (toString(x.key).contains("password"))

图片


2.2 提取认证信息


2.2.1 jwt认证提取

如果使用JWT进行认证,可以使用如下命令进行搜索。原理:jwt认证字符串永远都是以eyJ进行开头,所以搜索以eyJ开头或包含的字符串即可

# 在java.lang.String类中搜索以eyJ开头的字符串
select * from java.lang.String s where s.toString().startsWith("eyJ")
# 除了String之外,也可以在byte[]、char[]中搜索包含eyJ的字符串
select * from byte[] s where s.toString().contains("eyJ")

图片

除此之外,也可以搜索JWT的密钥关键字进行搜索,找到密钥就等同于任意用户登录

# 区分大小写,jwt、JWT、Jwt都有可能;还有secret、key等关键字
select * from java.lang.String s where s.toString().contains("jwt")

图片

# 如果jwt设置在环境变量中,也可以使用寻找数据库密码的方式进行搜索
select * from org.springframework.web.context.support.StandardServletEnvironment
# spring boot 1.x
select * from java.util.Hashtable$Entry x WHERE (toString(x.key).contains("jwt"))
# spring boot 2.x
select * from java.util.LinkedHashMap$Entry x WHERE (toString(x.key).contains("jwt"))

图片

如果并未使用JWT相关库的话,可以先搜索到jwt相关关键字对应的类

select * from java.util.LinkedHashMap$Entry x WHERE (toString(x.key).contains("Jwt"))

图片

然后根据类名去搜索,找到对应的key

图片


2.2.2 一般session id提取

注意,搜索中的SESSION区分大小写

# 可在java.lang.String、byte[]、char[]中进行搜索
select * from java.lang.String s where toString(s) like ".*SESSION.*"

图片

当然如果COOKIE中是自定义的session名,也需要去对应的进行搜索


2.2.3 提取明文账号密码

# 关键字匹配受限于1024字节,有可能找不到
select * from byte[] s where toString(s) like ".*password.*"
select * from char[] s where toString(s) like ".*password.*"
select * from java.lang.String s where toString(s) like ".*password.*"
# 关键词可以模糊搜索,注意是区分大小写的,大致有如下内容
password
user
name
code
vertify
vertification
phone
login
register


2.3 提取shiro key

点击Histogram按钮

图片

在ClassName处搜索COOKIERememberMeManager,在搜索结果处右击->List objects->with outgoing references。

图片

然后点击decryptionCipherKey一行,左侧就会显示shiro key的值

图片

然后使用python小脚本转换一下即可

import base64,struct
base64.b64encode(struct.pack('

除此之外,也可以用OQL进行查询

select * from org.apache.shiro.web.mgt.COOKIERememberMeManager

图片


2.4 OQL其他搜索(用处不大)

提取内存中的文件路径

SELECT file.path.value.toString() FROM java.io.File file

图片

查看某个对象的具体内容

SELECT o FROM INSTANCEOF 0xa033b028 o

图片

按字符串长度进行搜索

SELECT * FROM byte[] s WHERE (s.toString().length() > 100)
SELECT * FROM java.lang.String s WHERE (s.toString().length() > 100)
select * from char[] s where s.@length > 100

图片

使用as retained set关键字可以得到所得对象的保留集

select as retained set * from java.lang.String s where s.value != null

图片

distinct来去除重复对象

SELECT DISTINCT s.value.toString() FROM java.lang.String s WHERE (s.toString() = "password")

原本可以查到15条password字符串

图片

去重之后只有一条

图片


三、利用工具进行分析

这里就简单的放几个heapdump分析工具,具体的使用就不说了,用起来挺简单的

https://github.com/wyzxxz/heapdump_tool

https://github.com/whwlsfb/JDumpSpider

https://github.com/wdahlenburg/pyhprof


四、参考链接

https://www.cnblogs.com/snowie/p/15561081.html

https://www.secpulse.com/archives/184037.html

https://www.cnblogs.com/icez/p/Actuator_heapdump_exploit.html

https://forum.butian.net/share/1032

https://blog.csdn.net/weixin_40418457/article/details/116323736

https://www.exploit-db.com/docs/50459

http://cr.openjdk.java.net/~sundar/8022483/webrev.01/raw_files/new/src/share/classes/com/sun/tools/hat/resources/oqlhelp.html#sizeof

https://docs.mendix.com/refguide/

https://blog.csdn.net/chengqiuming/article/details/120002225

https://www.cnblogs.com/kira2will/p/11312822.html

end

图片

灼剑(Tsojan)

安全团队

图片

图片







推荐阅读
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 开发日志:高效图片压缩与上传技术解析 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 手指触控|Android电容屏幕驱动调试指南
    手指触控|Android电容屏幕驱动调试指南 ... [详细]
  • 基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析
    基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析 ... [详细]
  • 在处理大图片时,PHP 常常会遇到内存溢出的问题。为了避免这种情况,建议避免使用 `setImageBitmap`、`setImageResource` 或 `BitmapFactory.decodeResource` 等方法直接加载大图。这些函数在处理大图片时会消耗大量内存,导致应用崩溃。推荐采用分块处理、图像压缩和缓存机制等策略,以优化内存使用并提高处理效率。此外,可以考虑使用第三方库如 ImageMagick 或 GD 库来处理大图片,这些库提供了更高效的内存管理和图像处理功能。 ... [详细]
  • JVM参数设置与命令行工具详解
    JVM参数配置与命令行工具的深入解析旨在优化系统性能,通过合理设置JVM参数,确保在高吞吐量的前提下,有效减少垃圾回收(GC)的频率,进而降低系统停顿时间,提升服务的稳定性和响应速度。此外,本文还将详细介绍常用的JVM命令行工具,帮助开发者更好地监控和调优JVM运行状态。 ... [详细]
  • 深入解析零拷贝技术(Zerocopy)及其应用优势
    零拷贝技术(Zero-copy)是Netty框架中的一个关键特性,其核心在于减少数据在操作系统内核与用户空间之间的传输次数。通过避免不必要的内存复制操作,零拷贝显著提高了数据传输的效率和性能。本文将深入探讨零拷贝的工作原理及其在实际应用中的优势,包括降低CPU负载、减少内存带宽消耗以及提高系统吞吐量等方面。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
author-avatar
mobiledu2502896071
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有