RSync: Heap Buffer Overflow, Info Leak, Server Leaks, Path Traversal and Safe links Bypass
Summary
In this report, we describe multiple vulnerabilities we discovered in Rsync.
The first pair of vulnerabilities are a [Heap Buffer Overflow](https://nvd.nist.gov/vuln/detail/cve-2024-12084) and an [Info Leak](https://nvd.nist.gov/vuln/detail/cve-2024-12085). When combined, they allow a client to execute arbitrary code on the machine a Rsync server is running on. The client only requires anonymous read-access to the server.
We developed a reliable Proof-of-Concept exploit for the following Binary release:
Distro: Debian 12
Rsync version: 3.2.7
Binary MD5: 003765c378f66a4ac14a4f7ee43f7132
Invocation:Rsync --daemon
The two vulnerabilities reside in code that is reachable in any configuration and should thus be exploitable in any binary that includes the vulnerable code.
Additionally, we disclose 3 further vulnerabilities:
A Path Traversal issue in the client that allows a malicious server to exfiltrate the contents of any file on the client’s machine
A bypass for the --safe-links CLI flag that can allow a malicious server to place unsafe symbolic links in a clients directory
A Path Traversal issue in the client that allows a malicious server to overwrite arbitrary files on the client's machine when either the -l and the -l isn't formatted ( but the subsequent -a and --archive are).
Severity
High - Multiple vulnerabilities impacting Rsync ranging...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| Rsync Product | < 3.4.0 | 3.4.0 |
Details and references
### Summary In this report, we describe multiple vulnerabilities we discovered in Rsync. The first pair of vulnerabilities are a [Heap Buffer Overflow](https://nvd.nist.gov/vuln/detail/cve-2024-12084) and an [Info Leak](https://nvd.nist.gov/vuln/detail/cve-2024-12085). When combined, they allow a client to execute arbitrary code on the machine a Rsync server is running on. The client only requires anonymous read-access to the server. We developed a reliable Proof-of-Concept exploit for the following Binary release: Distro: Debian 12 Rsync version: 3.2.7 Binary MD5: 003765c378f66a4ac14a4f7ee43f7132 Invocation:`Rsync --daemon` The two vulnerabilities reside in code that is reachable in any configuration and should thus be exploitable in any binary that includes the vulnerable code. Additionally, we disclose 3 further vulnerabilities: A Path Traversal issue in the client that allows a malicious server to exfiltrate the contents of any file on the client’s machine A bypass for the `--safe-links` CLI flag that can allow a malicious server to place unsafe symbolic links in a clients directory A Path Traversal issue in the client that allows a malicious server to overwrite arbitrary files on the client's machine when either the `-l` and the `-l` isn't formatted ( but the subsequent `-a` and `--archive` are). ### Severity High - Multiple vulnerabilities impacting Rsync ranging from moderate (6.5) to Critical (9.8) CVSS scores which could allow a client to execute arbitrary code. ### Proof of Concept #### CVE-2024-12084 - Heap Buffer Overflow in Checksum Parsing When the checksums are read by the daemon, two different checksums read: 1. A 32-bit Adler-CRC32 Checksum 2. A digest of the file chunk. The digest algorithm is determined at the beginning of the protocol negotiation. The corresponding code can be seen below: [sender.c](https://github.com/RsyncProject/rsync/blob/9615a2492bbf96bc145e738ebff55bbb91e0bbee/sender.c#L96-L100) ```c++ s->sums = new_array(struct sum_buf, s->count); for (i = 0; i < s->count; i++) { s->sums[i].sum1 = read_int(f); read_buf(f, s->sums[i].sum2, s->s2length); ``` Most importantly, note that `sum2` field is filled with `s->s2length bytes`. `sum2` always has a size of 16: [Rsync.h](https://github.com/RsyncProject/rsync/blob/9615a2492bbf96bc145e738ebff55bbb91e0bbee/rsync.h#L955-L962) ```c++ #define SUM_LENGTH 16 // . . . struct sum_buf { OFF_T offset; /**< offset in file of this chunk */ int32 len; /**< length of chunk of file */ uint32 sum1; /**< simple checksum */ int32 chain; /**< next hash-table collision */ short flags; /**< flag bits */ char sum2[SUM_LENGTH]; /**< checksum */ }; ``` `s2length` is an attacker-controlled value and can have a value up to `MAX_DIGEST_LEN` bytes, as the next snipper shows: [io.c](https://github.com/RsyncProject/rsync/blob/9615a2492bbf96bc145e738ebff55bbb91e0bbee/io.c#L1979-L1984) ```c++ sum->s2length = protocol_version < 27 ? csum_length : (int)read_int(f); if (sum->s2length < 0 || sum->s2length > MAX_DIGEST_LEN) { rprintf(FERROR, "Invalid checksum length %d [%s]\n", sum->s2length, who_am_i()); exit_cleanup(RERR_PROTOCOL); } ``` The problem here is that `MAX_DIGEST_LEN` can be larger than 16 bytes, depending on the digest support the binary was compiled with: [md-defines.h](https://github.com/RsyncProject/rsync/blob/9615a2492bbf96bc145e738ebff55bbb91e0bbee/lib/md-defines.h#L11-L21) ```c++ #define MD4_DIGEST_LEN 16 #define MD5_DIGEST_LEN 16 #if defined SHA512_DIGEST_LENGTH #define MAX_DIGEST_LEN SHA512_DIGEST_LENGTH #elif defined SHA256_DIGEST_LENGTH #define MAX_DIGEST_LEN SHA256_DIGEST_LENGTH #elif defined SHA_DIGEST_LENGTH #define MAX_DIGEST_L
- Severity from
- GitHub (reviewed advisory)