Moves Models into their own namespace - Ref #1315

This commit is contained in:
erwanlr
2019-03-19 21:07:53 +00:00
parent f1657164d5
commit 898e8d4546
116 changed files with 613 additions and 560 deletions

View File

@@ -1,158 +1,160 @@
module WPScan
# WpItem (superclass of Plugin & Theme)
class WpItem
include Vulnerable
include Finders::Finding
include CMSScanner::Target::Platform::PHP
include CMSScanner::Target::Server::Generic
module Model
# WpItem (superclass of Plugin & Theme)
class WpItem
include Vulnerable
include Finders::Finding
include CMSScanner::Target::Platform::PHP
include CMSScanner::Target::Server::Generic
READMES = %w[readme.txt README.txt README.md readme.md Readme.txt].freeze
CHANGELOGS = %w[changelog.txt CHANGELOG.md changelog.md].freeze
READMES = %w[readme.txt README.txt README.md readme.md Readme.txt].freeze
CHANGELOGS = %w[changelog.txt CHANGELOG.md changelog.md].freeze
attr_reader :uri, :slug, :detection_opts, :version_detection_opts, :blog, :db_data
attr_reader :uri, :slug, :detection_opts, :version_detection_opts, :blog, :db_data
delegate :homepage_res, :xpath_pattern_from_page, :in_scope_urls, to: :blog
delegate :homepage_res, :xpath_pattern_from_page, :in_scope_urls, to: :blog
# @param [ String ] slug The plugin/theme slug
# @param [ Target ] blog The targeted blog
# @param [ Hash ] opts
# @option opts [ Symbol ] :mode The detection mode to use
# @option opts [ Hash ] :version_detection The options to use when looking for the version
# @option opts [ String ] :url The URL of the item
def initialize(slug, blog, opts = {})
@slug = URI.decode(slug)
@blog = blog
@uri = Addressable::URI.parse(opts[:url]) if opts[:url]
# @param [ String ] slug The plugin/theme slug
# @param [ Target ] blog The targeted blog
# @param [ Hash ] opts
# @option opts [ Symbol ] :mode The detection mode to use
# @option opts [ Hash ] :version_detection The options to use when looking for the version
# @option opts [ String ] :url The URL of the item
def initialize(slug, blog, opts = {})
@slug = URI.decode(slug)
@blog = blog
@uri = Addressable::URI.parse(opts[:url]) if opts[:url]
@detection_opts = { mode: opts[:mode] }
@version_detection_opts = opts[:version_detection] || {}
@detection_opts = { mode: opts[:mode] }
@version_detection_opts = opts[:version_detection] || {}
parse_finding_options(opts)
end
# @return [ Array<Vulnerabily> ]
def vulnerabilities
return @vulnerabilities if @vulnerabilities
@vulnerabilities = []
[*db_data['vulnerabilities']].each do |json_vuln|
vulnerability = Vulnerability.load_from_json(json_vuln)
@vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
parse_finding_options(opts)
end
@vulnerabilities
end
# @return [ Array<Vulnerabily> ]
def vulnerabilities
return @vulnerabilities if @vulnerabilities
# Checks if the wp_item is vulnerable to a specific vulnerability
#
# @param [ Vulnerability ] vuln Vulnerability to check the item against
#
# @return [ Boolean ]
def vulnerable_to?(vuln)
return true unless version && vuln && vuln.fixed_in && !vuln.fixed_in.empty?
@vulnerabilities = []
version < vuln.fixed_in
end
# @return [ String ]
def latest_version
@latest_version ||= db_data['latest_version'] ? WPScan::Version.new(db_data['latest_version']) : nil
end
# Not used anywhere ATM
# @return [ Boolean ]
def popular?
@popular ||= db_data['popular']
end
# @return [ String ]
def last_updated
@last_updated ||= db_data['last_updated']
end
# @return [ Boolean ]
def outdated?
@outdated ||= if version && latest_version
version < latest_version
else
false
end
end
# URI.encode is preferered over Addressable::URI.encode as it will encode
# leading # character:
# URI.encode('#t#') => %23t%23
# Addressable::URI.encode('#t#') => #t%23
#
# @param [ String ] path Optional path to merge with the uri
#
# @return [ String ]
def url(path = nil)
return unless @uri
return @uri.to_s unless path
@uri.join(URI.encode(path)).to_s
end
# @return [ Boolean ]
def ==(other)
self.class == other.class && slug == other.slug
end
def to_s
slug
end
# @return [ Symbol ] The Class symbol associated to the item
def classify
@classify ||= classify_slug(slug)
end
# @return [ String ] The readme url if found
def readme_url
return if detection_opts[:mode] == :passive
if @readme_url.nil?
READMES.each do |path|
return @readme_url = url(path) if Browser.get(url(path)).code == 200
[*db_data['vulnerabilities']].each do |json_vuln|
vulnerability = Vulnerability.load_from_json(json_vuln)
@vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
end
@vulnerabilities
end
@readme_url
end
# Checks if the wp_item is vulnerable to a specific vulnerability
#
# @param [ Vulnerability ] vuln Vulnerability to check the item against
#
# @return [ Boolean ]
def vulnerable_to?(vuln)
return true unless version && vuln && vuln.fixed_in && !vuln.fixed_in.empty?
# @return [ String, false ] The changelog urr if found
def changelog_url
return if detection_opts[:mode] == :passive
version < vuln.fixed_in
end
if @changelog_url.nil?
CHANGELOGS.each do |path|
return @changelog_url = url(path) if Browser.get(url(path)).code == 200
# @return [ String ]
def latest_version
@latest_version ||= db_data['latest_version'] ? Model::Version.new(db_data['latest_version']) : nil
end
# Not used anywhere ATM
# @return [ Boolean ]
def popular?
@popular ||= db_data['popular']
end
# @return [ String ]
def last_updated
@last_updated ||= db_data['last_updated']
end
# @return [ Boolean ]
def outdated?
@outdated ||= if version && latest_version
version < latest_version
else
false
end
end
# URI.encode is preferered over Addressable::URI.encode as it will encode
# leading # character:
# URI.encode('#t#') => %23t%23
# Addressable::URI.encode('#t#') => #t%23
#
# @param [ String ] path Optional path to merge with the uri
#
# @return [ String ]
def url(path = nil)
return unless @uri
return @uri.to_s unless path
@uri.join(URI.encode(path)).to_s
end
# @return [ Boolean ]
def ==(other)
self.class == other.class && slug == other.slug
end
def to_s
slug
end
# @return [ Symbol ] The Class symbol associated to the item
def classify
@classify ||= classify_slug(slug)
end
# @return [ String ] The readme url if found
def readme_url
return if detection_opts[:mode] == :passive
if @readme_url.nil?
READMES.each do |path|
return @readme_url = url(path) if Browser.get(url(path)).code == 200
end
end
@readme_url
end
@changelog_url
end
# @return [ String, false ] The changelog urr if found
def changelog_url
return if detection_opts[:mode] == :passive
# @param [ String ] path
# @param [ Hash ] params The request params
#
# @return [ Boolean ]
def directory_listing?(path = nil, params = {})
return if detection_opts[:mode] == :passive
if @changelog_url.nil?
CHANGELOGS.each do |path|
return @changelog_url = url(path) if Browser.get(url(path)).code == 200
end
end
super(path, params)
end
@changelog_url
end
# @param [ String ] path
# @param [ Hash ] params The request params
#
# @return [ Boolean ]
def error_log?(path = 'error_log', params = {})
return if detection_opts[:mode] == :passive
# @param [ String ] path
# @param [ Hash ] params The request params
#
# @return [ Boolean ]
def directory_listing?(path = nil, params = {})
return if detection_opts[:mode] == :passive
super(path, params)
super(path, params)
end
# @param [ String ] path
# @param [ Hash ] params The request params
#
# @return [ Boolean ]
def error_log?(path = 'error_log', params = {})
return if detection_opts[:mode] == :passive
super(path, params)
end
end
end
end