In late 2021, a vulnerability in ProFTPD’s mod_radius module was disclosed under the identifier CVE-2021-46854. This issue allows unintentional memory disclosure to RADIUS servers due to improper buffer handling when copying user information. If you're running ProFTPD before version 1.3.7c and have mod_radius enabled, you may be at risk.
In this article, we'll break down what this vulnerability is, explain how it works in simple language, provide code snippets for your understanding, link to the original advisory, and even describe how an attacker could exploit it.
ProFTPD is a popular, open-source FTP server.
- mod_radius is a module that allows ProFTPD to authenticate users against a RADIUS server. RADIUS is a protocol commonly used for centralized authentication.
The Core Issue: Block Copying Leaks Memory
CVE-2021-46854 is all about insecure memory handling. When ProFTPD’s mod_radius module copies user information to be sent to the RADIUS server, it uses a fixed-size buffer (16 characters). If the source string is shorter than 16 characters, the remaining buffer may contain uninitialized junk—potentially sensitive memory from the server.
This ‘junk’ can include portions of other users’ data, login credentials, or even just random memory that shouldn’t be exposed. If an attacker is controlling or able to observe the RADIUS server, they could potentially collect leaked data over time.
Code Snippet — Where Things Go Wrong
From the ProFTPD source code, let’s see the faulty code pattern:
char radius_buffer[16];
// Let's say username is less than 16 bytes
strncpy(radius_buffer, username, 16);
// radius_buffer is now sent to RADIUS server in request
- strncpy does not fill the remainder of radius_buffer with null (\) bytes if username is exactly 16 characters, potentially leaving the tail of radius_buffer filled with whatever was in memory before.
Exploit Scenario
Who can exploit?
Any RADIUS server you use for authentication could receive these "extra" bytes. In some cases, a malicious actor could control a RADIUS server, or perhaps an internal misconfiguration could allow untrusted servers to see these unintended disclosures.
Attacker tries to log in with different usernames (e.g. "bob", "alice").
4. For each authentication attempt, ProFTPD sends a 16-byte buffer containing the username, but possibly leaking old memory.
On the attacker’s server, you'd see
Received user: "bob?????secret_data"
Received user: "alice?previous_creds"
*(The ? here represents random memory bytes that might contain sensitive data)*
Below is a basic simulated exploit in Python, capturing the incoming User-Name attribute
import socket
# Very simplified RADIUS server listener
def listen_radius(port=1812):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('...', port))
print("Listening for RADIUS requests...")
while True:
data, addr = sock.recvfrom(4096)
# Look for 'User-Name' attribute in packet:
if b'bob' in data or b'alice' in data:
print(f"Received packet: {data}")
if __name__ == '__main__':
listen_radius()
> Note: In reality, parsing RADIUS packets is more complex, but this shows how an insecure RADIUS server could passively log the extra memory.
Was a Fix Issued?
Yes. The issue was silently patched in ProFTPD 1.3.7c by switching to safer buffer handling, ensuring the buffer is properly zeroed out after copying.
ProFTPD Changelog for 1.3.7c
Original NVD advisory
Patch example
char radius_buffer[16];
memset(radius_buffer, , sizeof(radius_buffer));
strncpy(radius_buffer, username, 16);
Final Thoughts
CVE-2021-46854 is a subtle but impactful memory disclosure bug—a great example of how even small mistakes in buffer management can lead to leaks of sensitive data. Because the vulnerability only shows up under certain configurations (mod_radius and pre-1.3.7c), many users escaped the worst. But for those using RADIUS, upgrade immediately!
References
- NVD CVE-2021-46854
- mod_radius source in ProFTPD GitHub
- ProFTPD Changelog 1.3.7c
Have questions? Drop them below or check out ProFTPD’s mailing list.
Timeline
Published on: 11/23/2022 07:15:00 UTC
Last modified on: 05/03/2023 11:15:00 UTC