Skip to content

Commit 9ccb939

Browse files
committed
Land rapid7#3264, throttl and csv output support for module
2 parents 15bd92d + e2b92a8 commit 9ccb939

File tree

1 file changed

+43
-6
lines changed

1 file changed

+43
-6
lines changed

modules/auxiliary/gather/dns_reverse_lookup.rb

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,32 @@ class Metasploit3 < Msf::Auxiliary
1212

1313
def initialize(info = {})
1414
super(update_info(info,
15-
'Name' => 'DNS Reverse Lookup Enumeration',
16-
'Description' => %q{
15+
'Name' => 'DNS Reverse Lookup Enumeration',
16+
'Description' => %q{
1717
This module performs DNS reverse lookup against a given IP range in order to
1818
retrieve valid addresses and names.
1919
},
20-
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ],
21-
'License' => BSD_LICENSE
20+
'Author' =>
21+
[
22+
'Carlos Perez <carlos_perez[at]darkoperator.com>', # Base code
23+
'Thanat0s <thanspam[at]trollprod[dot]org>' # Output, Throttling & Db notes add
24+
],
25+
'License' => BSD_LICENSE
2226
))
2327

2428
register_options(
2529
[
2630
OptAddressRange.new('RANGE', [true, 'IP range to perform reverse lookup against.']),
27-
OptAddress.new('NS', [ false, "Specify the nameserver to use for queries, otherwise use the system DNS." ])
31+
OptAddress.new('NS', [ false, "Specify the nameserver to use for queries, otherwise use the system DNS." ]),
32+
OptString.new('OUT_FILE', [ false, "Specify a CSV output file" ])
2833
], self.class)
2934

3035
register_advanced_options(
3136
[
3237
OptInt.new('RETRY', [ false, "Number of tries to resolve a record if no response is received.", 2]),
3338
OptInt.new('RETRY_INTERVAL', [ false, "Number of seconds to wait before doing a retry.", 2]),
34-
OptInt.new('THREADS', [ true, "The number of concurrent threads.", 1])
39+
OptInt.new('THREADS', [ true, "The number of concurrent threads.", 1]),
40+
OptInt.new('THROTTLE', [ false, "Specify the resolution throttle in query per sec. 0 means unthrottled",0 ])
3541
], self.class)
3642
end
3743

@@ -55,20 +61,51 @@ def reverselkp(iprange)
5561
print_status("Running reverse lookup against IP range #{iprange}")
5662
ar = Rex::Socket::RangeWalker.new(iprange)
5763
tl = []
64+
# Basic Throttling
65+
sleep_time = 0.0
66+
if (datastore['THROTTLE'] != 0)
67+
sleep_time = (1.0/datastore['THROTTLE'])*datastore['THREADS']
68+
print_status("Throttle set to #{datastore['THROTTLE']} queries per seconds")
69+
end
70+
# Output..
71+
if datastore['OUT_FILE']
72+
print_status("Scan result saved in #{datastore['OUT_FILE']}")
73+
open(datastore['OUT_FILE'], 'w') do |f|
74+
f.puts "; IP, Host"
75+
end
76+
end
5877
while (true)
5978
# Spawn threads for each host
79+
hosts = Hash.new
6080
while (tl.length <= @threadnum)
6181
ip = ar.next_ip
6282
break if not ip
6383
tl << framework.threads.spawn("Module(#{self.refname})-#{ip}", false, ip.dup) do |tip|
6484
begin
85+
Rex.sleep(sleep_time)
6586
query = @res.query(tip)
6687
query.each_ptr do |addresstp|
6788
print_status("Host Name: #{addresstp}, IP Address: #{tip.to_s}")
89+
if datastore['OUT_FILE']
90+
open(datastore['OUT_FILE'], 'a') do |f|
91+
f.puts "#{tip.to_s},#{addresstp}"
92+
end
93+
end
6894
report_host(
6995
:host => tip.to_s,
7096
:name => addresstp
7197
)
98+
if !hosts[tip]
99+
hosts[tip] = Array.new
100+
end
101+
hosts[tip].push addresstp
102+
end
103+
unless hosts[tip].nil? or hosts[tip].empty?
104+
report_note(
105+
:host => tip.to_s,
106+
:type => "RDNS_Record",
107+
:data => hosts[tip]
108+
)
72109
end
73110
rescue ::Interrupt
74111
raise $!

0 commit comments

Comments
 (0)