CrushFTP Unauthenticated Remote Code Execution(CVE-2023-43177)
2023-12-10 21:4:9 Author: y4tacker.github.io(查看原文) 阅读量:9 收藏

crushftp.server.ServerSessionAJAX#buildPostItem当中,可以看到会解析每一个header,并将解析到的key,val保存到as2Info这个Properties中,同时这里对put的参数没有任何限制

继续往下接下来我们可以看到,在光标处没有做任何的限制,直接将as2Info中的每个键值对添加到了当前会话的user_info属性,因此这里存在一个属性覆盖的问题,接下来我们就需要看看覆盖哪些属性可能存在威胁

如果相等则返回登录成功,同时值得注意的是这里会返回user_name,因此我们可以利用这一点来判断漏洞是否可利用,如果是漏洞版本user_name就可以通过header覆盖,返回也可以是任意可控字符

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public boolean writeResponse(String response) throws Exception {
return this.writeResponse(response, true, 200, true, false, true);
}

public boolean writeResponse(String response, boolean json) throws Exception {
return this.writeResponse(response, true, 200, true, json, true);
}

public boolean writeResponse(String response, boolean log, int code, boolean convertVars, boolean json, boolean log_header) throws Exception {
boolean acceptsGZIP = false;
return this.writeResponse(response, log, code, convertVars, json, acceptsGZIP, log_header);
}

public boolean writeResponse(String response, boolean log, int code, boolean convertVars, boolean json, boolean acceptsGZIP, boolean log_header) throws Exception {
if (convertVars) {
response = ServerStatus.thisObj.change_vars_to_values(response, this.thisSessionHTTP.thisSession);
}
this.write_command_http("HTTP/1.1 " + code + " OK", log_header);
this.write_command_http("Cache-Control: no-store", log_header);
this.write_command_http("Pragma: no-cache", log_header);
if (json) {
this.write_command_http("Content-Type: application/jsonrequest;charset=utf-8");
} else {
this.write_command_http("Content-Type: text/" + (response.indexOf("<?xml") >= 0 ? "xml" : "plain") + ";charset=utf-8");
}
if (acceptsGZIP) {
this.thisSessionHTTP.write_command_http("Vary: Accept-Encoding");
this.thisSessionHTTP.write_command_http("Content-Encoding: gzip");
this.thisSessionHTTP.write_command_http("Transfer-Encoding: chunked");
this.thisSessionHTTP.write_command_http("Date: " + this.thisSessionHTTP.sdf_rfc1123.format(new Date()), log, true);
this.thisSessionHTTP.write_command_http("Server: " + ServerStatus.SG("http_server_header"), log, true);
this.thisSessionHTTP.write_command_http("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"", log, true);
if (!ServerStatus.SG("Access-Control-Allow-Origin").equals("")) {
String origin = this.thisSessionHTTP.headerLookup.getProperty("ORIGIN", "");
int x = 0;
while (x < ServerStatus.SG("Access-Control-Allow-Origin").split(",").length) {
boolean ok = false;
if (origin.equals("")) {
ok = true;
} else if (ServerStatus.SG("Access-Control-Allow-Origin").split(",")[x].toUpperCase().trim().equalsIgnoreCase(origin.toUpperCase().trim())) {
ok = true;
}
if (ok) {
this.write_command_http("Access-Control-Allow-Origin: " + ServerStatus.SG("Access-Control-Allow-Origin").split(",")[x].trim());
}
++x;
}
this.write_command_http("Access-Control-Allow-Headers: authorization,content-type");
this.write_command_http("Access-Control-Allow-Credentials: true");
this.write_command_http("Access-Control-Allow-Methods: GET,POST,OPTIONS,PUT,PROPFIND,DELETE,MKCOL,MOVE,COPY,HEAD,PROPPATCH,LOCK,UNLOCK,ACL,TR");
}
this.write_command_http("", log);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = response.getBytes("UTF8");
GZIPOutputStream out = new GZIPOutputStream(baos);
((OutputStream)out).write(b);
out.finish();
if (baos.size() > 0) {
this.thisSessionHTTP.original_os.write((String.valueOf(Long.toHexString(baos.size())) + "\r\n").getBytes());
baos.writeTo(this.thisSessionHTTP.original_os);
this.thisSessionHTTP.original_os.write("\r\n".getBytes());
baos.reset();
}
this.thisSessionHTTP.original_os.write("0\r\n\r\n".getBytes());
this.thisSessionHTTP.original_os.flush();
} else {
this.thisSessionHTTP.write_standard_headers(log);
int len = response.getBytes("UTF8").length + 2;
if (len == 2) {
len = 0;
}
this.write_command_http("Content-Length: " + len, log_header);
this.write_command_http("", log);
if (len > 0) {
this.thisSessionHTTP.write_command_http(response, log, convertVars);
}
}
this.thisSessionHTTP.thisSession.drain_log();
return true;
}

但继续阅读源码我们会发现,程序在运行过程还会”定期”,将session当中的属性信息保存到sessions.obj文件当中(保存的条件是重启过服务器…),这个文件的作用相当于是充当了服务器重启时的缓存,因此漏洞利用需要看运气了


文章来源: https://y4tacker.github.io/2023/12/10/year/2023/12/CrushFTP-Unauthenticated-Remote-Code-Execution-CVE-2023-43177/
如有侵权请联系:admin#unsafe.sh