Skip to content

Commit f0f3b65

Browse files
committed
Merge branch 'master' of github.com:rapid7/metasploit-framework into rapid7
2 parents aea76a5 + a19da61 commit f0f3b65

File tree

6 files changed

+696
-5
lines changed

6 files changed

+696
-5
lines changed

modules/auxiliary/admin/http/rails_devise_pass_reset.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ def initialize(info = {})
2727
2828
Affects Devise < v2.2.3, 2.1.3, 2.0.5 and 1.5.4 when backed by any database
2929
except PostgreSQL or SQLite3. Tested with v2.2.2, 2.1.2, and 2.0.4 on Rails
30-
3.2.11. Patch applied to Rails 3.2.12 should prevent exploitation of this
31-
vulnerability, by quoting numeric values when comparing them with non numeric
32-
values.
30+
3.2.11. Patch applied to Rails 3.2.12 and 3.1.11 should prevent exploitation
31+
of this vulnerability, by quoting numeric values when comparing them with
32+
non numeric values.
3333
},
3434
'Author' =>
3535
[
@@ -44,7 +44,8 @@ def initialize(info = {})
4444
[ 'BID', '57577' ],
4545
[ 'URL', 'http://blog.plataformatec.com.br/2013/01/security-announcement-devise-v2-2-3-v2-1-3-v2-0-5-and-v1-5-3-released/'],
4646
[ 'URL', 'http://www.phenoelit.org/blog/archives/2013/02/05/mysql_madness_and_rails/index.html'],
47-
[ 'URL', 'https://github.com/rails/rails/commit/921a296a3390192a71abeec6d9a035cc6d1865c8' ]
47+
[ 'URL', 'https://github.com/rails/rails/commit/921a296a3390192a71abeec6d9a035cc6d1865c8' ],
48+
[ 'URL', 'https://github.com/rails/rails/commit/26e13c3ca71cbc7859cc4c51e64f3981865985d8']
4849
],
4950
'DisclosureDate' => 'Jan 28 2013'
5051
))
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
##
2+
# ## This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
require "net/dns/resolver"
10+
require 'rex'
11+
12+
class Metasploit3 < Msf::Auxiliary
13+
include Msf::Auxiliary::Report
14+
15+
def initialize(info = {})
16+
super(update_info(info,
17+
'Name' => 'DNS Brutefoce Enumeration',
18+
'Description' => %q{
19+
This module uses a dictionary to perform a bruteforce attack to enumerate
20+
hostnames and subdomains available under a given domain.
21+
},
22+
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ],
23+
'License' => BSD_LICENSE
24+
))
25+
26+
register_options(
27+
[
28+
OptString.new('DOMAIN', [ true, "The target domain name"]),
29+
OptAddress.new('NS', [ false, "Specify the name server to use for queries, otherwise use the system DNS" ]),
30+
OptPath.new('WORDLIST', [ true, "Wordlist file for domain name brute force.",
31+
File.join(Msf::Config.install_root, "data", "wordlists", "namelist.txt")])
32+
], self.class)
33+
34+
register_advanced_options(
35+
[
36+
OptInt.new('RETRY', [ false, "Number of tries to resolve a record if no response is received.", 2]),
37+
OptInt.new('RETRY_INTERVAL', [ false, "Number of seconds to wait before doing a retry.", 2]),
38+
OptInt.new('THREADS', [ true, "Number of threads", 1])
39+
], self.class)
40+
end
41+
42+
def run
43+
print_status("Enumerating #{datastore['DOMAIN']}")
44+
@res = Net::DNS::Resolver.new()
45+
@res.retry = datastore['RETRY'].to_i unless datastore['RETRY'].nil?
46+
@res.retry_interval = datastore['RETRY_INTERVAL'].to_i unless datastore['RETRY_INTERVAL'].nil?
47+
wildcard(datastore['DOMAIN'])
48+
switchdns() unless datastore['NS'].nil?
49+
dnsbrt(datastore['DOMAIN'])
50+
end
51+
52+
def wildcard(target)
53+
rendsub = rand(10000).to_s
54+
query = @res.query("#{rendsub}.#{target}", "A")
55+
if query.answer.length != 0
56+
print_status("This Domain has wild-cards enabled!!")
57+
query.answer.each do |rr|
58+
print_warning("Wild-card IP for #{rendsub}.#{target} is: #{rr.address.to_s}") if rr.class != Net::DNS::RR::CNAME
59+
end
60+
return true
61+
else
62+
return false
63+
end
64+
end
65+
66+
def get_ip(host)
67+
results = []
68+
query = @res.search(host, "A")
69+
if (query)
70+
query.answer.each do |rr|
71+
if rr.type == "CNAME"
72+
results = results + get_ip(rr.cname)
73+
else
74+
record = {}
75+
record[:host] = host
76+
record[:type] = "AAAA"
77+
record[:address] = rr.address.to_s
78+
results << record
79+
end
80+
end
81+
end
82+
query1 = @res.search(host, "AAAA")
83+
if (query1)
84+
query1.answer.each do |rr|
85+
if rr.type == "CNAME"
86+
results = results + get_ip(rr.cname)
87+
else
88+
record = {}
89+
record[:host] = host
90+
record[:type] = "AAAA"
91+
record[:address] = rr.address.to_s
92+
results << record
93+
end
94+
end
95+
end
96+
return results
97+
end
98+
99+
def switchdns()
100+
print_status("Using DNS server: #{datastore['NS']}")
101+
@res.nameserver=(datastore['NS'])
102+
@nsinuse = datastore['NS']
103+
end
104+
105+
def dnsbrt(domain)
106+
print_status("Performing bruteforce against #{domain}")
107+
queue = []
108+
File.open(datastore['WORDLIST'], 'rb').each_line do |testd|
109+
queue << testd.strip
110+
end
111+
while(not queue.empty?)
112+
tl = []
113+
1.upto(datastore['THREADS']) do
114+
tl << framework.threads.spawn("Module(#{self.refname})-#{domain}", false, queue.shift) do |testf|
115+
Thread.current.kill if not testf
116+
vprint_status("Testing #{testf}.#{domain}")
117+
get_ip("#{testf}.#{domain}").each do |i|
118+
print_good("Host #{i[:host]} with address #{i[:address]} found")
119+
report_host(
120+
:host => i[:address].to_s,
121+
:name => i[:host].gsub(/\.$/,'')
122+
)
123+
end
124+
end
125+
end
126+
if(tl.length == 0)
127+
break
128+
end
129+
tl.first.join
130+
tl.delete_if { |t| not t.alive? }
131+
end
132+
end
133+
end
134+

modules/auxiliary/gather/dns_info.rb

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
##
2+
# ## This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
require "net/dns/resolver"
10+
require 'rex'
11+
12+
class Metasploit3 < Msf::Auxiliary
13+
include Msf::Auxiliary::Report
14+
15+
def initialize(info = {})
16+
super(update_info(info,
17+
'Name' => 'DNS Basic Information Enumeration',
18+
'Description' => %q{
19+
This module enumerates basic DNS information for a given domain. The module
20+
gets information regarding to A (addresses), AAAA (IPv6 addresses), NS (name
21+
servers), SOA (start of authority) and MX (mail servers) records for a given
22+
domain. In addition, this module retrieves information stored in TXT records.
23+
},
24+
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ],
25+
'License' => BSD_LICENSE
26+
))
27+
28+
register_options(
29+
[
30+
OptString.new('DOMAIN', [ true, "The target domain name"]),
31+
OptAddress.new('NS', [ false, "Specify the name server to use for queries, otherwise use the system configured DNS Server is used." ]),
32+
33+
], self.class)
34+
35+
register_advanced_options(
36+
[
37+
OptInt.new('RETRY', [ false, "Number of tries to resolve a record if no response is received.", 2]),
38+
OptInt.new('RETRY_INTERVAL', [ false, "Number of seconds to wait before doing a retry.", 2]),
39+
], self.class)
40+
end
41+
42+
def run
43+
print_status("Enumerating #{datastore['DOMAIN']}")
44+
@res = Net::DNS::Resolver.new()
45+
46+
if datastore['RETRY']
47+
@res.retry = datastore['RETRY'].to_i
48+
end
49+
50+
if datastore['RETRY_INTERVAL']
51+
@res.retry_interval = datastore['RETRY_INTERVAL'].to_i
52+
end
53+
54+
wildcard(datastore['DOMAIN'])
55+
switchdns() unless datastore['NS'].nil? or datastore['NS'].empty?
56+
57+
get_ip(datastore['DOMAIN']).each do |r|
58+
print_good("#{r[:host]} - Address #{r[:address]} found. Record type: #{r[:type]}")
59+
report_host(:host => r[:address])
60+
end
61+
62+
get_ns(datastore['DOMAIN']).each do |r|
63+
print_good("#{datastore['DOMAIN']} - Name server #{r[:host]} (#{r[:address]}) found. Record type: #{r[:type]}")
64+
report_host(:host => r[:address], :name => r[:host])
65+
report_service(
66+
:host => r[:address],
67+
:name => "dns",
68+
:port => 53,
69+
:proto => "udp"
70+
)
71+
end
72+
73+
get_soa(datastore['DOMAIN']).each do |r|
74+
print_good("#{datastore['DOMAIN']} - #{r[:host]} (#{r[:address]}) found. Record type: #{r[:type]}")
75+
report_host(:host => r[:address], :name => r[:host])
76+
end
77+
78+
get_mx(datastore['DOMAIN']).each do |r|
79+
print_good("#{datastore['DOMAIN']} - Mail server #{r[:host]} (#{r[:address]}) found. Record type: #{r[:type]}")
80+
report_host(:host => r[:address], :name => r[:host])
81+
report_service(
82+
:host => r[:address],
83+
:name => "smtp",
84+
:port => 25,
85+
:proto => "tcp"
86+
)
87+
end
88+
89+
get_txt(datastore['DOMAIN']).each do |r|
90+
print_good("#{datastore['DOMAIN']} - Text info found: #{r[:text]}. Record type: #{r[:type]}")
91+
report_note(
92+
:host => datastore['DOMAIN'],
93+
:proto => 'udp',
94+
:port => 53,
95+
:type => 'dns.info',
96+
:data => {:text => r[:text]}
97+
)
98+
end
99+
end
100+
101+
def wildcard(target)
102+
rendsub = rand(10000).to_s
103+
query = @res.query("#{rendsub}.#{target}", "A")
104+
if query.answer.length != 0
105+
print_status("This Domain has Wild-cards Enabled!!")
106+
query.answer.each do |rr|
107+
print_status("Wild-card IP for #{rendsub}.#{target} is: #{rr.address.to_s}") if rr.class != Net::DNS::RR::CNAME
108+
report_note(
109+
:host => datastore['DOMAIN'],
110+
:proto => 'UDP',
111+
:port => 53,
112+
:type => 'dns.wildcard',
113+
:data => "Wildcard IP for #{rendsub}.#{target} is: #{rr.address.to_s}"
114+
)
115+
end
116+
return true
117+
else
118+
return false
119+
end
120+
end
121+
122+
def get_ip(host)
123+
results = []
124+
query = @res.search(host, "A")
125+
if query
126+
query.answer.each do |rr|
127+
record = {}
128+
record[:host] = host
129+
record[:type] = "A"
130+
record[:address] = rr.address.to_s
131+
results << record
132+
end
133+
end
134+
query1 = @res.search(host, "AAAA")
135+
if query1
136+
query1.answer.each do |rr|
137+
record = {}
138+
record[:host] = host
139+
record[:type] = "AAAA"
140+
record[:address] = rr.address.to_s
141+
results << record
142+
end
143+
end
144+
return results
145+
end
146+
147+
def get_ns(target)
148+
results = []
149+
query = @res.query(target, "NS")
150+
return results if not query
151+
(query.answer.select { |i| i.class == Net::DNS::RR::NS}).each do |rr|
152+
get_ip(rr.nsdname).each do |r|
153+
record = {}
154+
record[:host] = rr.nsdname.gsub(/\.$/,'')
155+
record[:type] = "NS"
156+
record[:address] = r[:address].to_s
157+
results << record
158+
end
159+
end
160+
return results
161+
end
162+
163+
def get_soa(target)
164+
results = []
165+
query = @res.query(target, "SOA")
166+
return results if not query
167+
(query.answer.select { |i| i.class == Net::DNS::RR::SOA}).each do |rr|
168+
if Rex::Socket.dotted_ip?(rr.mname)
169+
record = {}
170+
record[:host] = rr.mname
171+
record[:type] = "SOA"
172+
record[:address] = rr.mname
173+
results << record
174+
else
175+
get_ip(rr.mname).each do |ip|
176+
record = {}
177+
record[:host] = rr.mname.gsub(/\.$/,'')
178+
record[:type] = "SOA"
179+
record[:address] = ip[:address].to_s
180+
results << record
181+
end
182+
end
183+
end
184+
return results
185+
end
186+
187+
def get_txt(target)
188+
results = []
189+
query = @res.query(target, "TXT")
190+
return results if not query
191+
query.answer.each do |rr|
192+
record = {}
193+
record[:host] = target
194+
record[:text] = rr.txt
195+
record[:type] = "TXT"
196+
results << record
197+
end
198+
return results
199+
end
200+
201+
def get_mx(target)
202+
results = []
203+
query = @res.query(target, "MX")
204+
return results if not query
205+
(query.answer.select { |i| i.class == Net::DNS::RR::MX}).each do |rr|
206+
if Rex::Socket.dotted_ip?(rr.exchange)
207+
record = {}
208+
record[:host] = rr.exchange
209+
record[:type] = "MX"
210+
record[:address] = rr.exchange
211+
results << record
212+
else
213+
get_ip(rr.exchange).each do |ip|
214+
record = {}
215+
record[:host] = rr.exchange.gsub(/\.$/,'')
216+
record[:type] = "MX"
217+
record[:address] = ip[:address].to_s
218+
results << record
219+
end
220+
end
221+
end
222+
return results
223+
end
224+
225+
def switchdns()
226+
print_status("Using DNS server: #{datastore['NS']}")
227+
@res.nameserver=(datastore['NS'])
228+
@nsinuse = datastore['NS']
229+
end
230+
end
231+

0 commit comments

Comments
 (0)