|
|
Saturation du processeur
par _SebF
1 - Le concept
2 - Le fonctionnement
2.1 - Schéma
2.2 -
Calcul du Checksum IP
2.3 -
Calcul du Checksum TCP
2.4 -
Calcul du Checksum UDP
3 - Les conseils et astuces
4 - Les liens
5 - Les outils
6 - La conclusion
7 - Discussion autour de la
documentation
8 -
Suivi du document
Le but est de saturer le processeur de la cible en lui demandant
d'effectuer des calculs de checksum. L'attaque peut être émise à partir d'un
poste ou plusieurs simultanément. Dans le premier cas, vous aurez très souvent vous-même
besoin d'un bon processeur afin de surpasser celui de la cible, excepté, si vous
utilisez des checksums pré calculés. Dans le second cas, vous émettez alors
l'attaque à partir de N postes et disposant ainsi d'une puissance processeur
supérieur à votre cible, d'une bande passante supérieur et des points d'accès
non concentrés et donc plus difficile à stopper.
Le fonctionnement est de générer une trame IP sans application spécifique afin
d'obliger la cible à calculer le checksum de l'entête IP afin de
valider la conformité.

Voici le schéma de l'entête IP
avec ce fameux
Checksum
basé sur 2 octets :

La cible devra calculer le
checksum pour chaque trame reçue sollicitant
implicitement son processeur. Le calcul effectué par la cible est le suivant :
|
unsigned short calcul_du_checksum(bool
liberation, unsigned short *data,
int taille)
{
unsigned long checksum=0;
//
********************************************************
// Complément à 1 de la somme des complément à 1 sur 16 bits
// ********************************************************
while(taille>1)
{
if (liberation==TRUE)
liberation_du_jeton(); // Rend la main à la fenêtre
principale
checksum=checksum+*data++;
taille=taille-sizeof(unsigned
short);
}
if(taille)
checksum=checksum+*(unsigned
char*)data;
checksum=(checksum>>16)+(checksum&0xffff);
checksum=checksum+(checksum>>16);
return (unsigned
short)(~checksum);
} |
L'avantage de cette méthode est d'être portable sur toutes piles IP, même si aucun
port n'est en écoute.
Le fonctionnement est de générer une trame TCP afin d'obliger la cible à calculer le checksum de l'entête IP et TCP afin de valider la
conformité. Voici le schéma de l'entête TCP avec le
Checksum basé sur 2 octets :

La cible devra calculer le checksum de l'entête IP puis celui de l'entête TCP
pour chaque trame reçue sollicitant implicitement son processeur. Le calcul
effectué par la cible pour le Checksum TCP est le suivant :
|
struct pseudo_entete
{
unsigned long ip_source;
// Adresse ip source
unsigned long ip_destination;
// Adresse ip destination
char mbz;
// Champs à 0
char type;
// Type de protocole (6->TCP et 17->UDP)
unsigned short length;
// htons( Taille de l'entete Pseudo + Entete TCP
ou UDP + Data )
};
unsigned short calcul_du_checksum_tcp(bool
liberation, unsigned long ip_source_tampon,
unsigned long ip_destination_tampon,
struct tcp tcp_tampon,
char data_tampon[65535])
{
struct pseudo_entete pseudo_tcp;
char tampon[65535];
unsigned short checksum;
//
********************************************************
// Initialisation du checksum
// ********************************************************
tcp_tampon.checksum=0; // Doit être à 0
pour le calcul
//
********************************************************
// Le calcul du Checksum TCP (Idem à UDP)
// ********************************************************
// Le calcul passe par une pseudo entete TCP + l'entete TCP +
les Data
pseudo_tcp.ip_source=ip_source_tampon;
pseudo_tcp.ip_destination=ip_destination_tampon;
pseudo_tcp.mbz=0;
pseudo_tcp.type=IPPROTO_TCP;
pseudo_tcp.length=htons((unsigned short)(sizeof(struct
tcp)+strlen(data_tampon)));
memcpy(tampon,&pseudo_tcp,sizeof(pseudo_tcp));
memcpy(tampon+sizeof(pseudo_tcp),&tcp_tampon,sizeof(struct
tcp));
memcpy(tampon+sizeof(pseudo_tcp)+sizeof(struct
tcp),data_tampon,strlen(data_tampon));
checksum=calcul_du_checksum(liberation,(unsigned
short*)tampon,sizeof(pseudo_tcp)+sizeof(struct
tcp)+strlen(data_tampon));
return(checksum);
} |
L'utilisation du checksum TCP permet d'obtenir de meilleur résultat, car
implicitement, il est combiné au checksum IP.
Le fonctionnement est identique à la méthode TCP, pour cela, il faut générer
une trame UDP afin d'obliger la cible à calculer le checksum de
l'entête IP et UDP afin de valider la conformité. Voici le schéma de l'entête
UDP avec le
Checksum basé sur 2 octets :

La cible devra calculer le checksum de l'entête
IP puis celui de l'entête UDP
pour chaque trame reçue sollicitant implicitement son processeur. Le calcul
effectué par la cible pour le Checksum UDP est le suivant :
|
struct pseudo_entete
{
unsigned long ip_source;
// Adresse ip source
unsigned long ip_destination;
// Adresse ip destination
char mbz;
// Champs à 0
char type;
// Type de protocole (6->TCP et 17->UDP)
unsigned short length;
// htons( Taille de l'entete Pseudo + Entete TCP ou UDP +
Data )
};
unsigned short calcul_du_checksum_udp(bool
liberation, unsigned long ip_source_tampon,
unsigned long ip_destination_tampon,
struct udp udp_tampon, char
data_tampon[65535])
{
struct pseudo_entete pseudo_udp;
char tampon[65535];
unsigned short checksum;
//
********************************************************
// Initialisation du checksum
// ********************************************************
udp_tampon.checksum=0; // Doit être à 0 pour le calcul
//
********************************************************
// Le calcul du Checksum UDP (Idem à TCP)
// ********************************************************
// Le calcul passe par une pseudo entete UDP + l'entete UDP +
les Data
pseudo_udp.ip_source=ip_source_tampon;
pseudo_udp.ip_destination=ip_destination_tampon;
pseudo_udp.mbz=0;
pseudo_udp.type=IPPROTO_UDP;
pseudo_udp.length=htons((unsigned short)(sizeof(struct
udp)+(unsigned short)strlen(data_tampon)));
memcpy(tampon,&pseudo_udp,sizeof(pseudo_udp));
memcpy(tampon+sizeof(pseudo_udp),&udp_tampon,sizeof(struct
udp));
memcpy(tampon+sizeof(pseudo_udp)+sizeof(struct
udp),data_tampon,strlen(data_tampon));
checksum=calcul_du_checksum(liberation,(unsigned
short*)tampon,sizeof(pseudo_udp)+sizeof(struct
udp)+strlen(data_tampon));
return(checksum);
} |
- L'astuce de l'émetteur est d'envoyer des trames préconstruites afin de ne pas
calculer soit même le checksum gagnant ainsi un temps considérable.
-
L'utilisation de
smurf augmentera fortement le nombre de checksum à calculer.
-
Le choix de la taille des données est important. Si les trames sont grandes, du style
65535 octets, alors le calcul du checksum sera plus long et sollicitera plus de
processeur.
-
FrameIP est un générateur de trames IP. Il vous permettra de personnaliser
les champs des différentes entêtes réseaux.
Vous aurez la possibilité grâce à cet outils de pré calculer les checksum.
-
PingIcmp permet d'effectuer des Ping Icmp sans interruption.
La puissance de calcul est tel maintenant, que même la combinaison Checksum IP
et TCP n'écroulera pas les récents processeurs. Cependant, destiné à des petits
chipset tel que des boîtiers d'impression, des routeurs de particulier et
autres, la gêne occasionnée peut être conséquente.
Vous pouvez poser toutes vos questions,
vos remarques et vos expériences à propos de l'attaque pour saturer le processeur. Pour cela,
rendez-vous sur le
Forum "Sécurité".
Le 30 septembre 2003, par _SebF, création du document.
|
|