su18 / blogtalk

0 stars 0 forks source link

Hessian 反序列化知一二 | 素十八 #48

Open su18 opened 2 years ago

su18 commented 2 years ago

https://su18.org/post/hessian/#%E4%B9%9D-%E5%8F%82%E8%80%83

你救赎的人 终将成为你的光

zzzskd commented 2 years ago

师傅请问下Resin链、XBean 链中,关于 XString 的处理有介绍嘛,看着截图里面有说对碳基生物有些超前==

我在复现 Resin 链时发现如果 new QNamefirst 还有 rest 字符串长度都小于3时(比如 QName qName = new QName(continuationDirContext, "a", "b"); ),虽然经过 marshalsec.gadgets.ToStringUtil#unhash 处理,依然会导致在 java.util.HashMap#putVal 里面 XstringQName 的hash不一样, 不能执行 XString.equals方法

还请师傅指教

su18 commented 2 years ago

师傅请问下Resin链、XBean 链中,关于 XString 的处理有介绍嘛,看着截图里面有说对碳基生物有些超前==

我在复现 Resin 链时发现如果 new QNamefirst 还有 rest 字符串长度都小于3时(比如 QName qName = new QName(continuationDirContext, "a", "b"); ),虽然经过 marshalsec.gadgets.ToStringUtil#unhash 处理,依然会导致在 java.util.HashMap#putVal 里面 XstringQName 的hash不一样, 不能执行 XString.equals方法

还请师傅指教

第一个问题,文章里一笔带过,XString 的 equals() 方法会调用其封装类的 toSting() 方法, 作为中间链存在,前面可以用 HashMap 触发,后面可以触发 Qname/ReadOnlyBinding 等 toString() 方法中的逻辑。

第二个问题,我对 HashMap put 影响处理的“碳基超前”写法其实不具有通用性,只能在部分版本 JDK 使用,具体分析可以参考链接:https://su18.org/post/ysoserial-su18-1/#urldns,此举是为了解决触发反序列化利用之前使用 put 方法将类放入 HashMap 带来的一系列影响,例如 hashCode 缓存等,在某些链中,甚至还会提前触发利用链,这部分 ysoserial 和 marshalsec 自身的实现方式要比我学习的时候写的测试代码要更好,所以可以忽略。

第三个问题,实际涉及到的可以称之为 “HashCode碰撞”,java.util.HashMap#putVal 方法在 key 的 hashCode 一致的时候会触发 equals 方法调用,XString 的 hashCode 比较有意思,会将其封装的类强转为 String 类型再调用 hashCode 方法,而利用 String 类型的 hashCode ,就可以碰撞出任意 HashCode,可以参考这篇文章 https://paper.seebug.org/199/#hashcode,实际上代码与 marshalsec.gadgets.ToStringUtil#unhash 这个方法的代码也是一致的,但是这个具体的碰撞流程我没跟过,至于你提出的问题,我猜测可能是在字符串较短时,相关的逻辑失效,导致计算的结果不一致,你可以单独将这部分拿出来测试下试试

zzzskd commented 2 years ago

@su18

师傅请问下Resin链、XBean 链中,关于 XString 的处理有介绍嘛,看着截图里面有说对碳基生物有些超前==

我在复现 Resin 链时发现如果 new QNamefirst 还有 rest 字符串长度都小于3时(比如 QName qName = new QName(continuationDirContext, "a", "b"); ),虽然经过 marshalsec.gadgets.ToStringUtil#unhash 处理,依然会导致在 java.util.HashMap#putVal 里面 XstringQName 的hash不一样, 不能执行 XString.equals方法

还请师傅指教

第一个问题,文章里一笔带过,XString 的 equals() 方法会调用其封装类的 toSting() 方法, 作为中间链存在,前面可以用 HashMap 触发,后面可以触发 Qname/ReadOnlyBinding 等 toString() 方法中的逻辑。

第二个问题,我对 HashMap put 影响处理的“碳基超前”写法其实不具有通用性,只能在部分版本 JDK 使用,具体分析可以参考链接:https://su18.org/post/ysoserial-su18-1/#urldns,此举是为了解决触发反序列化利用之前使用 put 方法将类放入 HashMap 带来的一系列影响,例如 hashCode 缓存等,在某些链中,甚至还会提前触发利用链,这部分 ysoserial 和 marshalsec 自身的实现方式要比我学习的时候写的测试代码要更好,所以可以忽略。

第三个问题,实际涉及到的可以称之为 “HashCode碰撞”,java.util.HashMap#putVal 方法在 key 的 hashCode 一致的时候会触发 equals 方法调用,XString 的 hashCode 比较有意思,会将其封装的类强转为 String 类型再调用 hashCode 方法,而利用 String 类型的 hashCode ,就可以碰撞出任意 HashCode,可以参考这篇文章 https://paper.seebug.org/199/#hashcode,实际上代码与 marshalsec.gadgets.ToStringUtil#unhash 这个方法的代码也是一致的,但是这个具体的碰撞流程我没跟过,至于你提出的问题,我猜测可能是在字符串较短时,相关的逻辑失效,导致计算的结果不一致,你可以单独将这部分拿出来测试下试试

感谢师傅解答,我试下😆

EndlessShw commented 1 week ago

这里由于篇幅原因(懒癌),这里就不一一分析各个利用链了,只是大概说一下利用链和一些关键触发点,详细的利用测试代码和注释已经更新到 ysoserial 学习项目中。

请问师傅,该学习项目似乎已经没了,请问还有吗?QAQ