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>