forked from vanhauser-thc/thc-ipv6
-
Notifications
You must be signed in to change notification settings - Fork 0
/
passive_discovery6.c
171 lines (145 loc) · 5.16 KB
/
passive_discovery6.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#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"
#define MAX_ENTRIES 65536
int maxhop = 255, dcnt = 0, do_dst = 0, noverb = 0;
unsigned char d[MAX_ENTRIES + 1][16], hostpart[8];
char *interface, *script = NULL, exec[256], *replace = NULL, *ll;
void help(char *prg) {
printf("%s %s (c) 2019 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE);
printf("Syntax: %s [-Ds] [-m maxhop] [-R prefix] interface [script]\n\n", prg);
printf("Options:\n");
printf(" -D do also dump destination addresses (does not work with -m)\n");
printf(" -s do only print the addresses, no other output\n");
printf(" -m maxhop the maximum number of hops a target which is dumped may be away.\n");
printf(" 0 means local only, the maximum amount to make sense is usually 5\n");
printf(" -R prefix exchange the defined prefix with the link local prefix\n");
printf("\nPassivly sniffs the network and dump all client's IPv6 addresses detected.\n");
printf("Note that in a switched environment you get better results when additionally\nstarting parasite6, however this will impact the network.\n");
printf("If a script name is specified after the interface, it is called with the\ndetected ipv6 address as first and the interface as second option.\n");
exit(-1);
}
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;
}
}
int main(int argc, char *argv[]) {
int i;
char *glob;
if (argc < 2 || strncmp(argv[1], "-h", 2) == 0)
help(argv[0]);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
while ((i = getopt(argc, argv, "Dsm:R:")) >= 0) {
switch (i) {
case 'm':
maxhop = atoi(optarg);
break;
case 'D':
do_dst = 1;
break;
case 's':
noverb = 1;
break;
case 'R':
if ((ll = index(optarg, '/')) != NULL)
*ll = 0;
replace = thc_resolve6(optarg);
break;
default:
fprintf(stderr, "Error: invalid option %c\n", i);
exit(-1);
}
}
if (argc - optind < 1 || argc - optind > 2)
help(argv[0]);
interface = argv[optind];
if (argc == optind + 2)
script = argv[optind + 1];
memset(d, 0, sizeof(d));
_thc_ipv6_showerrors = 0;
// we dont want our own address in the discovered addresses
glob = thc_get_own_ipv6(interface, NULL, PREFER_GLOBAL);
ll = thc_get_own_ipv6(interface, NULL, PREFER_LINK);
memcpy(hostpart, ll + 8, 8);
if (memcmp(ll + 8, glob + 8, 8) != 0) { // do we have a global address with a different host part?
memcpy(d[0], glob, 16);
dcnt = 1;
}
if (do_dst < 255 && do_dst)
fprintf(stderr, "Warning: it does not make sense to use the -m and -D options together!\n");
if (noverb == 0)
printf("Started IPv6 passive system detection (Press Control-C to end) ...\n");
return thc_pcap_function(interface, "ip6", (char *) detect, 1, NULL);
return 0; // never reached
}