ysoserial分析之Clojure利用链

admin 2022年5月15日01:25:56代码审计评论1 views2535字阅读8分27秒阅读模式

0x01 前言

这个漏洞给我的感觉和Groovy有点像,都是在 Java 上解析和执行命令,也属于Lisp编程语言,本文着重点在于分析如何触发漏洞,具体的解析流程可能不会过于深入,分析不到位的地方,大佬们多多包涵。


0x02 漏洞分析

01 命令执行浅析

我们先通过一段代码来了解一下Clojure是如何执行命令的,使用如下代码

import clojure.main$eval_opt;
public class Demo1 {
public static void main(String[] args) { domain(); }
private static void domain() { String clojurePayload = "(use '[clojure.java.shell :only [sh]]) (sh "calc")"; Object invoke = new main$eval_opt().invoke(clojurePayload); }}


在invoke方法打上断点,调试看看

ysoserial分析之Clojure利用链


可以看到将构造的payload传入了invokeStatic方法,跟入

ysoserial分析之Clojure利用链


这里会先将payload传入StringReader然后转化为LineNumberReader对象,之后将reader对象传入 main$eval_opt$fn__7422 构造方法,如图

ysoserial分析之Clojure利用链


构造方法进行了赋值,之后调用 main$eval_opt$fn__7422 的 invoke 方法

ysoserial分析之Clojure利用链


先是将reader赋值给了 var10000,然后调用 reader 对象的 invokeStatic 方法,由于有些方法进不去,就不一一展示了,之后会回到 clojure.main$eval_opt#invokeStatic 方法,调用 clojure.core$eval.invokeStatic(var10000),跟入

ysoserial分析之Clojure利用链


主要就是在 Compiler.eval 中解析 payload 然后触发命令执行的,我们可以看下核心代码,clojure.java.shell$sh#invokeStatic

ysoserial分析之Clojure利用链

ysoserial分析之Clojure利用链

可以看到最后调用的就是Runtime的exec方法执行的命令弹出计算器

ysoserial分析之Clojure利用链

ysoserial分析之Clojure利用链


02 如何通过反序列化触发漏洞

通过前面的调试我们可以知道,如果能够调用 main$eval_opt().invoke 方法,且传入的内容为我们构造的payload,即可触发命令执行,作者是在 clojure.core$comp$fn__4727#invoke(java.lang.Object) 方法找到的命令执行点,如图

ysoserial分析之Clojure利用链


其实看到这个就很明显了,只要 this.f 和 this.g 可控,那么就可以用来命令执行了

我们看一下这两个属性是如何赋值的

ysoserial分析之Clojure利用链


实例化的时候进行赋值,那么如何控制返回值为我们的payload呢,其实就是找什么类执行invoke之后能返回我们要的payload,这里作者找到的是 core$constantly 对象,我们可以看一下

ysoserial分析之Clojure利用链


将payload传入了invokeStatic方法,然后传入了构造方法 core$constantly$fn__4614 ,跟入

ysoserial分析之Clojure利用链


这里将payload传给了this.x,当调用invoke方法时会返回this.x的值,如图

ysoserial分析之Clojure利用链

ysoserial分析之Clojure利用链

有点类似cc链的那种感觉,存一个对象再返回这个对象

到这里,我们大致了解了命令执行点在什么位置,以及如何构造,接下来就是如何触发的问题了

我们通过调试来讲解,运行debug程序

ysoserial分析之Clojure利用链


先是构造了payload,然后创建了三个对象,AbstractTableModel$ff19274a 这个是关键类,其他的都是用来触发的,将model作为key放置到targetMap集合中,继续往下

ysoserial分析之Clojure利用链


这里可以看到将payload传入了 clojure.core$constantly().invoke 方法,也就是前面分析的赋值给了this.x然后invoke返回payload的值,然后实例化了 clojure.main$eval_opt 对象,将这两个对象传入 clojure.core$comp().invoke 方法,跟入看下

ysoserial分析之Clojure利用链


将 clojure.main$eval_opt 对象赋值给了var10000,clojure.core$constantly 对象赋值给了var10001,传入invokeStatic,跟入

ysoserial分析之Clojure利用链


这里也是赋值,然后传入构造方法实例化 core$comp$fn__4727 对象

ysoserial分析之Clojure利用链


this.g 是 clojure.core$constantly 对象,this.f 是 clojure.main$eval_opt对象

返回的对象作为 value 赋值给了 fnMap 对象的 hashCode 键

后面调用 model.__initClojureFnMappings(PersistentArrayMap.create(fnMap)),我们跟入看下

ysoserial分析之Clojure利用链


就是将fnMap对象转化后赋值给了 __clojurefnMap,后面我们会用到

接下来就开始反序列化,反序列化的是HashMap对象,跟入readObject

ysoserial分析之Clojure利用链

这里key是 AbstractTableModel$ff19274a 对象,传入hash方法,跟入

ysoserial分析之Clojure利用链


调用key的hashCode方法,也就是 clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a#hashCode 方法,跟入

ysoserial分析之Clojure利用链


这里先是从 this.__clojureFnMap 对象中取出hashCode键对应的值,也就是前面的 core$comp$fn__4727 对象,取出来之后调用其invoke方法,跟入

ysoserial分析之Clojure利用链


这里就是我们前面分析的触发点了,有些代码动态调试进不去,所以这里一部分是静态分析,到了这一步后面的触发过程就和前面分析的一样了,最后通过Runtime对象触发命令执行

0x03 总结

本次漏洞分析其实没有太多新的东西,也是典型的对象可控导致的反序列化命令执行,主要是找到漏洞触发点,对clojure这个组件也不是那么了解,所以可能有分析不到位的地方,当作学习笔记了。


0x04 参考文章


    java反序列化漏洞(https://su18.org/post/ysoserial-su18-5/#clojure)


原文始发于微信公众号(伟盾网络安全):ysoserial分析之Clojure利用链

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月15日01:25:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  ysoserial分析之Clojure利用链 http://cn-sec.com/archives/1004597.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: