some ftpd implementations mishandle CWD ~{

From: Matt Power (mhpowerat_private)
Date: Mon Apr 30 2001 - 18:00:20 PDT

  • Next message: russi: "Re: Hijack IP Address using cable modem"

    I've recently noticed some incorrect behavior in various ftp daemons
    when presented with the command "CWD ~{" (and other similar commands).
    This affects ftp daemons that are considered not vulnerable to the
    globbing issues (e.g., CAN-2001-0247) announced earlier this month.
    
    There isn't any ftpd for which I've found an exploit by which the
    "CWD ~{" behavior can be leveraged to allow execution of significantly
    undesirable code. The three main points of this posting are:
    
      -- the "CWD ~{" behavior is incorrect in different ways in
         different ftpd's -- in one case, a call to free() occurs that
         shouldn't occur, but others are almost certainly different
      -- the examples included here might provide a starting point for
         locating some combination of a certain ftpd, a certain operating
         system, and certain other circumstances that results in an
         exploitable problem (then again, they might not)
      -- if you prefer to patch daemons whenever there's any way for a
         remote user to cause a segmentation fault, then you may have
         some ftpd code to patch already
    
    All of the examples below are for anonymous-ftp sessions.
    
    In many cases, approximately the same behavior is seen with longer
    input that includes characters after the ~ and after the {, as long as
    these extra characters are unrelated to glob functionality. In other
    words, "CWD ~AAAAAAAAAA{BBBBBBBBBB" is often the same, but "CWD ~*{"
    would be different.
    
    
    (1) wu-ftpd 2.6.1 on Linux (I obtained the source code from
        ftp://ftp.wu-ftpd.org/pub/wu-ftpd/ and built the ftpd on a Red Hat
        6.1 i386 system; however, other installations of wu-ftpd on other
        Linux systems appear to have approximately the same behavior and
        it's quite likely that non-Linux systems are also affected)
    
        command from client: CWD ~{
        behavior of server: segmentation fault (there is no core dump,
           due to the signal handler that wu-ftpd has set for SIGSEGV)
        analysis: In the ftpcmd.y file in the wu-ftpd 2.6.1 source code,
           the relevant part is
    
           else if (logged_in && $1 && strncmp($1, "~", 1) == 0) {
           ...
           globlist = ftpglob($1);
           ...
           else if (globlist) {
           ...
           blkfree(&globlist[1]);
    
         where blkfree is defined as:
    
         void blkfree(char **av0)
         {
             register char **av = av0;
    
             while (*av)
                 free(*av++);
         }
    
    
         For "CWD ~{", in the return value from ftpglob, globlist[0] is
         equal to 0, denoting the end of the list. globlist[1] is after
         the end of the list. The value of globlist[1] is taken from a
         memory location one beyond the end of a malloced block.
         Specifically, there is a statement
    
           register char **nv = (char **) malloc((unsigned) ((blklen(v) + 1) *
                                                             sizeof(char **)));
    
         (it happens to be the case that (blklen(v) + 1) is equal to 1)
    
         and the value of globlist[1] is *(nv + 1). When running the ftpd
         program, the two values of globlist[1] that I saw were 0x40159398
         (for the simple ~{ input), and 0x40159050 (for longer input of
         the form ~AAAAA...{BBBBB...).
    
         In any case, when the value of globlist[1] is passed to free,
         there is a segmentation fault and the ftpd dies. In some cases in
         other programs, passing incorrect values to free can result in
         overwriting of critical memory locations as part of free chunk
         management. However, I have not developed a method by which the
         overwriting in wu-ftpd constitutes an exploit.
    
         Here is a possible patch. It appears to prevent the segmentation
         fault in this particular case. It is quite likely not the best
         solution. The patch is intended only for this CWD ~{ issue and
         doesn't represent an audit of any other parts of the source.
    
    *** ftpcmd.y.old	Sat Jul  1 14:17:39 2000
    --- ftpcmd.y	Mon Apr 30 18:26:45 2001
    ***************
    *** 1139,1141 ****
      			$$ = *globlist;
    ! 			blkfree(&globlist[1]);
      			free((char *) globlist);
    --- 1139,1147 ----
      			$$ = *globlist;
    !  		        if (globlist[0]) {
    ! 			    blkfree(&globlist[1]);
    ! 		        }
    ! 		        else {
    ! 			    errno = ENOENT;
    ! 			    perror_reply(550, $1);
    ! 		        }
      			free((char *) globlist);
    ***************
    *** 1165,1167 ****
      		    $$ = *globlist;
    ! 		    blkfree(&globlist[1]);
      		    free((char *) globlist);
    --- 1171,1179 ----
      		    $$ = *globlist;
    ! 		    if (globlist[0]) {
    ! 			blkfree(&globlist[1]);
    ! 		    }
    ! 		    else {
    ! 			errno = ENOENT;
    ! 			perror_reply(550, $1);
    ! 		    }
      		    free((char *) globlist);
    
    On April 24, Gregory A Lundberg of the WU-FTPD Development Group made
    a small change to the original version of my patch. (The original
    version had two statements that were semantically equivalent to NOP.)
    
    
    (2) NetBSD 1.5T -- I installed a new system with the binary snapshot
        ftp://ftp.netbsd.org/pub/NetBSD/arch/i386/snapshot/20010407-1.5T --
        the SOURCE_DATE file had the contents "20010407-UTC". The NetBSD
        advisory SA2001-005 about the ftpd glob issue mentions "Systems
        running NetBSD-current dated from before 2001-04-04 should be
        upgraded to NetBSD-current dated 2001-04-04 or later." From this,
        I inferred that by doing a complete fresh installation of NetBSD
        from that snapshot directory, the resulting system would have the
        fix for that ftpd glob issue. (This inference might be completely
        incorrect.) The term "snapshot" in the above pathname means that
        the operating-system code used represented a certain point in
        NetBSD development -- this was not an operating-system release and
        it was not in any way implied that the code was suitable for
        general use.
    
        ftpd banner:
        220 hostname FTP server (NetBSD-ftpd 20010329) ready.
    
        client-server dialogue 1:
        client: CWD ~{
        server: 550 ~O s s(ls:%,tp:%): No such file or directory.
    
        client-server dialogue 2:
        client: CWD ~{}{}{{
        server: 250 CWD command successful.
        client: CWD ~{
        server: 550 ~{}{{: No such file or directory.
    
        Off hand, it looks like the server is responding with data from an
        inappropriate memory location. I have not done a source-code analysis.
    
        On a separate issue, there is a wu-ftpd-2.6.1 in the NetBSD
        Packages Collection. See the discussion of wu-ftpd in (1) above.
    
    
    (3) FreeBSD 4.3-RELEASE, i386
    
        ftpd banner:
        220 hostname FTP server (Version 6.00LS) ready.
    
        First client-server dialogue; server has an etc/pwd.db in the
        anonymous-ftp directory tree that specifies a home directory for
        the "ftp" user that actually exists:
        client: CWD ~{
        server: 250 CWD command successful.
    
        Second client-server dialogue; server has an etc/pwd.db in the
        anonymous-ftp directory tree that specifies a home directory for
        the "ftp" user that doesn't actually exist:
        client: CWD ~{
        server: 550 ~: No such file or directory.
    
        This may be not a problem at all, i.e., it may be sufficiently close
        to correct that users are unaffected and all of the glob code
        paths are implemented safely. Possibly, the server ought to return
        "550 ~{: No such file or directory." in both cases, though.
    
        On a separate issue, there is a wu-ftpd-2.6.1 in the FreeBSD Ports
        and Packages Collection. See the discussion of wu-ftpd in (1) above.
    
    
    (4) OpenBSD - I installed a new system using the binary snapshot from
        ftp://ftp.openbsd.org/pub/OpenBSD/snapshots/i386/base29.tgz dated
        "Apr 23 00:41". I guessed that this snapshot incorporated the
        025_glob.patch security fix; possibly I guessed incorrectly. The
        term "snapshots" in the above pathname means that the
        operating-system code used represented a certain point in OpenBSD
        development -- this was not an operating-system release and it was
        not in any way implied that the code was suitable for general use.
    
        ftpd banner:
        220 hostname FTP server (Version 6.5/OpenBSD) ready.
    
        client-server dialogue:
        client: CWD ~{
        server: 250 CWD command successful.
    
        As in the FreeBSD case, this may be not a problem at all. Possibly,
        the server ought to return "550 ~{: No such file or directory."
    
    
    (5) AIX 4.2.x
    
        ftpd banner:
        220 hostname FTP server (Version 4.1 Tue Sep 8 17:35:59 CDT 1998) ready.
    
        client-server dialogue:
        client: CWD ~{
        server: 550 Unknown user name after ~
    
                550 : No such file or directory
    
        (in other words, the server sends a multi-line reply that is not
        valid in the FTP protocol)
    
    
    (6) Tru64 UNIX 4.0_
    
        ftpd banner:
        220 hostname FTP server (Digital UNIX Version 5.60) ready.
    
        If the client sends "CWD ~{", the ftpd does not send any reply to
        that command, but the ftpd continues running.
    
        vendor response:
    
          COMPAQ COMPUTER CORPORATION
             Software Security Response Team  28 Apr 2001
             ref case-id: SSRT0722U
    
          At the time this document was written, Compaq is investigating
          the potential impact to Compaq's Tru64 UNIX ftpd.
    
          Compaq's TCP/IP for OpenVMS is not affected by this issue.
    
          If and when further information becomes available Compaq will
          provide notice of the completion/availability of any necessary
          patches or tuning recommendations through AES services (DIA,
          DSNlink FLASH and posted to the Services WEB page) and be
          available from your normal Compaq Global Services Support
          channel. You may subscribe to several operating system patch
          mailing lists to receive notices of new patches and security
          advisories at:
          http://www.support.compaq.com/patches/mailing-list.shtml
    
    
    (7) HP-UX 11.00
    
        ftpd banner:
        220 hostname FTP server (Version 1.1.214.6 Wed Feb  9 08:03:34 GMT 2000) ready.
    
        If the client sends "CWD ~{", the ftpd does not send any reply to
        that command, but the ftpd continues running. (This HP-UX 11.00
        ftpd is known to have the globbing vulnerability announced earlier
        this month, either in ftpd code or in a system library.)
    
    
    (8) Solaris 8
    
        ftpd banner:
        220 hostname FTP server (SunOS 5.8) ready.
    
        If the client sends "CWD ~{", the ftpd does not send any reply to
        that command, but the ftpd continues running. (This Solaris 8
        ftpd is known to have the globbing vulnerability announced earlier
        this month, either in ftpd code or in a system library.)
    
    
    (9) SunOS 4.1.x
    
        ftpd banner:
        220 hostname FTP server (SunOS 4.1) ready.
    
        If the client sends "CWD ~{", the ftpd dies.
    
    
    (10) ULTRIX 4.x
    
         ftpd banner:
         220 hostname FTP server (Version 4.1 Sun Mar 25 22:59:11 EST 1990) ready.
    
         If the client sends "CWD ~{", the ftpd does not send any reply to
         that command, but the ftpd continues running.
    
    
    (11) Macintosh Darwin
    
         ftpd banner:
         220 hostname FTP server (Version 6.00) ready.
    
         first client-server dialogue:
         client: CWD ~{
         server: 550 ~: No such file or directory.
    
         second client-server dialogue
         client: CWD ~/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
         server: 550 ~/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: No such file or directory.
         client: CWD ~{
         server: 550 ~/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: No such file or directory.
    
        (apparently, if there is no previous input, the server sends an
        error response mentioning "~"; if there is previous input, the
        server sends an error response that includes that previous input)
    
    Matt Power
    BindView Corporation, RAZOR Team
    mhpowerat_private
    



    This archive was generated by hypermail 2b30 : Mon Apr 30 2001 - 20:20:34 PDT