Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/scanner/discovery/ipv6_neighbor.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Ipv67include Msf::Exploit::Remote::Capture8include Msf::Auxiliary::Report9include Msf::Auxiliary::Scanner101112def initialize13super(14'Name' => 'IPv6 Local Neighbor Discovery',15'Description' => %q{16Enumerate local IPv6 hosts which respond to Neighbor Solicitations with a link-local address.17Note, that like ARP scanning, this usually cannot be performed beyond the local18broadcast network.19},20'Author' => 'belch',21'License' => MSF_LICENSE22)2324register_options(25[26OptString.new('SHOST', [false, "Source IP Address"]),27OptString.new('SMAC', [false, "Source MAC Address"]),28OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 5]),29])3031deregister_options('SNAPLEN', 'FILTER')32end3334def run_batch_size35datastore['BATCHSIZE'] || 25636end3738def run_batch(hosts)39open_pcap({'SNAPLEN' => 68, 'FILTER' => "arp[6:2] == 0x0002"})4041@netifaces = true42if not netifaces_implemented?43print_error("WARNING : Pcaprub is not up-to-date, some functionality will not be available")44@netifaces = false45end4647print_status("Discovering IPv4 nodes via ARP...")4849@interface = datastore['INTERFACE'] || Pcap.lookupdev50@shost = datastore['SHOST']51@shost ||= get_ipv4_addr(@interface) if @netifaces52raise 'SHOST should be defined' unless @shost5354@smac = datastore['SMAC']55@smac ||= get_mac(@interface) if @netifaces56raise 'SMAC should be defined' unless @smac5758addrs = []5960begin61found = {}62hosts.each do |dhost|6364probe = buildprobe(@shost, @smac, dhost)65capture.inject(probe)66while(reply = getreply())67next unless reply.is_arp?68if not found[reply.arp_saddr_ip]69print_good(sprintf(" %16s ALIVE",reply.arp_saddr_ip))70addrs << [reply.arp_saddr_ip, reply.arp_saddr_mac]71report_host(:host => reply.arp_saddr_ip, :mac=>reply.arp_saddr_mac)72found[reply.arp_saddr_ip] = true73end74end75end7677etime = ::Time.now.to_f + datastore['TIMEOUT']7879while (::Time.now.to_f < etime)80while(reply = getreply())81next unless reply.is_arp?82if not found[reply.arp_saddr_ip]83print_good(sprintf(" %16s ALIVE",reply.arp_saddr_ip))84addrs << [reply.arp_saddr_ip, reply.arp_saddr_mac]85report_host(:host => reply.arp_saddr_ip, :mac=>reply.arp_saddr_mac)86found[reply.arp_saddr_ip] = true87end88end8990::IO.select(nil, nil, nil, 0.50)91end9293ensure94close_pcap()95end9697neighbor_discovery(addrs)98end99100def map_neighbor(nodes, adv)101nodes.each do |node|102ipv4_addr, mac_addr = node103next unless adv.eth_saddr == mac_addr104ipv6_addr = adv.ipv6_saddr105return {:eth => mac_addr, :ipv4 => ipv4_addr, :ipv6 => ipv6_addr}106end107nil108end109110def neighbor_discovery(neighs)111print_status("Discovering IPv6 addresses for IPv4 nodes...")112print_status("")113114smac = @smac115open_pcap({'SNAPLEN' => 68, 'FILTER' => "icmp6"})116117begin118neighs.each do |neigh|119host, dmac = neigh120121shost = ipv6_linklocaladdr(smac)122neigh = ipv6_linklocaladdr(dmac)123124probe = buildsolicitation(smac, shost, neigh)125126capture.inject(probe)127Kernel.select(nil,nil,nil,0.1)128129while(adv = getadvertisement())130next unless adv.is_ipv6?131132addr = map_neighbor(neighs, adv)133next if not addr134135print_status(sprintf(" %16s maps to %s",addr[:ipv4], addr[:ipv6]))136report_note(137:host => addr[:ipv4],138:type => 'host.ipv4.ipv6.mapping',139:data => "system with IPv4 address #{addr[:ipv4]} matches to IPv6 address #{addr[:ipv6]}"140) # with this we have the results in our database141142end143end144145etime = ::Time.now.to_f + (neighs.length * 0.5)146147while (::Time.now.to_f < etime)148while(adv = getadvertisement())149next if not adv150151addr = map_neighbor(neighs, adv)152next if not addr153154print_status(sprintf(" %16s maps to %s",addr[:ipv4], addr[:ipv6]))155end156::IO.select(nil, nil, nil, 0.50)157end158159ensure160close_pcap()161end162end163164def buildprobe(shost, smac, dhost)165p = PacketFu::ARPPacket.new166p.eth_saddr = smac167p.eth_daddr = "ff:ff:ff:ff:ff:ff"168p.arp_opcode = 1169p.arp_saddr_mac = p.eth_saddr170p.arp_daddr_mac = p.eth_daddr171p.arp_saddr_ip = shost172p.arp_daddr_ip = dhost173p.to_s174end175176def getreply177pkt = capture.next178Kernel.select(nil,nil,nil,0.1)179return if not pkt180p = PacketFu::Packet.parse(pkt)181return unless p.is_arp?182return unless p.arp_opcode == 2183p184end185186def buildsolicitation(smac, shost, neigh)187dmac = ipv6_soll_mcast_mac(neigh)188dhost = ipv6_soll_mcast_addr6(neigh)189190p = PacketFu::IPv6Packet.new191p.eth_saddr = smac192p.eth_daddr = dmac193p.ipv6_saddr = shost194p.ipv6_daddr = dhost195p.ipv6_next = 0x3a196p.ipv6_hop = 255197p.payload = ipv6_neighbor_solicitation(198IPAddr.new(neigh).to_i,199p.eth_src200)201p.ipv6_len = p.payload.size202ipv6_checksum!(p)203p.to_s204end205206def getadvertisement207pkt = capture.next208Kernel.select(nil,nil,nil,0.1)209return if not pkt210p = PacketFu::Packet.parse(pkt)211return unless p.is_ipv6?212return unless p.ipv6_next == 0x3a213return unless p.icmpv6_type == 136 && p.icmpv6_code == 0214p215end216end217218219