Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wpscanteam
GitHub Repository: wpscanteam/wpscan
Path: blob/master/app/controllers/core.rb
485 views
1
# frozen_string_literal: true
2
3
module WPScan
4
module Controller
5
# Specific Core controller to include WordPress checks
6
class Core < CMSScanner::Controller::Core
7
# @return [ Array<OptParseValidator::Opt> ]
8
def cli_options
9
[OptURL.new(['--url URL', 'The URL of the blog to scan'],
10
required_unless: %i[update help hh version], default_protocol: 'http')] +
11
super.drop(2) + # delete the --url and --force from CMSScanner
12
[
13
OptChoice.new(['--server SERVER', 'Force the supplied server module to be loaded'],
14
choices: %w[apache iis nginx],
15
normalize: %i[downcase to_sym],
16
advanced: true),
17
OptBoolean.new(['--force', 'Do not check if the target is running WordPress or returns a 403']),
18
OptBoolean.new(['--[no-]update', 'Whether or not to update the Database'])
19
]
20
end
21
22
# @return [ DB::Updater ]
23
def local_db
24
@local_db ||= DB::Updater.new(DB_DIR)
25
end
26
27
# @return [ Boolean ]
28
def update_db_required?
29
if local_db.missing_files?
30
raise Error::MissingDatabaseFile if ParsedCli.update == false
31
32
return true
33
end
34
35
return ParsedCli.update unless ParsedCli.update.nil?
36
37
return false unless user_interaction? && local_db.outdated?
38
39
output('@notice', msg: 'It seems like you have not updated the database for some time.')
40
print '[?] Do you want to update now? [Y]es [N]o, default: [N]'
41
$stdout.flush
42
43
response = $stdin.gets.to_s.strip
44
45
!!/^y/i.match?(response)
46
end
47
48
def update_db
49
output('db_update_started')
50
output('db_update_finished', updated: local_db.update, verbose: ParsedCli.verbose)
51
52
exit(0) unless ParsedCli.url
53
end
54
55
def before_scan
56
@last_update = local_db.last_update
57
58
maybe_output_banner_help_and_version # From CMSScanner
59
60
update_db if update_db_required?
61
setup_cache
62
check_target_availability
63
load_server_module
64
check_wordpress_state
65
rescue Error::NotWordPress => e
66
target.maybe_add_cookies
67
raise e unless target.wordpress?(ParsedCli.detection_mode)
68
end
69
70
# Raises errors if the target is hosted on wordpress.com or is not running WordPress
71
# Also check if the homepage_url is still the install url
72
def check_wordpress_state
73
raise Error::WordPressHosted if target.wordpress_hosted?
74
75
if %r{/wp-admin/install.php$}i.match?(Addressable::URI.parse(target.homepage_url).path)
76
77
output('not_fully_configured', url: target.homepage_url)
78
79
exit(WPScan::ExitCode::VULNERABLE)
80
end
81
82
raise Error::NotWordPress unless target.wordpress?(ParsedCli.detection_mode) || ParsedCli.force
83
end
84
85
# Loads the related server module in the target
86
# and includes it in the WpItem class which will be needed
87
# to check if directory listing is enabled etc
88
#
89
# @return [ Symbol ] The server module loaded
90
def load_server_module
91
server = target.server || :Apache # Tries to auto detect the server
92
93
# Force a specific server module to be loaded if supplied
94
case ParsedCli.server
95
when :apache
96
server = :Apache
97
when :iis
98
server = :IIS
99
when :nginx
100
server = :Nginx
101
end
102
103
mod = CMSScanner::Target::Server.const_get(server)
104
105
target.extend mod
106
Model::WpItem.include mod
107
108
server
109
end
110
end
111
end
112
end
113
114