Daniel Stenberg
2018-07-11 06:06:01 UTC
SMTP send heap buffer overflow
==============================
Project curl Security Advisory, July 11th 2018 -
[Permalink](https://curl.haxx.se/docs/adv_2018-70a2.html)
VULNERABILITY
-------------
curl might overflow a heap based memory buffer when sending data over SMTP and
using a reduced read buffer.
When sending data over SMTP, curl allocates a separate "scratch area" on the
heap to be able to escape the uploaded data properly if the uploaded data
contains data that requires it.
The size of this temporary scratch area was mistakenly made to be `2 *
sizeof(download_buffer)` when it should have been made `2 *
sizeof(upload_buffer)`.
The upload and the download buffer sizes are identically sized by default
(16KB) but since version 7.54.1, curl can resize the download buffer into a
smaller buffer (as well as larger). If the download buffer size is set to a
value smaller than 10923, the `Curl_smtp_escape_eob()` function might overflow
the scratch buffer when sending contents of sufficient size and contents.
The curl command line tool lowers the buffer size when `--limit-rate` is set
to a value smaller than 16KB.
We are not aware of any exploit of this flaw.
TEST CASES
----------
Here's a shell script
# Setup an SMTP end-point, make file, run curl
$ printf '220 Hi\n250 SIZE 10000\n250 OK\n250 OK\n354 send data\n' | nc -l -p 2525 >/dev/null &
$ printf '%5000s' > mail.txt
$ curl -v smtp://localhost:2525 --mail-from me --mail-rcpt ***@localhost --upload-file mail.txt --limit-rate 1024
PHP code:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "smtp://localhost:2525");
curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_MAIL_FROM, "me");
curl_setopt($ch, CURLOPT_MAIL_RCPT, ["***@localhost"]);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$eof = false;
curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $stream, $maxSize) {
global $eof;
echo "Max Size: [$maxSize]\n";
if ($eof) {
return "";
}
$eof = true;
return str_repeat(" ", $maxSize);
});
curl_exec($ch);
curl_close($ch);
INFO
----
This bug was introduced in April 2017 in [this
commit](https://github.com/curl/curl/commit/e40e9d7f0decc79) when we
introduced support for buffer resize. The scratch buffer was mistakenly made
to use the dynamic size when it should kept using the fixed upload buffer
size.
The Common Vulnerabilities and Exposures (CVE) project has assigned the name
CVE-2018-0500 to this issue.
CWE-122: Heap-based Buffer Overflow
AFFECTED VERSIONS
-----------------
- Affected versions: curl 7.54.1 to and including curl 7.60.0
- Not affected versions: curl < 7.54.1 and curl >= 7.61.0
libcurl is used by many applications, but not always advertised as such.
THE SOLUTION
------------
In curl version 7.61.0, curl will use the upload buffer size as base for the
scratch area allocation.
A [patch for CVE-2018-0500](https://github.com/curl/curl/commit/ba1dbd78e5f1e.patch) is
available.
RECOMMENDATIONS
---------------
We suggest you take one of the following actions immediately, in order of
preference:
A - Upgrade curl to version 7.61.0
B - Apply the patch to your version and rebuild
C - Avoid using SMTP uploads with CURLOPT_BUFFERSIZE set below 10923
TIME LINE
---------
It was reported to the curl project on June 11, 2018
We contacted ***@openwall on July X, 2018.
curl 7.61.0 was released on July 11 2018, coordinated with the publication of
this advisory.
CREDITS
-------
Detected and researched by Peter Wu. Patch by Daniel Stenberg.
Thanks a lot!
==============================
Project curl Security Advisory, July 11th 2018 -
[Permalink](https://curl.haxx.se/docs/adv_2018-70a2.html)
VULNERABILITY
-------------
curl might overflow a heap based memory buffer when sending data over SMTP and
using a reduced read buffer.
When sending data over SMTP, curl allocates a separate "scratch area" on the
heap to be able to escape the uploaded data properly if the uploaded data
contains data that requires it.
The size of this temporary scratch area was mistakenly made to be `2 *
sizeof(download_buffer)` when it should have been made `2 *
sizeof(upload_buffer)`.
The upload and the download buffer sizes are identically sized by default
(16KB) but since version 7.54.1, curl can resize the download buffer into a
smaller buffer (as well as larger). If the download buffer size is set to a
value smaller than 10923, the `Curl_smtp_escape_eob()` function might overflow
the scratch buffer when sending contents of sufficient size and contents.
The curl command line tool lowers the buffer size when `--limit-rate` is set
to a value smaller than 16KB.
We are not aware of any exploit of this flaw.
TEST CASES
----------
Here's a shell script
# Setup an SMTP end-point, make file, run curl
$ printf '220 Hi\n250 SIZE 10000\n250 OK\n250 OK\n354 send data\n' | nc -l -p 2525 >/dev/null &
$ printf '%5000s' > mail.txt
$ curl -v smtp://localhost:2525 --mail-from me --mail-rcpt ***@localhost --upload-file mail.txt --limit-rate 1024
PHP code:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "smtp://localhost:2525");
curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_MAIL_FROM, "me");
curl_setopt($ch, CURLOPT_MAIL_RCPT, ["***@localhost"]);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$eof = false;
curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $stream, $maxSize) {
global $eof;
echo "Max Size: [$maxSize]\n";
if ($eof) {
return "";
}
$eof = true;
return str_repeat(" ", $maxSize);
});
curl_exec($ch);
curl_close($ch);
INFO
----
This bug was introduced in April 2017 in [this
commit](https://github.com/curl/curl/commit/e40e9d7f0decc79) when we
introduced support for buffer resize. The scratch buffer was mistakenly made
to use the dynamic size when it should kept using the fixed upload buffer
size.
The Common Vulnerabilities and Exposures (CVE) project has assigned the name
CVE-2018-0500 to this issue.
CWE-122: Heap-based Buffer Overflow
AFFECTED VERSIONS
-----------------
- Affected versions: curl 7.54.1 to and including curl 7.60.0
- Not affected versions: curl < 7.54.1 and curl >= 7.61.0
libcurl is used by many applications, but not always advertised as such.
THE SOLUTION
------------
In curl version 7.61.0, curl will use the upload buffer size as base for the
scratch area allocation.
A [patch for CVE-2018-0500](https://github.com/curl/curl/commit/ba1dbd78e5f1e.patch) is
available.
RECOMMENDATIONS
---------------
We suggest you take one of the following actions immediately, in order of
preference:
A - Upgrade curl to version 7.61.0
B - Apply the patch to your version and rebuild
C - Avoid using SMTP uploads with CURLOPT_BUFFERSIZE set below 10923
TIME LINE
---------
It was reported to the curl project on June 11, 2018
We contacted ***@openwall on July X, 2018.
curl 7.61.0 was released on July 11 2018, coordinated with the publication of
this advisory.
CREDITS
-------
Detected and researched by Peter Wu. Patch by Daniel Stenberg.
Thanks a lot!
--
/ daniel.haxx.se
-----------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-users
Etiquette: https://curl.
/ daniel.haxx.se
-----------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-users
Etiquette: https://curl.