Check for API access and /wp-json/'s users output
This commit is contained in:
@@ -304,3 +304,11 @@ end
|
||||
def url_encode(str)
|
||||
CGI.escape(str).gsub("+", "%20")
|
||||
end
|
||||
|
||||
# Check valid JSON?
|
||||
def valid_json?(json)
|
||||
JSON.parse(json)
|
||||
return true
|
||||
rescue JSON::ParserError => e
|
||||
return false
|
||||
end
|
||||
@@ -1,22 +1,24 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
require 'web_site'
|
||||
require 'wp_target/wp_readme'
|
||||
require 'wp_target/wp_registrable'
|
||||
require 'wp_target/wp_api'
|
||||
require 'wp_target/wp_config_backup'
|
||||
require 'wp_target/wp_must_use_plugins'
|
||||
require 'wp_target/wp_login_protection'
|
||||
require 'wp_target/wp_custom_directories'
|
||||
require 'wp_target/wp_full_path_disclosure'
|
||||
require 'wp_target/wp_login_protection'
|
||||
require 'wp_target/wp_must_use_plugins'
|
||||
require 'wp_target/wp_readme'
|
||||
require 'wp_target/wp_registrable'
|
||||
|
||||
class WpTarget < WebSite
|
||||
include WpTarget::WpReadme
|
||||
include WpTarget::WpRegistrable
|
||||
include WpTarget::WpAPI
|
||||
include WpTarget::WpConfigBackup
|
||||
include WpTarget::WpMustUsePlugins
|
||||
include WpTarget::WpLoginProtection
|
||||
include WpTarget::WpCustomDirectories
|
||||
include WpTarget::WpFullPathDisclosure
|
||||
include WpTarget::WpLoginProtection
|
||||
include WpTarget::WpMustUsePlugins
|
||||
include WpTarget::WpReadme
|
||||
include WpTarget::WpRegistrable
|
||||
|
||||
attr_reader :verbose
|
||||
|
||||
|
||||
66
lib/wpscan/wp_target/wp_api.rb
Normal file
66
lib/wpscan/wp_target/wp_api.rb
Normal file
@@ -0,0 +1,66 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
class WpTarget < WebSite
|
||||
module WpAPI
|
||||
|
||||
# Checks to see if the REST API is enabled
|
||||
#
|
||||
# This by default in a WordPress installation since 4.5+
|
||||
# @return [ Boolean ]
|
||||
def has_api?(url)
|
||||
# Make the request
|
||||
response = Browser.get(url)
|
||||
|
||||
# Able to view the output?
|
||||
if valid_json?(response.body)
|
||||
# Read in JSON
|
||||
data = JSON.parse(response.body)
|
||||
|
||||
# If there is nothing there, return false
|
||||
return false if data.empty?
|
||||
|
||||
# WAF/API disabled response
|
||||
return false if data.include?('message') and data['message'] =~ /Only authenticated users can access the REST API/
|
||||
|
||||
# Success!
|
||||
return true if response.code == 200
|
||||
end
|
||||
|
||||
# Something went wrong
|
||||
return false
|
||||
end
|
||||
|
||||
# @return [ String ] The API/JSON URL
|
||||
def json_url
|
||||
@uri.merge('/wp-json/').to_s
|
||||
end
|
||||
|
||||
# @return [ String ] The API/JSON URL to show users
|
||||
def json_users_url
|
||||
@uri.merge('/wp-json/wp/v2/users').to_s
|
||||
end
|
||||
|
||||
# @return [ String ] The API/JSON URL to show users
|
||||
def json_get_users(url)
|
||||
# Make the request
|
||||
response = Browser.get(url)
|
||||
|
||||
# Able to view the output?
|
||||
return false if not valid_json?(response.body)
|
||||
|
||||
# Read in JSON
|
||||
data = JSON.parse(response.body)
|
||||
|
||||
# If there is nothing there, return false
|
||||
return false if data.empty?
|
||||
|
||||
# If not HTTP 200, return false
|
||||
return false if response.code != 200
|
||||
|
||||
data.each do |child|
|
||||
puts notice("ID: #{child['id']} | Name: #{child['name']}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
15
wpscan.rb
15
wpscan.rb
@@ -299,6 +299,21 @@ def main
|
||||
puts info("XML-RPC Interface available under: #{wp_target.xml_rpc_url}")
|
||||
end
|
||||
|
||||
if wp_target.has_api?(wp_target.json_url)
|
||||
puts info("API exposed: #{wp_target.json_url}")
|
||||
|
||||
if wp_target.has_api?(wp_target.json_users_url)
|
||||
puts warning("Users exposed via API: #{wp_target.json_users_url}")
|
||||
|
||||
# Print users from JSON
|
||||
wp_target.json_get_users(wp_target.json_users_url)
|
||||
end
|
||||
end
|
||||
|
||||
if wp_target.has_full_path_disclosure?
|
||||
puts warning("Full Path Disclosure (FPD) in '#{wp_target.full_path_disclosure_url}': #{wp_target.full_path_disclosure_data}")
|
||||
end
|
||||
|
||||
if wp_target.upload_directory_listing_enabled?
|
||||
puts warning("Upload directory has directory listing enabled: #{wp_target.upload_dir_url}")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user