Skip to content

Commit 3630388

Browse files
committed
zoomeye search
1 parent 260257a commit 3630388

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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'
9+
require 'net/https'
10+
require 'uri'
11+
12+
13+
class MetasploitModule < Msf::Auxiliary
14+
15+
include Msf::Exploit::Remote::HttpClient
16+
include Msf::Auxiliary::Report
17+
18+
def initialize(info={})
19+
super(update_info(info,
20+
'Name' => 'ZoomEye Search',
21+
'Description' => %q{
22+
The module use the ZoomEye API to search ZoomEye. ZoomEye is a search
23+
engine for cyberspace that lets the user find specific network
24+
components(ip, services, etc.). Site: https://www.zoomeye.org/api/doc
25+
},
26+
'Author' => [ 'Nixawk' ],
27+
'License' => MSF_LICENSE
28+
))
29+
30+
deregister_options('RHOST', 'DOMAIN', 'DigestAuthIIS', 'NTLM::SendLM',
31+
'NTLM::SendNTLM', 'VHOST', 'RPORT', 'NTLM::SendSPN', 'NTLM::UseLMKey',
32+
'NTLM::UseNTLM2_session', 'NTLM::UseNTLMv2', 'SSL')
33+
34+
register_options(
35+
[
36+
OptString.new('ZOOMEYE_APIKEY', [true, 'The ZoomEye API Key']),
37+
OptString.new('ZOOMEYE_DORK', [true, 'The ZoomEye Dock']),
38+
OptEnum.new('RESOURCE', [true, 'ZoomEye Resource Type', 'host', ['host', 'web']]),
39+
OptInt.new('MAXPAGE', [true, 'Max amount of pages to collect', 1])
40+
], self.class)
41+
end
42+
43+
def dork_search(dork, resource, page, facet=['ip'])
44+
# param: dork
45+
# ex: country:cn
46+
# access https://www.zoomeye.org/search/dorks for more details.
47+
# param: page
48+
# total page(s) number
49+
# param: resource
50+
# set a search resource type, ex: [web, host]
51+
# param: facet
52+
# ex: [app, device]
53+
# A comma-separated list of properties to get summary information
54+
55+
zoomeye_dork_api = "https://api.zoomeye.org/#{resource}/search"
56+
zoomeye_dork_api << "?query=" + Rex::Text.uri_encode(dork)
57+
zoomeye_dork_api << "&page=#{page}"
58+
zoomeye_dork_api << "&facet=facet"
59+
60+
uri = URI.parse(zoomeye_dork_api)
61+
http = Net::HTTP.new(uri.host, uri.port)
62+
http.use_ssl = true
63+
request = Net::HTTP::Get.new(uri.request_uri)
64+
request['Authorization'] = "JWT #{datastore['ZOOMEYE_APIKEY']}"
65+
66+
res = http.request(request)
67+
return 'server_response_error' unless res
68+
69+
# Invalid Token, Not enough segments
70+
# Invalid Token, Signature has expired
71+
if res.body =~ /Invalid Token, /
72+
fail_with(Failure::BadConfig, '401 Unauthorized. Your ZOOMEYE_APIKEY is invalid')
73+
end
74+
75+
ActiveSupport::JSON.decode(res.body)
76+
77+
end
78+
79+
def match_records?(records)
80+
records && records.key?('matches') ? true : false
81+
end
82+
83+
def parse_host_records(records)
84+
records.each do |match|
85+
host = match['ip']
86+
port = match['portinfo']['port']
87+
88+
report_service(:host => host, :port => port)
89+
print_good("Host: #{host} ,PORT: #{port}")
90+
end
91+
end
92+
93+
def parse_web_records(records)
94+
records.each do |match|
95+
host = match['ip'][0]
96+
domains = match['domains']
97+
98+
report_host(:host => host)
99+
print_good("Host: #{host}, Domains: #{domains}")
100+
end
101+
end
102+
103+
def run
104+
dork = datastore['ZOOMEYE_DORK']
105+
resource = datastore['RESOURCE']
106+
page = 1
107+
maxpage = datastore['MAXPAGE']
108+
109+
while page <= maxpage
110+
break if page > maxpage
111+
print_status("ZoomEye #{resource} Search: #{dork} - page: #{page}")
112+
results = dork_search(dork, resource, page) if dork
113+
break unless match_records?(results)
114+
115+
matches = results['matches']
116+
if resource.include?('web')
117+
parse_web_records(matches)
118+
else
119+
parse_host_records(matches)
120+
end
121+
page += 1
122+
end
123+
end
124+
end

0 commit comments

Comments
 (0)