Date: Thu, 02 Jan 1997 07:38:37 -0800 From: David Greenman <dg@root.com> To: freebsd-isp@freebsd.org Subject: serious security bug in wu-ftpd v2.4 Message-ID: <199701021538.HAA16474@root.com>
next in thread | raw e-mail | index | archive | help
Summary ------- There is a serious security bug in wu-ftpd v2.4 (including the version from Academ) which may allow both regular and anonymous users to access files as uid 0 (root). The same bug is also responsible for an advisory lock not being unlocked - potentially resulting in blocked access to future ftp logins and filling up the process table and swap space until the server dies. Description ----------- The ftpd server installs two signal handlers as part of its startup procedure: one to catch SIGPIPE for control/data port connection closes, and one to catch SIGURG for when out-of-band signaling is used with the ABOR (abort file transfer) command. The SIGPIPE handler is: lostconn(int sig) { if (debug) syslog(LOG_DEBUG, "lost connection to %s [%s]", remotehost, remoteaddr); dologout(-1); } ...which causes the ftpd server to exit via dologout() whenever the control or data connection is unexpectedly closed. The function dologout() is: dologout(int status) { if (logged_in) { (void) seteuid((uid_t) 0); logwtmp(ttyline, "", ""); } syslog(LOG_INFO, "FTP session closed"); if (xferlog) close(xferlog); acl_remove(); /* beware of flushing buffers after a SIGPIPE */ _exit(status); } ...which changes the effective uid to 0, adds a logout record to wtmp, closes the xferlog log file, removes this instance of the server from the PID file for his class, and exits. The initial part of the SIGURG handler is: myoob(int sig) { char *cp; /* only process if transfer occurring */ if (!transflag) return; cp = tmpline; if (getline(cp, 7, stdin) == NULL) { reply(221, "You could at least say goodbye."); dologout(0); } upper(cp); if (strcmp(cp, "ABOR\r\n") == 0) { tmpline[0] = '\0'; reply(426, "Transfer aborted. Data connection closed."); reply(226, "Abort successful"); longjmp(urgcatch, 1); } (...) ...which does nothing if transflag is 0 - not currently doing a file transfer, but if you are and an ABOR command was issued along with the "urgent" data that caused this signal, then the procedure does a longjmp() restoring the "urgcatch" saved state, which ultimately returns back to the server main command loop. Now, some FTP client programs will abort a file transfer by BOTH closing the data connection AND issuing an ABOR with out-of-band signaling. In many instances, the ftpd server gets the SIGPIPE due to the closed data connection and begins the dologout() procedure. While it is uid 0 and sometimes while it also has the pid file advisory lock (which occurs in the acl_remove() procedure), the ftpd server will sometimes be interrupted by the SIGURG that is delivered as part of the ABOR command. Since transflag is not 0 (a file transfer WAS occuring), the signal handler does a longjmp which ultimately returns to the main command loop...and presto, you are uid 0, and to make things even better, the xferlog log file is closed so nothing you do is even logged. A patch to fix this problem is simple: *** ftpd.c.bak Wed Jan 1 22:10:05 1997 --- ftpd.c Wed Jan 1 22:10:14 1997 *************** *** 2503,2508 **** --- 2503,2514 ---- void dologout(int status) { + /* + * Prevent reception of SIGURG from resulting in a resumption + * back to the main program loop. + */ + transflag = 0; + if (logged_in) { (void) seteuid((uid_t) 0); logwtmp(ttyline, "", ""); ...which does as the comment suggests. -DG David Greenman Core-team/Principal Architect, The FreeBSD Project
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199701021538.HAA16474>