Path: blob/master/modules/auxiliary/scanner/kademlia/server_info.rb
19591 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::Report7include Msf::Auxiliary::UDPScanner8include Msf::Auxiliary::Kademlia910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Gather Kademlia Server Information',15'Description' => %q{16This module uses the Kademlia BOOTSTRAP and PING messages to identify17and extract information from Kademlia speaking UDP endpoints,18typically belonging to eMule/eDonkey/BitTorrent servers or other P2P19applications.20},21'Author' => 'Jon Hart <jon_hart[at]rapid7.com>',22'References' => [23# There are lots of academic papers on the protocol but they tend to lack usable24# protocol details. This is the best I've found25['URL', 'https://gbmaster.wordpress.com/2013/06/16/botnets-surrounding-us-sending-kademlia2_bootstrap_req-kademlia2_hello_req-and-their-strict-cousins/#more-125']26],27'License' => MSF_LICENSE,28'Actions' => [29['BOOTSTRAP', 'Description' => 'Use a Kademlia2 BOOTSTRAP'],30['PING', 'Description' => 'Use a Kademlia2 PING']31],32'DefaultAction' => 'BOOTSTRAP',33'Notes' => {34'Reliability' => UNKNOWN_RELIABILITY,35'Stability' => UNKNOWN_STABILITY,36'SideEffects' => UNKNOWN_SIDE_EFFECTS37}38)39)4041register_options(42[43Opt::RPORT(4672)44]45)46end4748def build_probe49@probe ||= case action.name50when 'BOOTSTRAP'51BootstrapRequest.new52when 'PING'53Ping.new54end55end5657def scanner_process(response, src_host, src_port)58return if response.blank?5960peer = "#{src_host}:#{src_port}"6162case action.name63when 'BOOTSTRAP'64if bootstrap_res = BootstrapResponse.from_data(response)65info = {66peer_id: bootstrap_res.peer_id,67tcp_port: bootstrap_res.tcp_port,68version: bootstrap_res.version,69peers: bootstrap_res.peers70}71print_good("#{peer} ID #{bootstrap_res.peer_id}, TCP port #{bootstrap_res.tcp_port}," +72" version #{bootstrap_res.version}, #{bootstrap_res.peers.size} peers")73end74when 'PING'75if pong = Pong.from_data(response)76print_good("#{peer} PONG port #{pong.port}")77# port should match the port we contacted it from. TODO: validate this?78info = { udp_port: pong.port }79end80end8182return unless info8384@results[src_host] ||= []85@results[src_host] << info86end8788def scanner_postscan(_batch)89@results.each_pair do |host, info|90report_host(host: host)91report_service(92host: host,93proto: 'udp',94port: rport,95name: 'kademlia',96info: info97)98end99end100end101102103