@@ -20,7 +20,7 @@ def initialize
20
20
This module provides a DNS service that redirects
21
21
all queries to a particular address.
22
22
} ,
23
- 'Author' => [ 'ddz' , 'hdm' ] ,
23
+ 'Author' => [ 'ddz' , 'hdm' , 'fozavci' ] ,
24
24
'License' => MSF_LICENSE ,
25
25
'Actions' =>
26
26
[
@@ -44,22 +44,27 @@ def initialize
44
44
45
45
register_advanced_options (
46
46
[
47
+ OptPort . new ( 'RR_SRV_PORT' , [ false , "The port field in the SRV response when FAKE" , 5060 ] ) ,
47
48
OptBool . new ( 'LogConsole' , [ false , "Determines whether to log all request to the console" , true ] ) ,
48
49
OptBool . new ( 'LogDatabase' , [ false , "Determines whether to log all request to the database" , false ] ) ,
49
50
] , self . class )
50
51
end
51
52
52
53
53
- def run
54
- @targ = datastore [ 'TARGETHOST' ]
55
- if ( @targ and @targ . strip . length == 0 )
56
- @targ = nil
57
- end
58
-
59
- if ( @targ )
60
- @targ = ::Rex ::Socket . resolv_to_dotted ( @targ )
54
+ def target_host ( addr = nil )
55
+ target = datastore [ 'TARGETHOST' ]
56
+ if target . blank?
57
+ if addr
58
+ ::Rex ::Socket . source_address ( addr )
59
+ else
60
+ nil
61
+ end
62
+ else
63
+ ::Rex ::Socket . resolv_to_dotted ( target )
61
64
end
65
+ end
62
66
67
+ def run
63
68
@port = datastore [ 'SRVPORT' ] . to_i
64
69
65
70
@log_console = false
@@ -90,10 +95,12 @@ def run
90
95
while @run
91
96
@error_resolving = false
92
97
packet , addr = @sock . recvfrom ( 65535 )
98
+ src_addr = addr [ 3 ]
93
99
@requestor = addr
94
- break if packet . length == 0
100
+ next if packet . length == 0
95
101
96
102
request = Resolv ::DNS ::Message . decode ( packet )
103
+ next unless request . qr == 0
97
104
98
105
#
99
106
# XXX: Track request IDs by requesting IP address and port
@@ -109,6 +116,18 @@ def run
109
116
lst = [ ]
110
117
111
118
request . each_question { |name , typeclass |
119
+ # Identify potential domain exceptions
120
+ @match_target = false
121
+ @match_name = name . to_s
122
+ @domain_target_list . each do |ex |
123
+ escaped = Regexp . escape ( ex ) . gsub ( '\*' , '.*?' )
124
+ regex = Regexp . new "^#{ escaped } $" , Regexp ::IGNORECASE
125
+ if ( name . to_s =~ regex )
126
+ @match_target = true
127
+ @match_name = ex
128
+ end
129
+ end
130
+
112
131
tc_s = typeclass . to_s ( ) . gsub ( /^Resolv::DNS::Resource::/ , "" )
113
132
114
133
request . qr = 1
@@ -130,25 +149,12 @@ def run
130
149
# <hostname> SOA -> windows XP self hostname lookup
131
150
#
132
151
133
- answer = Resolv ::DNS ::Resource ::IN ::A . new ( @targ || ::Rex ::Socket . source_address ( addr [ 3 ] . to_s ) )
134
-
135
- # Identify potential domain exceptions
136
- @match_target = false
137
- @match_name = name . to_s
138
- @domain_target_list . each do |ex |
139
- escaped = Regexp . escape ( ex ) . gsub ( '\*' , '.*?' )
140
- regex = Regexp . new "^#{ escaped } $" , Regexp ::IGNORECASE
141
- if ( name . to_s =~ regex )
142
- @match_target = true
143
- @match_name = ex
144
- end
145
- end
152
+ answer = Resolv ::DNS ::Resource ::IN ::A . new ( target_host ( src_addr ) )
146
153
147
154
if ( @match_target and not @bypass ) or ( not @match_target and @bypass )
148
155
# Resolve FAKE response
149
156
if ( @log_console )
150
- print_status ( "DNS target domain found: #{ @match_name } " )
151
- print_status ( "DNS target domain #{ name . to_s } faked" )
157
+ print_status ( "DNS target domain #{ @match_name } found; Returning fake A records for #{ name } " )
152
158
end
153
159
else
154
160
# Resolve the exception domain
@@ -160,8 +166,7 @@ def run
160
166
next
161
167
end
162
168
if ( @log_console )
163
- print_status ( "DNS bypass domain found: #{ @match_name } " )
164
- print_status ( "DNS bypass domain #{ name . to_s } resolved #{ ip } " )
169
+ print_status ( "DNS bypass domain #{ @match_name } found; Returning real A records for #{ name } " )
165
170
end
166
171
end
167
172
@@ -171,16 +176,54 @@ def run
171
176
when 'IN::MX'
172
177
mx = Resolv ::DNS ::Resource ::IN ::MX . new ( 10 , Resolv ::DNS ::Name . create ( "mail.#{ name } " ) )
173
178
ns = Resolv ::DNS ::Resource ::IN ::NS . new ( Resolv ::DNS ::Name . create ( "dns.#{ name } " ) )
174
- ar = Resolv ::DNS ::Resource ::IN ::A . new ( @targ || :: Rex :: Socket . source_address ( addr [ 3 ] . to_s ) )
179
+ ar = Resolv ::DNS ::Resource ::IN ::A . new ( target_host ( src_addr ) )
175
180
request . add_answer ( name , 60 , mx )
176
181
request . add_authority ( name , 60 , ns )
177
182
request . add_additional ( Resolv ::DNS ::Name . create ( "mail.#{ name } " ) , 60 , ar )
178
183
179
184
when 'IN::NS'
180
185
ns = Resolv ::DNS ::Resource ::IN ::NS . new ( Resolv ::DNS ::Name . create ( "dns.#{ name } " ) )
181
- ar = Resolv ::DNS ::Resource ::IN ::A . new ( @targ || :: Rex :: Socket . source_address ( addr [ 3 ] . to_s ) )
186
+ ar = Resolv ::DNS ::Resource ::IN ::A . new ( target_host ( src_addr ) )
182
187
request . add_answer ( name , 60 , ns )
183
188
request . add_additional ( name , 60 , ar )
189
+
190
+ when 'IN::SRV'
191
+ if @bypass || !@match_target
192
+ if @log_console
193
+ print_status ( "DNS bypass domain #{ @match_name } found; Returning real SRV records for #{ name } " )
194
+ end
195
+ # if we are in bypass mode or we are in fake mode but the target didn't match,
196
+ # just return the real response RRs
197
+ resources = Resolv ::DNS . new ( ) . getresources ( Resolv ::DNS ::Name . create ( name ) , Resolv ::DNS ::Resource ::IN ::SRV )
198
+ if resources . empty?
199
+ @error_resolving = true
200
+ print_error ( "Unable to resolve SRV record for #{ name } -- skipping" )
201
+ next
202
+ end
203
+ resources . each do |resource |
204
+ host = resource . target
205
+ port = resource . port . to_i
206
+ weight = resource . weight . to_i
207
+ priority = resource . priority . to_i
208
+ ttl = resource . ttl . to_i
209
+ request . add_answer (
210
+ name ,
211
+ ttl ,
212
+ Resolv ::DNS ::Resource ::IN ::SRV . new ( priority , weight , port , Resolv ::DNS ::Name . create ( host ) )
213
+ )
214
+ end
215
+ else
216
+ if @log_console
217
+ print_status ( "DNS target domain #{ @match_name } found; Returning fake SRV records for #{ name } " )
218
+ # Prepare the FAKE response
219
+ request . add_answer (
220
+ name ,
221
+ 10 ,
222
+ Resolv ::DNS ::Resource ::IN ::SRV . new ( 5 , 0 , datastore [ 'RR_SRV_PORT' ] , Resolv ::DNS ::Name . create ( name ) )
223
+ )
224
+ request . add_additional ( Resolv ::DNS ::Name . create ( name ) , 60 , Resolv ::DNS ::Resource ::IN ::A . new ( target_host ( src_addr ) ) )
225
+ end
226
+ end
184
227
when 'IN::PTR'
185
228
soa = Resolv ::DNS ::Resource ::IN ::SOA . new (
186
229
Resolv ::DNS ::Name . create ( "ns.internet.com" ) ,
0 commit comments