Skip to content

Commit 893a6ef

Browse files
committed
add censys search module
1 parent 05ffa00 commit 893a6ef

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
7+
require 'msf/core'
8+
require 'rex/proto/http'
9+
10+
class MetasploitModule < Msf::Auxiliary
11+
12+
def initialize(info={})
13+
super(update_info(info,
14+
'Name' => 'Censys Search',
15+
'Description' => %q{
16+
The module use the Censys REST API to access the same data
17+
accessible through web interface. The search endpoint allows searches
18+
against the current data in the IPv4, Top Million Websites, and
19+
Certificates indexes using the same search syntax as the primary site.
20+
},
21+
'Author' => [ 'Nixawk' ],
22+
'References' => [
23+
['URL', 'https://censys.io/api']
24+
],
25+
'License' => MSF_LICENSE
26+
))
27+
28+
register_options([
29+
OptString.new('CENSYS_UID', [true, 'The Censys API UID']),
30+
OptString.new('CENSYS_SECRET', [true, 'The Censys API SECRET']),
31+
OptString.new('CENSYS_DORK', [true, 'The Censys Search Dork']),
32+
OptEnum.new('CENSYS_SEARCHTYPE', [true, 'The Censys Search Type', 'certificates', ['certificates', 'ipv4', 'websites']])
33+
], self.class)
34+
end
35+
36+
def basic_auth_header(username, password)
37+
auth_str = username.to_s + ":" + password.to_s
38+
auth_str = "Basic " + Rex::Text.encode_base64(auth_str)
39+
end
40+
41+
def search(keyword, search_type)
42+
@uri = "https://www.censys.io/api/v1"
43+
# search_type should be one of ipv4, websites, certificates
44+
45+
begin
46+
# "80.http.get.headers.server: Apache"
47+
payload = {
48+
'query' => keyword
49+
}
50+
51+
@cli = Rex::Proto::Http::Client.new('www.censys.io', 443, {}, true)
52+
@cli.connect
53+
54+
response = @cli.request_cgi(
55+
'method' => 'post',
56+
'uri' => "/api/v1/search/#{search_type}",
57+
'headers' => { 'Authorization' => basic_auth_header(@uid, @secret) },
58+
'data' => payload.to_json
59+
)
60+
61+
res = @cli.send_recv(response)
62+
63+
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
64+
print_error("HTTP Connection Failed")
65+
end
66+
67+
unless res
68+
print_error('server_response_error')
69+
return
70+
end
71+
72+
records = ActiveSupport::JSON.decode(res.body)
73+
results = records['results']
74+
75+
if @searchtype.include?('certificates')
76+
parse_certificates(results)
77+
elsif @searchtype.include?('ipv4')
78+
parse_ipv4(results)
79+
elsif @searchtype.include?('websites')
80+
parse_websites(results)
81+
end
82+
end
83+
84+
def parse_certificates(records)
85+
records.each do |certificate|
86+
# parsed.fingerprint_sha256
87+
# parsed.subject_dn
88+
# parsed.issuer_dn
89+
print_status(certificate['parsed.fingerprint_sha256'].join(','))
90+
print_status(certificate['parsed.subject_dn'].join(','))
91+
print_status(certificate['parsed.issuer_dn'].join(','))
92+
end
93+
end
94+
95+
def parse_ipv4(records)
96+
records.each do |ipv4|
97+
# ip
98+
# protocols
99+
print_status("#{ipv4['ip']} - #{ipv4['protocols'].join(',')}")
100+
end
101+
end
102+
103+
def parse_websites(records)
104+
records.each do |website|
105+
# domain
106+
# alexa_rank
107+
print_status("#{website['domain']} - #{website['alexa_rank']}")
108+
end
109+
end
110+
111+
# Check to see if www.censys.io resolves properly
112+
def censys_resolvable?
113+
begin
114+
Rex::Socket.resolv_to_dotted("www.censys.io")
115+
rescue RuntimeError, SocketError
116+
return false
117+
end
118+
true
119+
end
120+
121+
def run
122+
# check to ensure www.censys.io is resolvable
123+
unless censys_resolvable?
124+
print_error("Unable to resolve www.censys.io")
125+
return
126+
end
127+
128+
@uid = datastore['CENSYS_UID']
129+
@secret = datastore['CENSYS_SECRET']
130+
@dork = datastore['CENSYS_DORK']
131+
@searchtype = datastore['CENSYS_SEARCHTYPE']
132+
search(@dork, @searchtype)
133+
end
134+
end

0 commit comments

Comments
 (0)