HELLO v3!!!
This commit is contained in:
158
app/models/wp_item.rb
Normal file
158
app/models/wp_item.rb
Normal file
@@ -0,0 +1,158 @@
|
||||
module WPScan
|
||||
# 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
|
||||
|
||||
attr_reader :uri, :slug, :detection_opts, :version_detection_opts, :blog, :db_data
|
||||
|
||||
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]
|
||||
|
||||
@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)
|
||||
end
|
||||
|
||||
@vulnerabilities
|
||||
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?
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
@readme_url
|
||||
end
|
||||
|
||||
# @return [ String, false ] The changelog urr if found
|
||||
def changelog_url
|
||||
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
|
||||
|
||||
@changelog_url
|
||||
end
|
||||
|
||||
# @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)
|
||||
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
|
||||
Reference in New Issue
Block a user