Spoofing
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <arpa/inet.h> #define PACKET_SIZE 1024 // Función para calcular el checksum unsigned short checksum(void *b, int len) { unsigned short *buf = b; unsigned int sum = 0; unsigned short result; for (sum = 0; len > 1; len -= 2) sum += *buf++; if (len == 1) sum += *(unsigned char *)buf; sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); result = ~sum; return result; } int main() { int sd; char packet[PACKET_SIZE]; // En macOS usamos 'struct ip' y 'struct icmp' struct ip *ip = (struct ip *) packet; struct icmp *icmp = (struct icmp *) (packet + sizeof(struct ip)); struct sockaddr_in sin; int one = 1; // 1. Crear el Raw Socket sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sd < 0) { perror("Error al crear socket (¿usaste sudo?)"); exit(1); } // Informar al kernel que nosotros incluimos la cabecera IP if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0) { perror("Error en setsockopt"); exit(1); } memset(packet, 0, PACKET_SIZE); // 2. Direcciones char *src_ip = "8.8.8.8"; char *dst_ip = "127.0.0.1"; sin.sin_family = AF_INET; inet_pton(AF_INET, dst_ip, &sin.sin_addr); // 3. Construir Cabecera IP (Estilo BSD/macOS) ip->ip_v = 4; ip->ip_hl = 5; ip->ip_tos = 0; ip->ip_len = sizeof(struct ip) + sizeof(struct icmp); ip->ip_id = htons(12345); ip->ip_off = 0; ip->ip_ttl = 64; ip->ip_p = IPPROTO_ICMP; ip->ip_sum = 0; // El kernel suele calcularlo, pero lo pondremos a 0 inet_pton(AF_INET, src_ip, &ip->ip_src); inet_pton(AF_INET, dst_ip, &ip->ip_dst); // 4. Construir Cabecera ICMP icmp->icmp_type = ICMP_ECHO; icmp->icmp_code = 0; icmp->icmp_id = htons(getpid()); icmp->icmp_seq = htons(1); icmp->icmp_cksum = 0; // Calcular Checksum ICMP icmp->icmp_cksum = checksum(icmp, sizeof(struct icmp)); // 5. Enviar printf("Enviando ICMP: %s -> %s\n", src_ip, dst_ip); if (sendto(sd, packet, ip->ip_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("Error al enviar"); } else { printf("¡Paquete enviado! Revisa tu sniffer.\n"); } close(sd); return 0; } |
Sniffer
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pcap.h> #include <arpa/inet.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <time.h> #define SNAPLEN 65535 static void procesar_paquete(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { (void)args; if (header->caplen < 4) { return; } /* * En loopback de macOS suele usarse DLT_NULL: * 4 bytes con la familia de direcciones, seguidos de la cabecera IP. */ const u_char *ip_start = packet + 4; if ((size_t)header->caplen < 4 + sizeof(struct ip)) { return; } const struct ip *ip_header = (const struct ip *)ip_start; if (ip_header->ip_v != 4) { return; } int ip_header_len = ip_header->ip_hl * 4; if (ip_header_len < 20) { return; } if (ip_header->ip_p != IPPROTO_ICMP) { return; } if ((size_t)header->caplen < 4 + ip_header_len + 8) { return; } const struct icmp *icmp_header = (const struct icmp *)(ip_start + ip_header_len); char ip_origen[INET_ADDRSTRLEN]; char ip_destino[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(ip_header->ip_src), ip_origen, sizeof(ip_origen)); inet_ntop(AF_INET, &(ip_header->ip_dst), ip_destino, sizeof(ip_destino)); char tiempo[64]; struct tm *tm_info = localtime(&header->ts.tv_sec); if (tm_info != NULL) { strftime(tiempo, sizeof(tiempo), "%Y-%m-%d %H:%M:%S", tm_info); } else { snprintf(tiempo, sizeof(tiempo), "hora-desconocida"); } printf("\n[%s.%06ld]\n", tiempo, (long)header->ts.tv_usec); printf("Origen : %s\n", ip_origen); printf("Destino : %s\n", ip_destino); printf("Interfaz : lo0\n"); printf("Protocolo : ICMP\n"); printf("Tipo ICMP : %u\n", icmp_header->icmp_type); printf("Código ICMP : %u\n", icmp_header->icmp_code); printf("Longitud : %u bytes\n", header->len); switch (icmp_header->icmp_type) { case ICMP_ECHO: printf("Descripción : Echo Request (ping)\n"); break; case ICMP_ECHOREPLY: printf("Descripción : Echo Reply\n"); break; case ICMP_UNREACH: printf("Descripción : Destination Unreachable\n"); break; case ICMP_TIMXCEED: printf("Descripción : Time Exceeded\n"); break; default: printf("Descripción : Otro tipo ICMP\n"); break; } } int main(void) { char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *handle; struct bpf_program fp; char filter_exp[] = "icmp"; bpf_u_int32 net = 0, mask = 0; const char *dev = "lo0"; memset(errbuf, 0, sizeof(errbuf)); if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { net = 0; mask = 0; } handle = pcap_open_live(dev, SNAPLEN, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "No se pudo abrir la interfaz %s: %s\n", dev, errbuf); return 1; } int dlt = pcap_datalink(handle); if (dlt != DLT_NULL) { fprintf(stderr, "La interfaz %s no está usando DLT_NULL. DLT detectado: %d\n", dev, dlt); fprintf(stderr, "Este ejemplo está preparado específicamente para loopback con DLT_NULL.\n"); pcap_close(handle); return 1; } if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Error compilando filtro '%s': %s\n", filter_exp, pcap_geterr(handle)); pcap_close(handle); return 1; } if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Error aplicando filtro '%s': %s\n", filter_exp, pcap_geterr(handle)); pcap_freecode(&fp); pcap_close(handle); return 1; } printf("Capturando paquetes ICMP en la interfaz de loopback: %s\n", dev); printf("Pulsa Ctrl+C para detener.\n"); pcap_loop(handle, 0, procesar_paquete, NULL); pcap_freecode(&fp); pcap_close(handle); return 0; } |

