CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/kademlia/server_info.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Auxiliary::Report
8
include Msf::Auxiliary::UDPScanner
9
include Msf::Auxiliary::Kademlia
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Gather Kademlia Server Information',
16
'Description' => %q(
17
This module uses the Kademlia BOOTSTRAP and PING messages to identify
18
and extract information from Kademlia speaking UDP endpoints,
19
typically belonging to eMule/eDonkey/BitTorrent servers or other P2P
20
applications.
21
),
22
'Author' => 'Jon Hart <jon_hart[at]rapid7.com>',
23
'References' =>
24
[
25
# There are lots of academic papers on the protocol but they tend to lack usable
26
# protocol details. This is the best I've found
27
['URL', 'https://gbmaster.wordpress.com/2013/06/16/botnets-surrounding-us-sending-kademlia2_bootstrap_req-kademlia2_hello_req-and-their-strict-cousins/#more-125']
28
],
29
'License' => MSF_LICENSE,
30
'Actions' => [
31
['BOOTSTRAP', 'Description' => 'Use a Kademlia2 BOOTSTRAP'],
32
['PING', 'Description' => 'Use a Kademlia2 PING']
33
],
34
'DefaultAction' => 'BOOTSTRAP'
35
)
36
)
37
38
register_options(
39
[
40
Opt::RPORT(4672)
41
])
42
end
43
44
def build_probe
45
@probe ||= case action.name
46
when 'BOOTSTRAP'
47
BootstrapRequest.new
48
when 'PING'
49
Ping.new
50
end
51
end
52
53
def scanner_process(response, src_host, src_port)
54
return if response.blank?
55
peer = "#{src_host}:#{src_port}"
56
57
case action.name
58
when 'BOOTSTRAP'
59
if bootstrap_res = BootstrapResponse.from_data(response)
60
info = {
61
peer_id: bootstrap_res.peer_id,
62
tcp_port: bootstrap_res.tcp_port,
63
version: bootstrap_res.version,
64
peers: bootstrap_res.peers
65
}
66
print_good("#{peer} ID #{bootstrap_res.peer_id}, TCP port #{bootstrap_res.tcp_port}," +
67
" version #{bootstrap_res.version}, #{bootstrap_res.peers.size} peers")
68
end
69
when 'PING'
70
if pong = Pong.from_data(response)
71
print_good("#{peer} PONG port #{pong.port}")
72
# port should match the port we contacted it from. TODO: validate this?
73
info = { udp_port: pong.port }
74
end
75
end
76
77
return unless info
78
@results[src_host] ||= []
79
@results[src_host] << info
80
end
81
82
def scanner_postscan(_batch)
83
@results.each_pair do |host, info|
84
report_host(host: host)
85
report_service(
86
host: host,
87
proto: 'udp',
88
port: rport,
89
name: 'kademlia',
90
info: info
91
)
92
end
93
end
94
end
95
96