[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