curl can be fooled into writing a zero byte out of bounds.
This bug can trigger when curl is told to work on an FTP URL, with the setting
to only issue a single CWD command (--ftp-method singlecwd
or the libcurl
alternative CURLOPT_FTP_FILEMETHOD
).
curl then URL-decodes the given path, calls strlen() on the result and deducts the length of the filename part to find the end of the directory within the buffer. It then writes a zero byte on that index, in a buffer allocated on the heap.
If the directory part of the URL contains a "%00" sequence, the directory
length might end up shorter than the filename path, making the calculation
size_t index = directory_len - filepart_len
end up with a huge index
variable for where the zero byte gets stored: heap_buffer[index] = 0
. On
several architectures that huge index wraps and works as a negative value,
thus overwriting memory before the intended heap buffer.
By using different file part lengths and putting %00 in different places in the URL, an attacker that can control what paths a curl-using application uses can write that zero byte on different indexes.
{ "package": "curl", "severity": "High", "CWE": { "desc": "Heap-based Buffer Overflow", "id": "CWE-122" }, "last_affected": "7.58.0", "URL": "https://curl.se/docs/CVE-2018-1000120.json", "affects": "both", "www": "https://curl.se/docs/CVE-2018-1000120.html" }
{ "vanir_signatures": [ { "id": "CURL-CVE-2018-1000120-1a41fdc7", "deprecated": false, "signature_version": "v1", "digest": { "line_hashes": [ "186785845436151373612249911977958489167", "139368412014933340594086933420174292978", "70225530077095739146651377461514758151", "315143483916214608334710777218089290124", "330558257654468377878934021755801694908", "254969999324771221931386190909434168886", "314505041855647615494139870984025356690", "193603554521551770788174899501257487744", "218104536554178230123180371501278426620", "249311429039464347119097856005670027110", "1949081060692883523800352474588507207", "213361387690354360733145989391887781117", "208717138941869647486339912054043560965", "269526386197135474816625635309184114445", "66234633984291063582401520848155751934", "309919340248357245579399319652351958555" ], "threshold": 0.9 }, "source": "https://github.com/curl/curl.git/commit/535432c0adb62fe167ec09621500470b6fa4eb0f", "signature_type": "Line", "target": { "file": "lib/ftp.c" } }, { "id": "CURL-CVE-2018-1000120-3930517d", "deprecated": false, "signature_version": "v1", "digest": { "function_hash": "165261537492784234712649842191490061433", "length": 925.0 }, "source": "https://github.com/curl/curl.git/commit/535432c0adb62fe167ec09621500470b6fa4eb0f", "signature_type": "Function", "target": { "file": "lib/ftp.c", "function": "ftp_state_list" } }, { "id": "CURL-CVE-2018-1000120-3dc55c90", "deprecated": false, "signature_version": "v1", "digest": { "function_hash": "53816560832323379067076410399629338950", "length": 3107.0 }, "source": "https://github.com/curl/curl.git/commit/535432c0adb62fe167ec09621500470b6fa4eb0f", "signature_type": "Function", "target": { "file": "lib/ftp.c", "function": "ftp_parse_url_path" } }, { "id": "CURL-CVE-2018-1000120-e7d820bb", "deprecated": false, "signature_version": "v1", "digest": { "function_hash": "250530457694557457073913850752791544424", "length": 4608.0 }, "source": "https://github.com/curl/curl.git/commit/535432c0adb62fe167ec09621500470b6fa4eb0f", "signature_type": "Function", "target": { "file": "lib/ftp.c", "function": "ftp_done" } } ] }