Bug 1552628 (CVE-2018-1000120) - CVE-2018-1000120 curl: FTP path trickery leads to NIL byte out of bounds write
Summary: CVE-2018-1000120 curl: FTP path trickery leads to NIL byte out of bounds write
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2018-1000120
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1555207 1555208 1555209 1555210 1555221 1555222 1802791 1803053
Blocks: 1552634
TreeView+ depends on / blocked
 
Reported: 2018-03-07 13:07 UTC by Andrej Nemec
Modified: 2021-02-17 00:41 UTC (History)
26 users (show)

Fixed In Version: curl 7.59.0
Doc Type: If docs needed, set a value
Doc Text:
It was found that libcurl did not safely parse FTP URLs when using the CURLOPT_FTP_FILEMETHOD method. An attacker, able to provide a specially crafted FTP URL to an application using libcurl, could write a NULL byte at an arbitrary location, resulting in a crash or an unspecified behavior.
Clone Of:
Environment:
Last Closed: 2019-06-10 10:16:51 UTC
Embargoed:


Attachments (Terms of Use)
upstream patch (4.18 KB, patch)
2018-03-07 13:17 UTC, Andrej Nemec
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2018:3157 0 None None None 2018-10-30 07:43:17 UTC
Red Hat Product Errata RHSA-2018:3558 0 None None None 2018-11-13 08:35:32 UTC
Red Hat Product Errata RHSA-2019:1543 0 None None None 2019-06-18 19:09:06 UTC
Red Hat Product Errata RHSA-2020:0544 0 None None None 2020-02-18 14:43:58 UTC
Red Hat Product Errata RHSA-2020:0594 0 None None None 2020-02-25 12:11:27 UTC

Description Andrej Nemec 2018-03-07 13:07:21 UTC
It was found that 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 file name 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 file name 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 will wrap and work 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.

Comment 1 Andrej Nemec 2018-03-07 13:07:29 UTC
Acknowledgments:

Name: the Curl project
Upstream: Duy Phan Thanh

Comment 2 Andrej Nemec 2018-03-07 13:17:59 UTC
Created attachment 1405333 [details]
upstream patch

Comment 4 Cedric Buissart 2018-03-13 20:57:48 UTC
Mitigation:

Preventing application from using non-default CURLOPT_FTP_FILEMETHOD will avoid triggering the vulnerable code.

Comment 5 Adam Mariš 2018-03-14 07:30:53 UTC
External References:

https://curl.haxx.se/docs/adv_2018-9cd6.html

Comment 6 Adam Mariš 2018-03-14 07:33:39 UTC
Created mingw-curl tracking bugs for this issue:

Affects: fedora-all [bug 1555207]


Created curl tracking bugs for this issue:

Affects: fedora-all [bug 1555209]


Created mingw-curl tracking bugs for this issue:

Affects: epel-7 [bug 1555208]

Comment 9 Cedric Buissart 2018-03-14 08:35:48 UTC
Upstream commit: 
 FTP: reject path components with control codes 
https://github.com/curl/curl/commit/535432c0ad

Comment 12 errata-xmlrpc 2018-10-30 07:43:06 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2018:3157 https://access.redhat.com/errata/RHSA-2018:3157

Comment 13 errata-xmlrpc 2018-11-13 08:35:20 UTC
This issue has been addressed in the following products:

  Red Hat Software Collections for Red Hat Enterprise Linux 6
  Red Hat Software Collections for Red Hat Enterprise Linux 7
  Red Hat Software Collections for Red Hat Enterprise Linux 7.4 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7.5 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7.6 EUS

Via RHSA-2018:3558 https://access.redhat.com/errata/RHSA-2018:3558

Comment 14 Pandian 2019-05-13 11:58:57 UTC
I have used 7.35 version ...

In my version following code compared to diff more mismatches ...


  lstArg = NULL;
  if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
     data->state.path &&
     data->state.path[0] &&
     strchr(data->state.path,'/')) {

    lstArg = strdup(data->state.path);
    if(!lstArg)
      return CURLE_OUT_OF_MEMORY;

    /* Check if path does not end with /, as then we cut off the file part */
    if(lstArg[strlen(lstArg) - 1] != '/')  {

      /* chop off the file part if format is dir/dir/file */
      slashPos = strrchr(lstArg,'/');
      if(slashPos)
        *(slashPos+1) = '\0';
    }
  }

  cmd = aprintf( "%s%s%s",
                 data->set.str[STRING_CUSTOMREQUEST]?
                 data->set.str[STRING_CUSTOMREQUEST]:
                 (data->set.ftp_list_only?"NLST":"LIST"),
                 lstArg? " ": "",
                 lstArg? lstArg: "" );



Note:  Curl_urldecode() not added in this ftp_state_list() in 7.35 ....will you please clarify me

Comment 15 Kamil Dudka 2019-05-13 12:09:51 UTC
I am not sure what you are trying to say but this is the patch that was applied on RHEL-7 to fix this CVE:

https://git.centos.org/rpms/curl/blob/f0f8d7eb/f/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch

Comment 16 Pandian 2019-05-13 12:43:47 UTC
Kamil, we have used curl 7.35.0 version  and founded some vulnerabilities including "CVE-2018-1000120" 

Here patches or diff available "https://bugzilla.redhat.com/attachment.cgi?id=1405333&action=diff"  ------>  for CVE-2018-1000120


My curl 7.35.0 lib/ftp.c  

Curl_urldecode() calling function not there in  ftp_state_list(struct connectdata *conn)



But here the diff "https://bugzilla.redhat.com/attachment.cgi?id=1405333&action=diff" 

     Curl_urldecode() changes the arguement value as "False"  



My code 7.35.0 lib/ftp.c
===========================

static CURLcode ftp_state_list(struct connectdata *conn)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;

  /* If this output is to be machine-parsed, the NLST command might be better
     to use, since the LIST command output is not specified or standard in any
     way. It has turned out that the NLST list output is not the same on all
     servers either... */

  /*
     if FTPFILE_NOCWD was specified, we are currently in
     the user's home directory, so we should add the path
     as argument for the LIST / NLST / or custom command.
     Whether the server will support this, is uncertain.

     The other ftp_filemethods will CWD into dir/dir/ first and
     then just do LIST (in that case: nothing to do here)
  */
  char *cmd,*lstArg,*slashPos;

  lstArg = NULL;
  if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
     data->state.path &&
     data->state.path[0] &&
     strchr(data->state.path,'/')) {

    lstArg = strdup(data->state.path);
    if(!lstArg)
      return CURLE_OUT_OF_MEMORY;

    /* Check if path does not end with /, as then we cut off the file part */
    if(lstArg[strlen(lstArg) - 1] != '/')  {

      /* chop off the file part if format is dir/dir/file */
      slashPos = strrchr(lstArg,'/');
      if(slashPos)
        *(slashPos+1) = '\0';
    }
  }

  cmd = aprintf( "%s%s%s",
                 data->set.str[STRING_CUSTOMREQUEST]?
                 data->set.str[STRING_CUSTOMREQUEST]:
                 (data->set.ftp_list_only?"NLST":"LIST"),
                 lstArg? " ": "",
                 lstArg? lstArg: "" );

  if(!cmd) {
    if(lstArg)
      free(lstArg);
    return CURLE_OUT_OF_MEMORY;
  }

  result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);

  if(lstArg)
    free(lstArg);

  free(cmd);

  if(result != CURLE_OK)
    return result;

  state(conn, FTP_LIST);

  return result;
}

================================================================================================================



Just compare the my code with diff given by the link (in my comments above) ..... where Curl_urldecode()  here .... How to apply this patch....

Comment 17 Kamil Dudka 2019-05-13 13:09:13 UTC
The attachment contains the original upstream patch that applies on curl 7.58.0.  It is not surprising that the patch does not cleanly apply on curl 7.35.0.  In comment #15 I pointed you to the actual patch that Red Hat applied on top of curl 7.29.0, which RHEL-7 packages of curl are based.  Feel free to use any of the patches as you like.  As far as I know, curl 7.35.0 is not used in any products currently supported by Red Hat.  So we are not going to provide patches for this upstream release of curl.  That is not our business.  Thanks for understanding!

Comment 18 errata-xmlrpc 2019-06-18 19:09:05 UTC
This issue has been addressed in the following products:

  JBoss Core Services Apache HTTP Server 2.4.29 SP2

Via RHSA-2019:1543 https://access.redhat.com/errata/RHSA-2019:1543

Comment 23 errata-xmlrpc 2020-02-18 14:43:56 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7.5 Extended Update Support

Via RHSA-2020:0544 https://access.redhat.com/errata/RHSA-2020:0544

Comment 24 errata-xmlrpc 2020-02-25 12:11:24 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7.4 Advanced Update Support
  Red Hat Enterprise Linux 7.4 Update Services for SAP Solutions
  Red Hat Enterprise Linux 7.4 Telco Extended Update Support

Via RHSA-2020:0594 https://access.redhat.com/errata/RHSA-2020:0594


Note You need to log in before you can comment on or make changes to this bug.