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