Vulnerability Development mailing list archives

Re: FreeBSD listen()


From: 3APA3A () SECURITY NNOV RU (3APA3A)
Date: Fri, 29 Oct 1999 12:45:37 +0400


Hello Sebastian,

29.10.1999 0:25, you wrote: FreeBSD listen();

full the client may receive an error with an indication of ECONNREFUSED,
or, if the underlying protocol supports retransmission, the request may
be ignored so that retries may succeed.

S> may receive an error ECONNREFUSED (may, not will)

"if  the underlying protocol supports retransmission" this means, if i
understand  clearly,  that  software  should  have  the way to control
action  then  backlog  succeeded,  but by default connection should be
refused, i.e. SYN must not be ACKed.

S> With listen() it is unfortunatly a bit more complicated. Posix.1g says
S> that backlog "defines the maximum length the queue of pending connections
S> may grow to.". It is unclear whether the SYN_RCVD or the ESTABLISHED state
S> is meant. The kernel keeps two lists, one of a completed (ESTABLISHED
S> state) connections and one of the still-to-be-completed connections (in
S> SYN_RCVD state).
S> According to Stevens the backlog parameter in listen() has historically
S> specified the maximum value of the sum of both queues.

and  that's  right.  Because after SYN is ACKed connection must not be
refused  because  of  queue  length  exceeded. It's SYN packed must be
refused.

S> For some unknown reasons berkeley derived implementations multiply backlog
S> with 1.5. (backlog = 5 will turn to 8 for example).

It's very strange behavior... I didn't knew that.

listen(sock, 1)
and  trying to connect() from 3 different connections all 3 connect()s
succeed  atleast  in  FreeBSD  up  to  2.2.6  (later  versions are not
tested).

S> mhh... don't know about this :(

But it is. And this can be clearly defined as a bug.

FreeBSD 3.* is different, but not perfect - extra connect() attempt is
always  ignored  (i.e. timed out) then backlog is exceeded. Connection
will never be rejected with ECONNREFUSED as stated in documentation.

S> may receive an error ... or the request may be ignored.

But  it  always  ignored  and  the  underlying  software has no way to
control it.

S> Limiting the incoming connections through backlog is insecure, if you do
S> not want any clients connecting to your listening sockets, then close the
S> sockets. Either the backlog parameter is multiplied (1 will be 2 on
S> BSD systems, to take care of the SYN_RCVD and ESTABLISHED state), or
S> different implementations will behave differently. Just close the socket.

the  problem is that before listen() and close() accepting side should
inform  other  side  with  the number of the port is listened and make
some  additional  actions. This requires some time and this way allows
attack.  For  example,  ftp  client from FreeBSD closes socket, but it
doesn't  prevent it against attack, because both intruder's connection
and server's connection come between listen() and close().

S>   And btw, since the first incoming connection will be used, you can still
S> mount any classic "ftp-file-stealing" attack, it will even be better with
S> a backlog of 1, because the real client will timeout on the connection.

"File stealing" attack will not work this way, because client will not
initiate  transfer  while PORT command is not succeeded in active mode
or while it hasn't successfully established data connection in passive
mode  (for  example  then  the client connects in passive mode it will
never send RETR command till it doesn't successfully connected to data
port. If data connection timed out RETR will not be sent by client and
data  will  not  be  intersected). So 3.x FreeBSD is safe against file
stealing.  But "data injecting" attack will work, because attacker can
begin transmission while real sender waits for time out, and this data
will  be  accepted  in  most  servers/clients.  That's  why,  I think,
rejecting of exceeding connection is more appropriate way...

3APA3A <WWW.SECURITY.NNOV.RU>

P.S. sorry for bad English.


Current thread: