Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 31 Oct 1999 14:48:47 +0300
From:      "3APA3A" <3APA3A@SECURITY.NNOV.RU>
To:        "David Schwartz" <davids@webmaster.com>, Warren Young <tkennedy@CYBERPORT.COM>, Sebastian <scut@nb.in-berlin.de>, CyberPsychotic <fygrave@SCORPIONS.NET>
Cc:        vulN-DEV@SECURITYFOCUS.COM, security@freebsd.org
Subject:   Re[2]: FreeBSD listen()
Message-ID:  <8617.991031@sandy.ru>
In-Reply-To: <000201bf2324$208587c0$021d85d1@youwant.to>
References:  <000201bf2324$208587c0$021d85d1@youwant.to>

next in thread | previous in thread | raw e-mail | index | archive | help

31.10.99 1:14, you wrote: FreeBSD listen();

I've  got a lot of messages saying there is no security problem. Ok. I
don't  know  is  it  problem  of backlog and operation system or is it
problem  of FTPd, but at least FTPd 6.0 shipped with FreeBSD , WU-ftpd
2.4  and  console  FTP clients from and FreeBSD are vulnerable to file
stealing attack on any OS where listen(sock, 1) doesn't limits pending
queue to exactly one. And only in this case. Let me show.


Lets  look  to "file stealing attack" where data transmitted from FTPD
to client in passive mode. Look how FTPD works after retrieving "PASV"
command:

1. <- PASV
....
sock=socket(..)
bind(sock,...)
...
listen(sock, 1)
/* port is opened and is ready to attack */
/* Now FTPD should inform client which socket is listened */

2. -> 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
/* Client connects dataport, server _waits_ for RETR command */
/* NOTE!!! There is no accept() yet!!!! */
/* This is the point where both hacker and client can connect to server */

3 <- RETR filename.ext
/* now, then filename is known, server begins transmission. */
/* server forks to handle both control and data connection*/
if ( !(child=fork() ) {
   /* data thread */
   data = accept(sock, ...);
   close(sock);
   /* only at that point listening  port  is closed!!! But "RETR" */
   /* command is already received!! */
   ....
   /* send file to "data". */
}
.....

The  problem  of  this  code  is  that  accept() is called _after_ any
connections are established. So real number of established connections
is limited only by backlog.

Now  lets  understand  how  will  attack go on in case listen(sock, 1)
really limits queue to 1 and if it's not.

a)  Assuming  backlog  works fine.
Both  client  and hacker are trying to connect server (it's between 1.
and  3.  Only one connection is succeeded. If client succeed then hacker
fails  and  there is no chance to attack. If hacker succeed and client
fails than client _will not_ send "RETR" command and server will never
begin data transfer. So attack fails. This code is safe.

b)  Assuming  backlog doesn't works.

And 2 connections will be queued. Both hacker's connect() and client's
connect()  will  be  succeed  (note!!!  it's  not accept() establishes
connection!  accept()  just  takes  connection  from  pending queue!).
Client  sends  "RETR"  command  _but_  _only_  _hacker's_ _connection_
_will_  _be_  _accept()ed_!!!! Client connection will be close()d with
sock,  and  client  will  fail  -  but  it's  too  late,  because data
transmission  already  began and data goes to hacker. And this code is
unsafe.

You  see  the  problem is. If you think it's not backlog problem, then
it's  FTPD  problem  and FTPD must perform fork() accept() and close()
immediately after listen():

sock=socket(..)
bind(sock,...)
...
listen(sock, 1)
if ( !(child=fork() ) {
   /* data thread */
   data = accept(sock, ...);
   close(sock);
   ...
}
else {
     /* port is opened but only one connection will succeed! */
     /* Now FTPD should inform client which socket is listened */
     2. -> 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
     ...
}

But  it makes program more complicated, because at this point filename
(or directory listing) to transfer still unknown for data thread. Some
kind  of  interprocess  communication must be implimented :( (sorry if
i'm  saying  some  stupid  things  -  i'm  not  professional  in  UNIX
programming).

As  i  said  already  I'm  not  agree  that the server should check IP
address. But it's better then nothing.

So.... something should be patched.

I  think  there's  no  need to continue discussion in Vuln-dev, please
reply privately.

Sorry again for my bad English.

"3APA3A" <WWW.SECURITY.NNOV.RU>




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8617.991031>