Initial attempt at implementing apiv2 #853
This commit is contained in:
@@ -67,6 +67,7 @@ class WpItems < Array
|
|||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# @return [ Class ]
|
# @return [ Class ]
|
||||||
def item_class
|
def item_class
|
||||||
Object.const_get(self.class.to_s.gsub(/.$/, ''))
|
Object.const_get(self.class.to_s.gsub(/.$/, ''))
|
||||||
|
|||||||
@@ -155,15 +155,7 @@ class WpItems < Array
|
|||||||
item_class = self.item_class
|
item_class = self.item_class
|
||||||
vulns_file = self.vulns_file
|
vulns_file = self.vulns_file
|
||||||
|
|
||||||
targets = vulnerable_targets_items(wp_target, item_class, vulns_file)
|
targets = target_items(wp_target, item_class, vulns_file, options[:type])
|
||||||
|
|
||||||
unless options[:only_vulnerable]
|
|
||||||
unless options[:file]
|
|
||||||
raise 'A file must be supplied'
|
|
||||||
end
|
|
||||||
|
|
||||||
targets += targets_items_from_file(options[:file], wp_target, item_class, vulns_file)
|
|
||||||
end
|
|
||||||
|
|
||||||
targets.uniq! { |t| t.name }
|
targets.uniq! { |t| t.name }
|
||||||
targets.sort_by { rand }
|
targets.sort_by { rand }
|
||||||
@@ -174,14 +166,25 @@ class WpItems < Array
|
|||||||
# @param [ String ] vulns_file
|
# @param [ String ] vulns_file
|
||||||
#
|
#
|
||||||
# @return [ Array<WpItem> ]
|
# @return [ Array<WpItem> ]
|
||||||
def vulnerable_targets_items(wp_target, item_class, vulns_file)
|
def target_items(wp_target, item_class, vulns_file, type)
|
||||||
targets = []
|
targets = []
|
||||||
json = json(vulns_file)
|
json = json(vulns_file)
|
||||||
|
|
||||||
[*json].each do |item|
|
case type
|
||||||
|
when :vulnerable
|
||||||
|
item_names = json.select { |item| !item['vulnerabilities'].empty? }.map {|item| item['name'] }
|
||||||
|
when :popular
|
||||||
|
item_names = json.select { |item| item['popular'] == true }.map {|item| item['name'] }
|
||||||
|
when :all
|
||||||
|
item_names = [*json].map { |item| item['name'] }
|
||||||
|
else
|
||||||
|
raise "Known type #{type}"
|
||||||
|
end
|
||||||
|
|
||||||
|
item_names.each do |item_name|
|
||||||
targets << create_item(
|
targets << create_item(
|
||||||
item_class,
|
item_class,
|
||||||
item.keys.inject,
|
item_name,
|
||||||
wp_target,
|
wp_target,
|
||||||
vulns_file
|
vulns_file
|
||||||
)
|
)
|
||||||
@@ -233,6 +236,5 @@ class WpItems < Array
|
|||||||
def item_class
|
def item_class
|
||||||
Object.const_get(self.to_s.gsub(/.$/, ''))
|
Object.const_get(self.to_s.gsub(/.$/, ''))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,17 +2,11 @@
|
|||||||
|
|
||||||
class WpPlugins < WpItems
|
class WpPlugins < WpItems
|
||||||
module Detectable
|
module Detectable
|
||||||
|
|
||||||
# @return [ String ]
|
# @return [ String ]
|
||||||
def vulns_file
|
def vulns_file
|
||||||
PLUGINS_VULNS_FILE
|
PLUGINS_FILE
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ]
|
|
||||||
# def item_xpath
|
|
||||||
# '//plugin'
|
|
||||||
# end
|
|
||||||
|
|
||||||
# @param [ WpTarget ] wp_target
|
# @param [ WpTarget ] wp_target
|
||||||
# @param [ Hash ] options
|
# @param [ Hash ] options
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -5,13 +5,7 @@ class WpThemes < WpItems
|
|||||||
|
|
||||||
# @return [ String ]
|
# @return [ String ]
|
||||||
def vulns_file
|
def vulns_file
|
||||||
THEMES_VULNS_FILE
|
THEMES_FILE
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ]
|
|
||||||
# def item_xpath
|
|
||||||
# '//theme'
|
|
||||||
# end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,20 +18,15 @@ COMMON_PLUGINS_DIR = File.join(COMMON_LIB_DIR, 'plugins')
|
|||||||
WPSCAN_PLUGINS_DIR = File.join(WPSCAN_LIB_DIR, 'plugins') # Not used ATM
|
WPSCAN_PLUGINS_DIR = File.join(WPSCAN_LIB_DIR, 'plugins') # Not used ATM
|
||||||
|
|
||||||
# Data files
|
# Data files
|
||||||
PLUGINS_FILE = File.join(DATA_DIR, 'plugins.txt')
|
WORDPRESSES_FILE = File.join(DATA_DIR, 'wordpresses.json')
|
||||||
PLUGINS_FULL_FILE = File.join(DATA_DIR, 'plugins_full.txt')
|
PLUGINS_FILE = File.join(DATA_DIR, 'plugins.json')
|
||||||
PLUGINS_VULNS_FILE = File.join(DATA_DIR, 'plugin_vulns.json')
|
THEMES_FILE = File.join(DATA_DIR, 'themes.json')
|
||||||
THEMES_FILE = File.join(DATA_DIR, 'themes.txt')
|
WP_VERSIONS_FILE = File.join(DATA_DIR, 'wp_versions.xml')
|
||||||
THEMES_FULL_FILE = File.join(DATA_DIR, 'themes_full.txt')
|
LOCAL_FILES_FILE = File.join(DATA_DIR, 'local_vulnerable_files.xml')
|
||||||
THEMES_VULNS_FILE = File.join(DATA_DIR, 'theme_vulns.json')
|
WP_VERSIONS_XSD = File.join(DATA_DIR, 'wp_versions.xsd')
|
||||||
WP_VULNS_FILE = File.join(DATA_DIR, 'wp_vulns.json')
|
LOCAL_FILES_XSD = File.join(DATA_DIR, 'local_vulnerable_files.xsd')
|
||||||
WP_VERSIONS_FILE = File.join(DATA_DIR, 'wp_versions.xml')
|
USER_AGENTS_FILE = File.join(DATA_DIR, 'user-agents.txt')
|
||||||
LOCAL_FILES_FILE = File.join(DATA_DIR, 'local_vulnerable_files.xml')
|
LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update')
|
||||||
# VULNS_XSD = File.join(DATA_DIR, 'vuln.xsd')
|
|
||||||
WP_VERSIONS_XSD = File.join(DATA_DIR, 'wp_versions.xsd')
|
|
||||||
LOCAL_FILES_XSD = File.join(DATA_DIR, 'local_vulnerable_files.xsd')
|
|
||||||
USER_AGENTS_FILE = File.join(DATA_DIR, 'user-agents.txt')
|
|
||||||
LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update')
|
|
||||||
|
|
||||||
WPSCAN_VERSION = '2.8'
|
WPSCAN_VERSION = '2.8'
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,8 @@
|
|||||||
class DbUpdater
|
class DbUpdater
|
||||||
FILES = %w(
|
FILES = %w(
|
||||||
local_vulnerable_files.xml local_vulnerable_files.xsd
|
local_vulnerable_files.xml local_vulnerable_files.xsd
|
||||||
plugins_full.txt plugins.txt themes_full.txt themes.txt
|
|
||||||
timthumbs.txt user-agents.txt wp_versions.xml wp_versions.xsd
|
timthumbs.txt user-agents.txt wp_versions.xml wp_versions.xsd
|
||||||
plugin_vulns.json theme_vulns.json wp_vulns.json LICENSE
|
wordpresses.json plugins.json themes.json LICENSE
|
||||||
)
|
)
|
||||||
|
|
||||||
attr_reader :repo_directory
|
attr_reader :repo_directory
|
||||||
|
|||||||
@@ -42,11 +42,12 @@ class Vulnerability
|
|||||||
# @return [ Vulnerability ]
|
# @return [ Vulnerability ]
|
||||||
def self.load_from_json_item(json_item)
|
def self.load_from_json_item(json_item)
|
||||||
references = {}
|
references = {}
|
||||||
|
references['id'] = [json_item['id']]
|
||||||
|
|
||||||
%w(id url cve secunia osvdb metasploit exploitdb).each do |key|
|
%w(url cve secunia osvdb metasploit exploitdb).each do |key|
|
||||||
if json_item[key]
|
if json_item['references'][key]
|
||||||
json_item[key] = [json_item[key]] if json_item[key].class != Array
|
json_item['references'][key] = [json_item['references'][key]] if json_item['references'][key].class != Array
|
||||||
references[key] = json_item[key]
|
references[key] = json_item['references'][key]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ class Vulnerability
|
|||||||
json_item['title'],
|
json_item['title'],
|
||||||
json_item['type'],
|
json_item['type'],
|
||||||
references,
|
references,
|
||||||
json_item['fixed_in'],
|
json_item['fixed_in']
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,22 @@
|
|||||||
|
|
||||||
class Vulnerability
|
class Vulnerability
|
||||||
module Output
|
module Output
|
||||||
|
|
||||||
# output the vulnerability
|
# output the vulnerability
|
||||||
def output(verbose = false)
|
def output(verbose = false)
|
||||||
puts
|
puts
|
||||||
puts critical("Title: #{title}")
|
puts critical("Title: #{title}")
|
||||||
|
|
||||||
references.each do |key, urls|
|
references.each do |key, urls|
|
||||||
methodname = "url_#{key}"
|
methodname = "url_#{key}"
|
||||||
|
|
||||||
urls.each do |u|
|
urls.each do |u|
|
||||||
next unless respond_to?(methodname)
|
next unless respond_to?(methodname)
|
||||||
url = send(methodname, u)
|
url = send(methodname, u)
|
||||||
puts " Reference: #{url}" if url
|
puts " Reference: #{url}" if url
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
unless fixed_in.nil?
|
|
||||||
puts notice("Fixed in: #{fixed_in}")
|
puts notice("Fixed in: #{fixed_in}") if fixed_in
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ class WpItem
|
|||||||
def output(verbose = false)
|
def output(verbose = false)
|
||||||
puts
|
puts
|
||||||
puts info("Name: #{self}") #this will also output the version number if detected
|
puts info("Name: #{self}") #this will also output the version number if detected
|
||||||
|
puts " | Latest version:"
|
||||||
|
puts " | Last updated:"
|
||||||
puts " | Location: #{url}"
|
puts " | Location: #{url}"
|
||||||
#puts " | WordPress: #{wordpress_url}" if wordpress_org_item?
|
#puts " | WordPress: #{wordpress_url}" if wordpress_org_item?
|
||||||
puts " | Readme: #{readme_url}" if has_readme?
|
puts " | Readme: #{readme_url}" if has_readme?
|
||||||
|
|||||||
@@ -9,15 +9,16 @@ class WpItem
|
|||||||
#
|
#
|
||||||
# @return [ Vulnerabilities ]
|
# @return [ Vulnerabilities ]
|
||||||
def vulnerabilities
|
def vulnerabilities
|
||||||
json = json(vulns_file)
|
json = json(vulns_file).select { |item| !item['vulnerabilities'].empty? }
|
||||||
vulnerabilities = Vulnerabilities.new
|
vulnerabilities = Vulnerabilities.new
|
||||||
|
|
||||||
json.each do |item|
|
json.each do |item|
|
||||||
asset = item[identifier]
|
asset = item['version'][identifier] if item['version']
|
||||||
|
asset = item['name'][identifier] if item['name']
|
||||||
|
|
||||||
next unless asset
|
next unless asset
|
||||||
|
|
||||||
asset['vulnerabilities'].each do |vulnerability|
|
item['vulnerabilities'].each do |vulnerability|
|
||||||
vulnerability = Vulnerability.load_from_json_item(vulnerability)
|
vulnerability = Vulnerability.load_from_json_item(vulnerability)
|
||||||
vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
|
vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class WpPlugin < WpItem
|
|||||||
# @return [ String ] The path to the file containing vulnerabilities
|
# @return [ String ] The path to the file containing vulnerabilities
|
||||||
def vulns_file
|
def vulns_file
|
||||||
unless @vulns_file
|
unless @vulns_file
|
||||||
@vulns_file = PLUGINS_VULNS_FILE
|
@vulns_file = PLUGINS_FILE
|
||||||
end
|
end
|
||||||
@vulns_file
|
@vulns_file
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class WpTheme < WpItem
|
|||||||
# @return [ String ] The path to the file containing vulnerabilities
|
# @return [ String ] The path to the file containing vulnerabilities
|
||||||
def vulns_file
|
def vulns_file
|
||||||
unless @vulns_file
|
unless @vulns_file
|
||||||
@vulns_file = THEMES_VULNS_FILE
|
@vulns_file = THEMES_FILE
|
||||||
end
|
end
|
||||||
@vulns_file
|
@vulns_file
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class WpVersion < WpItem
|
|||||||
# @return [ String ] The path to the file containing vulnerabilities
|
# @return [ String ] The path to the file containing vulnerabilities
|
||||||
def vulns_file
|
def vulns_file
|
||||||
unless @vulns_file
|
unless @vulns_file
|
||||||
@vulns_file = WP_VULNS_FILE
|
@vulns_file = WORDPRESSES_FILE
|
||||||
end
|
end
|
||||||
@vulns_file
|
@vulns_file
|
||||||
end
|
end
|
||||||
|
|||||||
39
wpscan.rb
39
wpscan.rb
@@ -273,15 +273,29 @@ def main
|
|||||||
# Enumerate the installed plugins
|
# Enumerate the installed plugins
|
||||||
if wpscan_options.enumerate_plugins or wpscan_options.enumerate_only_vulnerable_plugins or wpscan_options.enumerate_all_plugins
|
if wpscan_options.enumerate_plugins or wpscan_options.enumerate_only_vulnerable_plugins or wpscan_options.enumerate_all_plugins
|
||||||
puts
|
puts
|
||||||
puts info("Enumerating installed plugins #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_plugins} ...")
|
if wpscan_options.enumerate_only_vulnerable_plugins
|
||||||
|
puts info('Enumerating installed plugins (only ones with known vulnerabilities) ...')
|
||||||
|
plugin_enumeration_type = :vulnerable
|
||||||
|
end
|
||||||
|
|
||||||
|
if wpscan_options.enumerate_plugins
|
||||||
|
puts info('Enumerating installed plugins (only ones marked as popular) ...')
|
||||||
|
plugin_enumeration_type = :popular
|
||||||
|
end
|
||||||
|
|
||||||
|
if wpscan_options.enumerate_all_plugins
|
||||||
|
puts info('Enumerating all plugins (may take a while and use a lot of system resources) ...')
|
||||||
|
plugin_enumeration_type = :all
|
||||||
|
end
|
||||||
puts
|
puts
|
||||||
|
|
||||||
wp_plugins = WpPlugins.aggressive_detection(wp_target,
|
wp_plugins = WpPlugins.aggressive_detection(wp_target,
|
||||||
enum_options.merge(
|
enum_options.merge(
|
||||||
file: wpscan_options.enumerate_all_plugins ? PLUGINS_FULL_FILE : PLUGINS_FILE,
|
file: PLUGINS_FILE,
|
||||||
only_vulnerable: wpscan_options.enumerate_only_vulnerable_plugins || false
|
type: plugin_enumeration_type
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
puts
|
puts
|
||||||
if !wp_plugins.empty?
|
if !wp_plugins.empty?
|
||||||
puts info("We found #{wp_plugins.size} plugins:")
|
puts info("We found #{wp_plugins.size} plugins:")
|
||||||
@@ -295,13 +309,26 @@ def main
|
|||||||
# Enumerate installed themes
|
# Enumerate installed themes
|
||||||
if wpscan_options.enumerate_themes or wpscan_options.enumerate_only_vulnerable_themes or wpscan_options.enumerate_all_themes
|
if wpscan_options.enumerate_themes or wpscan_options.enumerate_only_vulnerable_themes or wpscan_options.enumerate_all_themes
|
||||||
puts
|
puts
|
||||||
puts info("Enumerating installed themes #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_themes} ...")
|
if wpscan_options.enumerate_only_vulnerable_themes
|
||||||
|
puts info('Enumerating installed themes (only ones with known vulnerabilities) ...')
|
||||||
|
theme_enumeration_type = :vulnerable
|
||||||
|
end
|
||||||
|
|
||||||
|
if wpscan_options.enumerate_themes
|
||||||
|
puts info('Enumerating installed themes (only ones marked as popular) ...')
|
||||||
|
theme_enumeration_type = :popular
|
||||||
|
end
|
||||||
|
|
||||||
|
if wpscan_options.enumerate_all_themes
|
||||||
|
puts info('Enumerating all themes (may take a while and use a lot of system resources) ...')
|
||||||
|
theme_enumeration_type = :all
|
||||||
|
end
|
||||||
puts
|
puts
|
||||||
|
|
||||||
wp_themes = WpThemes.aggressive_detection(wp_target,
|
wp_themes = WpThemes.aggressive_detection(wp_target,
|
||||||
enum_options.merge(
|
enum_options.merge(
|
||||||
file: wpscan_options.enumerate_all_themes ? THEMES_FULL_FILE : THEMES_FILE,
|
file: THEMES_FILE,
|
||||||
only_vulnerable: wpscan_options.enumerate_only_vulnerable_themes || false
|
type: theme_enumeration_type
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
puts
|
puts
|
||||||
|
|||||||
Reference in New Issue
Block a user