Bugtraq mailing list archives

WU-ftpd Upload Ownership/Permissions Bug


From: mbrennen () FNI COM (Michael Brennen)
Date: Tue, 24 Jun 1997 10:39:44 -0500


After looking further into the wu-ftpd bug I reported last week, I
realized that many sites may not be vulnerable to the bug that I reported.

In retrospect I realized that I had recently added the /./ to the end of
the anonymous ftp path in /etc/passwd while rearranging the ftp user.  I
certainly had no idea that it would break the upload directive code and
found it quite by accident.  The code does not expect /./ at the end of
the anonymous ftp path and does not behave correctly if it exists.

The argument could be made that the /./ should never [need to] be on the
anonymous ftp path since it is always chrooted.  Given the unexpected
consequences of placing it there, and that adding the patch does not alter
functionality if /./ is not there, I would argue that the source change
should be made in the eventuality that someone puts /./ on their anon ftp
path.

anonymous is a chrooted account, and it would be easy to think you needed
the /./.  If /./ is added, it unexpectedly changes the behaviour of the
daemon for the worse.  That hole should be closed.

A better patch against the original source is below; reverse the first
before applying this one.

   -- Michael

--- ftpd.c.orig Wed May 21 09:29:17 1997
+++ ftpd.c      Fri Jun 20 11:19:01 1997
@@ -1550,6 +1550,8 @@
     expand_id();

     if (anonymous || guest) {
+        char *sp;
+
         /* We MUST do a chdir() after the chroot. Otherwise the old current
          * directory will be accessible as "." outside the new root! */
 #ifdef VIRTUAL
@@ -1559,28 +1561,19 @@
             pw->pw_dir = sgetsave(virtual_root);
         }
 #endif
-        if (anonymous) {
+        /* determine root and home directory */
+
+        if ((sp = strstr(pw->pw_dir, "/./")) == NULL) {
             if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
                 reply(550, "Can't set guest privileges.");
                 goto bad;
             }
-        } else if (guest) {
-            char *sp;
-
-            /* determine root and home directory */
+        } else {
+            *sp++ = '\0';

-            if ((sp = strstr(pw->pw_dir, "/./")) == NULL) {
-                if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
-                    reply(550, "Can't set guest privileges.");
-                    goto bad;
-                }
-            } else {
-                *sp++ = '\0';
-
-                if (chroot(pw->pw_dir) < 0 || chdir(++sp) < 0) {
-                    reply(550, "Can't set guest privileges.");
-                    goto bad;
-                }
+            if (chroot(pw->pw_dir) < 0 || chdir(++sp) < 0) {
+                reply(550, "Can't set guest privileges.");
+                goto bad;
             }
         }
     }



Current thread: