[prev in list] [next in list] [prev in thread] [next in thread]
List: freebsd-security
Subject: Re[2]: FreeBSD listen()
From: "3APA3A" <3APA3A () SECURITY ! NNOV ! RU>
Date: 1999-10-31 11:48:47
[Download RAW message or body]
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
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic