ftpd security problems

Hello

User logged on ftp can create directories overriding permissions.
A.e. any user can create directories in /home

Dmitry Alexeyev
QNX.ORG.RU :: Russian QNX Comunity
dmi@qnx.org.ru

Dmitry Alexeyev <dmi@qnx.org.ru> wrote:
: Hello

: User logged on ftp can create directories overriding permissions.
: A.e. any user can create directories in /home

You will have give a little more or submit a PR.
When loggin in, anonymous ftpd does a chroot ("/home/ftp") (wherever
“home” is for ftp in /etc/passwd) followed by a chdir ("/").
In theory “/home/ftp” becomes – > “/” root.

Take note that we still use the “old” BSD ftpd code, they maybe
some security issues in terms of memory overflow etc … that
the networking group did not deal with yet, if this is the case,
bring this to there attention with a PR.

Alain Magloire wrote:

Dmitry Alexeyev <> dmi@qnx.org.ru> > wrote:
: Hello

: User logged on ftp can create directories overriding permissions.
: A.e. any user can create directories in /home

You will have give a little more or submit a PR.
When loggin in, anonymous ftpd does a chroot ("/home/ftp") (wherever
“home” is for ftp in /etc/passwd) followed by a chdir ("/").
In theory “/home/ftp” becomes – > “/” root.

I am logging in as ‘qnx’, not anonmymous.
chroot() still doesn’t work in QNX 6.
qnx uid is 500, gid is 100 ( non-existing group )
If I try to make directory “/home/aaa” from shell I can not do that.
But from ftp I can !!!

If you would try that on old NetBSD it won’t work.

And I just discovered that there are more problems in ftpd…

Take note that we still use the “old” BSD ftpd code, they maybe
some security issues in terms of memory overflow etc … that
the networking group did not deal with yet, if this is the case,
bring this to there attention with a PR.

Dmitry Alexeyev
QNX.ORG.RU :: Russian QNX Comunity
dmi@qnx.org.ru

Dmitry Alexeyev <dmi@qnx.org.ru> wrote:

: Alain Magloire wrote:

:> Dmitry Alexeyev <dmi@qnx.org.ru> wrote:
:> : Hello
:>
:> : User logged on ftp can create directories overriding permissions.
:> : A.e. any user can create directories in /home
:>
:> You will have give a little more or submit a PR.
:> When loggin in, anonymous ftpd does a chroot ("/home/ftp") (wherever
:> “home” is for ftp in /etc/passwd) followed by a chdir ("/").
:> In theory “/home/ftp” becomes – > “/” root.

: I am logging in as ‘qnx’, not anonmymous.
: chroot() still doesn’t work in QNX 6.

Yes, it does not work as expected many services are not passing through.
For example, when doing ls, this will map to popen ("/bin/ls -loA");
which will not work. But however, doing “nlist” will work, since it is
internal.
An iterim solution would be to provide a complete internal “/bin/ls”. But
the long term would be to fix this.

: qnx uid is 500, gid is 100 ( non-existing group )
: If I try to make directory “/home/aaa” from shell I can not do that.
: But from ftp I can !!!

is /home group writable ? i.e. What is ls -ld /home?

: If you would try that on old NetBSD it won’t work.

It does not work on my rtp box either.
However the user was 340 group 120 with /home own by root.

: And I just discovered that there are more problems in ftpd…

Which are?

Alain Magloire wrote:

:: qnx uid is 500, gid is 100 ( non-existing group )
: If I try to make directory “/home/aaa” from shell I can not do that.
: But from ftp I can !!!

is /home group writable ? i.e. What is ls -ld /home?

/home is owned by root.root , have 755 permissions.

qnx is gid 100, and root gid is 0

But gid 100 is not described in /etc/group

I tried this on default QNX installation.

: If you would try that on old NetBSD it won’t work.

It does not work on my rtp box either.
However the user was 340 group 120 with /home own by root.

I have installed QNX from windows, maybe the problem is here…

: And I just discovered that there are more problems in ftpd…

Which are?

try LIST ~// and ftpd will be signaled with SIGSEGV

Dmitry Alexeyev <dmi@qnx.org.ru> wrote:


: Alain Magloire wrote:

:> :: qnx uid is 500, gid is 100 ( non-existing group )
:> : If I try to make directory “/home/aaa” from shell I can not do that.
:> : But from ftp I can !!!
:>
:> is /home group writable ? i.e. What is ls -ld /home?
:>

: /home is owned by root.root , have 755 permissions.

: qnx is gid 100, and root gid is 0

: But gid 100 is not described in /etc/group

: I tried this on default QNX installation.

: I have installed QNX from windows, maybe the problem is here…

Once you authenticate, the server does a seteuid () and setegid ()
So normal file system permissions will apply if you try to create
or remove a file. I’ve try to recreate the 100 not in /etc/group
but still every thing behaves like expected.

:>
:> : And I just discovered that there are more problems in ftpd…
:>
:> Which are?

: try LIST ~// and ftpd will be signaled with SIGSEGV


Yes, this is quite old, it is a bug in the ftpd_popen () function
overruning its array. I do believe that the network group fixed this already
along with some other bugs. I’m not sure why it is not in your rtp distribution,
unless it is quite old or they put a wrong fix. In any case, it would be a good
thing if you submit a PR or for any other bugs that the BSD ftpd code still carries.

Alain Magloire wrote:

Yes, it does not work as expected many services are not passing through.
For example, when doing ls, this will map to popen ("/bin/ls -loA");
which will not work. But however, doing “nlist” will work, since it is
internal.
An iterim solution would be to provide a complete internal “/bin/ls”. But
the long term would be to fix this.

That’s only tip of the iceberg. After chroot() you don’t have /dev so
many library calls will fail, including socket(). Various flavors of
Unix deal with this problem in different ways, but QNX just does
nothing. The socket() was actually needed by ftpd itself, which is why
anon FTP did not work on QNX at all, before they hacked it using
openfd().

  • igor

This shows the problem. Looks like ftpd doesn’t correctly make setgid()

$ uname -a
QNX dmitry 6.1.0 2001/08/23-19:38:50edt x86pc x86
$ id
uid=100(qnx) gid=100
$ ls -ld /home
drwxrwxr-x 5 root root 2048 Dec 29 04:17 /home
$ mkdir /home/aaa
mkdir: /home/aaa: Permission denied
$ ftp localhost
Connected to localhost.localdomain.
220 dmitry FTP server (Version 5.60) ready.
Name (localhost:qnx): qnx
331 Password required for qnx.
Password:
230 User qnx logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /home
250 CWD command successful.
ftp> mkdir aaa
257 MKD command successful.
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls -loA.
total 16
drwxr-xr-- 2 qnx 2048 Dec 29 04:18 aaa
drwxr-xr-x 6 dmi 2048 Dec 04 19:02 dmi
drwxrwxr-x 7 root 2048 Dec 22 00:34 ftp
drwxr-xr-x 8 qnx 2048 Dec 22 04:31 qnx
226 Transfer complete.
ftp>

Yes, this is quite old, it is a bug in the ftpd_popen () function
overruning its array. I do believe that the network group fixed this already
along with some other bugs. I’m not sure why it is not in your rtp distribution,
unless it is quite old or they put a wrong fix. In any case, it would be a good
thing if you submit a PR or for any other bugs that the BSD ftpd code still carries.

I have submutted PR already, several months ago.

Dmitry Alexeyev <dmi@qnx.org.ru> wrote:
: This shows the problem. Looks like ftpd doesn’t correctly make setgid()

I can assume in your case that “qnx” is not in the root group
in /etc/group and that “/home” is not NFS mounted on anything of that sort.

Then, I do not know. It seems to work ok here.

uname -a

QNX node161 6.1.0 2001/08/23-19:38:50edt x86pc x86

id

uid=100(alain) gid=100

cd /home

ls -la

total 18
drwxrwxr-x 3 root root 2048 Dec 28 21:11 ./
drwxrwxr-x 14 root root 4096 Sep 05 08:37 …/
lrwxrwxrwx 1 root root 23 Jun 27 2001 alain@ → /fs/hd1-qnx4/home/al
ain
drwxr-xr-x 5 root root 2048 Dec 28 16:12 ftp/
lrwxrwxrwx 1 root root 23 Jun 27 2001 guest@ → /fs/hd1-qnx4/home/gu
est
-rw-rw-r-- 1 root root 0 Dec 28 16:27 me

mkdir aa

mkdir: aa: Permission denied

ftp localhost

Connected to localhost.
220 node161 FTP server (Version 5.60) ready.
Name (localhost:alain):
331 Password required for alain.
Password:
230 User alain logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /home
250 CWD command successful.
ftp> ls -la
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls -loA -la.
total 18
drwxrwxr-x 3 root root 2048 Dec 28 21:11 .
drwxrwxr-x 14 root root 4096 Sep 05 08:37 …
lrwxrwxrwx 1 root root 23 Jun 27 2001 alain → /fs/hd1-qnx4/home/ala
in
drwxr-xr-x 5 root root 2048 Dec 28 16:12 ftp
lrwxrwxrwx 1 root root 23 Jun 27 2001 guest → /fs/hd1-qnx4/home/gue
st
-rw-rw-r-- 1 root root 0 Dec 28 16:27 me
226 Transfer complete.
ftp> mkdir aa
550 aa: Permission denied.
ftp> dele me
550 me: Permission denied.
ftp> dele a
550 a: No such file or directory.
ftp> dele ftp
550 ftp: Directory not empty.
ftp> mkdir bb
550 bb: Permission denied.
ftp>

:> Yes, this is quite old, it is a bug in the ftpd_popen () function
:> overruning its array. I do believe that the network group fixed this already
:> along with some other bugs. I’m not sure why it is not in your rtp distribution,
:> unless it is quite old or they put a wrong fix. In any case, it would be a good
:> thing if you submit a PR or for any other bugs that the BSD ftpd code still carries.

: I have submutted PR already, several months ago.

hmm … Usually they are responsive, it depends on where they put the priorities.
I suppose ftpd is not in the top ten.

In my case doing LIST ~// anything bad then a
“550 arguments too long” → from glog.c
But however LIST ////// seems to get me in trouble … but no SIGSEGV.
just the disk going crasy.

Igor Kovalenko <Igor.Kovalenko@motorola.com> wrote:
: Alain Magloire wrote:
:>
:> Yes, it does not work as expected many services are not passing through.
:> For example, when doing ls, this will map to popen ("/bin/ls -loA");
:> which will not work. But however, doing “nlist” will work, since it is
:> internal.
:> An iterim solution would be to provide a complete internal “/bin/ls”. But
:> the long term would be to fix this.

: That’s only tip of the iceberg. After chroot() you don’t have /dev so
: many library calls will fail, including socket(). Various flavors of
: Unix deal with this problem in different ways, but QNX just does
: nothing. The socket() was actually needed by ftpd itself, which is why
: anon FTP did not work on QNX at all, before they hacked it using
: openfd().

Yes and I do believe we had this conversation before :sunglasses:.
The solution for chroot () is not an easy one.

Huh! I’ve found the problem. slay inetd and start it again !
inetd starts with gid=0 and avery gid in system. ftpd inherits this.

Then, I do not know. It seems to work ok here.

hmm … Usually they are responsive, it depends on where they put the priorities.
I suppose ftpd is not in the top ten.

In my case doing LIST ~// anything bad then a
“550 arguments too long” → from glog.c
But however LIST ////// seems to get me in trouble … but no SIGSEGV.
just the disk going crasy.

That’s how it is on my box ( no matter what command you use, it might be chmod, cd, mkdir
and so on ):

which ftpd

/usr/sbin/ftpd

ls -al /usr/sbin/ftpd

-rwxrwxr-x 1 root bin 49628 Jun 22 2001 /usr/sbin/ftpd

cksum /usr/sbin/ftpd

2709774707 49628 /usr/sbin/ftpd

ftp localhost

Connected to localhost.localdomain.
220 dmitry FTP server (Version 5.60) ready.
Name (localhost:root): qnx
331 Password required for qnx.
Password:
230 User qnx logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls ~//
200 PORT command successful.
421 Service not available, remote server has closed connection
ftp> quit

coreinfo /var/dumps/ftpd.core

/var/dumps/ftpd.core:
processor=X86 num_cpus=1
cpu 1 cpu=686 name=Pentium Celeron Stepping 5 speed=525
flags=0xc00017ff FPU MMU CPUID RDTSC INVLPG WP BSWAP MMX CMOV PSE PGE MTR
P FXSR
cyc/sec=525143700 tod_adj=1009587484177350072 nsec=137882900688 inc=999847
boot=1009603685 epoch=1970 intr=0
rate=838095345 scale=-15 load=1193
MACHINE=“x86pc” HOSTNAME=“localhost”
hwflags=0x000540
valid=512 heads=255 cyls=1025 sectors=63 nblocks=60050970 spare=0
pid=602149 parent=208919 child=0 pgrp=208919 sid=1
flags=0x002200 umask=023 base_addr=0x8048000 init_stack=0x8047e00
ruid=0 euid=100 suid=0 rgid=0 egid=100 sgid=0
ign=0000000000020000 queue=ff00000000000000 pending=0000000000000000
fds=4 threads=1 timers=1 chans=1
thread 1 SIGNALLED-SIGSEGV code=1 MAPERR refaddr=0 fltno=11
ip=0x804abd0 sp=0x804784c stkbase=0x7fc7000 stksize=528384
state=STOPPED flags=0 last_cpu=1 timeout=00000000
pri=10 realpri=10 policy=OTHER

I continued playing with ftpd ( just for fun )
ls ***********/
ftpd freezes, cpu load is 100%
both ftpd and procnto thread attached are in state READY

combining this and ls /dev ( which works really long ) i got my /dev directory converted to
a file containing list of files in my home directory.
But everything still worked fine !
I remembered old bug with tar/gzip which did the same and just erased /dev file. Directory
appeared again.
Why do this happen ?

Dmitry Alexeyev <dmi@qnx.org.ru> wrote:
: Huh! I’ve found the problem. slay inetd and start it again !
: inetd starts with gid=0 and avery gid in system. ftpd inherits this.

Great!

:> Then, I do not know. It seems to work ok here.
:>
:> hmm … Usually they are responsive, it depends on where they put the priorities.
:> I suppose ftpd is not in the top ten.
:>
:> In my case doing LIST ~// anything bad then a
:> “550 arguments too long” → from glog.c
:> But however LIST ////// seems to get me in trouble … but no SIGSEGV.
:> just the disk going crasy.

: That’s how it is on my box ( no matter what command you use, it might be chmod, cd, mkdir
: and so on ):

Please PR. I went to the network group about the issues you raised, but no
PR was found.

: I continued playing with ftpd ( just for fun )
: ls ***********/
: ftpd freezes, cpu load is 100%
: both ftpd and procnto thread attached are in state READY

: combining this and ls /dev ( which works really long ) i got my /dev directory converted to
: a file containing list of files in my home directory.
: But everything still worked fine !
: I remembered old bug with tar/gzip which did the same and just erased /dev file. Directory
: appeared again.
: Why do this happen ?

Do not remember that particular bug.

The ls ///* stuff may be related to lot of issues … do you use QNET? did
you have an NFS mount etc …?