@@ -12,26 +12,29 @@ class Metasploit3 < Msf::Auxiliary
12
12
13
13
def initialize ( info = { } )
14
14
super ( update_info ( info ,
15
- 'Name' => 'DNS Reverse Lookup Enumeration' ,
16
- 'Description' => %q{
15
+ 'Name' => 'DNS Reverse Lookup Enumeration' ,
16
+ 'Description' => %q{
17
17
This module performs DNS reverse lookup against a given IP range in order to
18
18
retrieve valid addresses and names.
19
19
} ,
20
- 'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ] ,
21
- 'License' => BSD_LICENSE
20
+ 'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' , # Base code
21
+ 'Thanat0s <thanatos[at]trollprod[dot]org>' ] , # Output, Throttling & Db notes add
22
+ 'License' => BSD_LICENSE
22
23
) )
23
24
24
25
register_options (
25
26
[
26
27
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." ] )
28
+ OptAddress . new ( 'NS' , [ false , "Specify the nameserver to use for queries, otherwise use the system DNS." ] ) ,
29
+ OptString . new ( 'OUT_FILE' , [ false , "Specify a CSV output file" ] )
28
30
] , self . class )
29
31
30
32
register_advanced_options (
31
33
[
32
34
OptInt . new ( 'RETRY' , [ false , "Number of tries to resolve a record if no response is received." , 2 ] ) ,
33
35
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 ] )
36
+ OptInt . new ( 'THREADS' , [ true , "The number of concurrent threads." , 1 ] ) ,
37
+ OptInt . new ( 'THROTTLE' , [ false , "Specify the resolution throttle in query per sec. 0 means unthrottled" , 0 ] )
35
38
] , self . class )
36
39
end
37
40
@@ -55,21 +58,50 @@ def reverselkp(iprange)
55
58
print_status ( "Running reverse lookup against IP range #{ iprange } " )
56
59
ar = Rex ::Socket ::RangeWalker . new ( iprange )
57
60
tl = [ ]
61
+ # Basic Throttling
62
+ sleep_time = 0.0
63
+ if ( datastore [ 'THROTTLE' ] != 0 )
64
+ sleep_time = ( 1.0 /datastore [ 'THROTTLE' ] ) /datastore [ 'THREADS' ]
65
+ print_status ( "Throttle set to #{ datastore [ 'THROTTLE' ] } queries per seconds" )
66
+ end
67
+ # Output..
68
+ if datastore [ 'OUT_FILE' ]
69
+ print_status ( "Scan result saved in #{ datastore [ 'OUT_FILE' ] } " )
70
+ open ( datastore [ 'OUT_FILE' ] , 'w' ) do |f |
71
+ f . puts "; IP, Host"
72
+ end
73
+ end
58
74
while ( true )
59
75
# Spawn threads for each host
60
76
while ( tl . length <= @threadnum )
61
77
ip = ar . next_ip
78
+ hosts = Array . new
62
79
break if not ip
63
80
tl << framework . threads . spawn ( "Module(#{ self . refname } )-#{ ip } " , false , ip . dup ) do |tip |
64
81
begin
82
+ sleep ( sleep_time )
65
83
query = @res . query ( tip )
66
84
query . each_ptr do |addresstp |
67
- print_status ( "Host Name: #{ addresstp } , IP Address: #{ tip . to_s } " )
85
+ print_status ( "#Host Name: #{ addresstp } , IP Address: #{ tip . to_s } " )
86
+ if datastore [ 'OUT_FILE' ]
87
+ open ( datastore [ 'OUT_FILE' ] , 'a' ) do |f |
88
+ f . puts "#{ tip . to_s } ,#{ addresstp } "
89
+ end
90
+ end
68
91
report_host (
69
92
:host => tip . to_s ,
70
93
:name => addresstp
71
94
)
95
+ hosts . push addresstp
96
+ end
97
+ if !hosts . empty?
98
+ report_note (
99
+ :host => tip . to_s ,
100
+ :type => "RDNS_Record" ,
101
+ :data => hosts
102
+ )
72
103
end
104
+ hosts = Array . new
73
105
rescue ::Interrupt
74
106
raise $!
75
107
rescue ::Rex ::ConnectionError
0 commit comments