[ipv6hackers] nmap's and msf's spoofed-ra scan technique?
Marc Heuse
mh at mh-sec.de
Wed Apr 25 13:06:37 CEST 2012
Hi Fernando,
Am 25.04.2012 11:30, schrieb Fernando Gont:
> After digging a bit into the aforementioned local-scan technique (see:
> <http://lists.si6networks.com/pipermail/ipv6hackers/2012-March/000500.html>),
> it turns out that nmap's script is kind of a port (?) of the
> corresponding Metasploit's script.
>
> Has anyone found a real world device that cannot be discovered with
> these two vectors (in addition to the traditional multicasted ping6)?
I do not have details, however when playing at a conference with a new
addition to the thc-ipv6 package (for fun&play sake, its attached) I
found that after I ran my own version of the RA discovery technique,
some systems popped up that I had not previously seen by the ping +
ping&invalid mechanisms.
I have no explanation for this nor can I see which OS these systems
were, just that I saw it. Could also have a different explaination (e.g.
some systems joining the conference wlan directly after my alive scan
and before the RA discovery packets)
> Unless there's a real use case for this technique, I'd say I find it
> noisy and maybe even disruptive.
well it is noisy, and can be disruptive, although the impact should be
none to marginal if done correctly.
Greets,
vh
--
Marc Heuse
www.mh-sec.de
PGP: FEDD 5B50 C087 F8DF 5CB9 876F 7FDD E533 BF4F 891A
-------------- next part --------------
#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
extern int debug;
extern int _thc_ipv6_showerrors;
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) 2012 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;
int i, j, k, offset = 22, doit;
// drop ff00::/8 and ::/128
for (k = 0; k <= do_dst; k++) {
doit = 0;
if (data[offset] != 0xff
&&
( maxhop > 254 || data[21] >= 255 - maxhop || (data[21] >= 128 - maxhop && data[21] <= 128) || (data[21] >= 64 - maxhop && data[21] <= 64) )
)
doit = 1;
if (memcmp(data + 22, d[dcnt + 1], 16) == 0) {
if (k == 0 && data[21] == 255 && data[20] == NXT_ICMP6 && data[54] == ICMP6_NEIGHBORSOL && header->caplen >= 78) {
doit = 1; // DAD packet
offset = 62;
} else
doit = 0;
}
// is it our own address?
if (memcmp(data + offset + 8, hostpart, 8) == 0)
doit = 0;
if (doit) {
// replace prefix with link-local if -R
if (replace != NULL)
if (memcmp(data + offset, replace, 8) == 0)
memcpy(data + offset, ll, 8);
// check for doubles
j = 0;
if (dcnt > 0)
for (i = 0; i < dcnt && j == 0; i++)
if (memcmp(data + offset, d[i], 16) == 0)
j = 1;
if (j == 0) { // no double
ptr = thc_ipv62notation((char *) (data + offset));
printf("%s%s\n", noverb == 0 ? "Detected: " : "", ptr);
if (dcnt < MAX_ENTRIES) { // add to double list
memcpy(d[dcnt], data + 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, ptr, interface);
if (system(exec) < 0)
fprintf(stderr, "Error: Executing failed - %s\n", exec);
exit(0);
}
free(ptr);
}
}
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
}
More information about the Ipv6hackers
mailing list