wpscan 3.2.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +73 -70
- data/app/controllers.rb +1 -1
- data/app/controllers/enumeration.rb +1 -1
- data/app/controllers/enumeration/cli_options.rb +32 -15
- data/app/controllers/enumeration/enum_methods.rb +7 -0
- data/app/controllers/password_attack.rb +108 -0
- data/app/finders.rb +2 -0
- data/app/finders/config_backups/known_filenames.rb +1 -1
- data/app/finders/db_exports.rb +17 -0
- data/app/finders/db_exports/known_locations.rb +49 -0
- data/app/finders/interesting_findings/mu_plugins.rb +1 -0
- data/app/finders/main_theme/css_style.rb +1 -1
- data/app/finders/medias/attachment_brute_forcing.rb +1 -1
- data/app/finders/passwords.rb +3 -0
- data/app/finders/passwords/wp_login.rb +22 -0
- data/app/finders/passwords/xml_rpc.rb +22 -0
- data/app/finders/passwords/xml_rpc_multicall.rb +102 -0
- data/app/finders/users.rb +2 -0
- data/app/finders/users/author_id_brute_forcing.rb +3 -3
- data/app/finders/users/author_posts.rb +2 -2
- data/app/finders/users/login_error_messages.rb +1 -1
- data/app/finders/users/oembed_api.rb +4 -4
- data/app/finders/users/rss_generator.rb +38 -0
- data/app/finders/users/wp_json_api.rb +5 -5
- data/app/finders/wp_version/atom_generator.rb +1 -1
- data/app/finders/wp_version/rdf_generator.rb +1 -1
- data/app/finders/wp_version/rss_generator.rb +1 -1
- data/app/models.rb +1 -1
- data/app/models/db_export.rb +5 -0
- data/app/models/wp_item.rb +2 -0
- data/app/views/cli/core/banner.erb +1 -1
- data/app/views/cli/enumeration/db_exports.erb +11 -0
- data/app/views/cli/{brute_force → password_attack}/users.erb +0 -0
- data/app/views/json/enumeration/db_exports.erb +10 -0
- data/app/views/json/{brute_force → password_attack}/users.erb +1 -1
- data/bin/wpscan +1 -1
- data/lib/wpscan/browser.rb +1 -1
- data/lib/wpscan/db/dynamic_finders/plugin.rb +2 -2
- data/lib/wpscan/db/dynamic_finders/wordpress.rb +2 -2
- data/lib/wpscan/db/fingerprints.rb +1 -1
- data/lib/wpscan/db/updater.rb +4 -1
- data/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb +2 -1
- data/lib/wpscan/finders/dynamic_finder/wp_item_version.rb +2 -1
- data/lib/wpscan/finders/dynamic_finder/wp_version.rb +5 -4
- data/lib/wpscan/target.rb +13 -0
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +1 -1
- data/lib/wpscan/version.rb +1 -1
- metadata +29 -22
- data/app/controllers/brute_force.rb +0 -116
- data/app/models/user.rb +0 -31
- data/app/views/cli/brute_force/error.erb +0 -1
- data/app/views/cli/brute_force/found.erb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5eac3c3174f8ae7798069fddfc45fd67f837b388
|
4
|
+
data.tar.gz: 626cfade1aeb099be9bfc1fbadf68a319a25fa55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 031efaee33293d3ee7f0ff05a0a7100b8cf87b8b3f1429c513a6cb5ddd7d0a015fb6d7d462fb7fcc8cfbf18fd15c6ffe7db2428cb2ea77fed577c18055d975b4
|
7
|
+
data.tar.gz: b010b70018627700aa90cfebb98adf0f5f3de157690e1baa56885405725f1e16fa96c2d1b65bc19d73fbd6707146e2ab1c712ad283cf388753a26218a0bdd5a4
|
data/README.md
CHANGED
@@ -3,7 +3,79 @@
|
|
3
3
|
[](https://badge.fury.io/rb/wpscan)
|
4
4
|
[](https://travis-ci.org/wpscanteam/wpscan-v3)
|
5
5
|
[](https://codeclimate.com/github/wpscanteam/wpscan-v3)
|
6
|
-
[](https://www.patreon.com/wpscan)
|
7
|
+
|
8
|
+
# INSTALL
|
9
|
+
|
10
|
+
## Prerequisites:
|
11
|
+
|
12
|
+
- Ruby >= 2.2.2 - Recommended: 2.3.3
|
13
|
+
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
14
|
+
- RubyGems - Recommended: latest
|
15
|
+
|
16
|
+
### From RubyGems:
|
17
|
+
|
18
|
+
```
|
19
|
+
gem install wpscan
|
20
|
+
```
|
21
|
+
|
22
|
+
### From sources:
|
23
|
+
|
24
|
+
Prerequisites: Git
|
25
|
+
|
26
|
+
```
|
27
|
+
git clone https://github.com/wpscanteam/wpscan-v3 wpscan
|
28
|
+
|
29
|
+
cd wpscan/
|
30
|
+
|
31
|
+
bundle install && rake install
|
32
|
+
```
|
33
|
+
|
34
|
+
# Docker
|
35
|
+
|
36
|
+
Pull the repo with ```docker pull wpscanteam/wpscan-v3```
|
37
|
+
|
38
|
+
# Usage
|
39
|
+
|
40
|
+
```wpscan --url blog.tld``` This will scan the blog using default options with a good compromise between speed and accuracy. For example, the plugins will be checked passively but their version with a mixed detection mode (passively + aggressively). Potential config backup files will also be checked, along with other interesting findings. If a more stealthy approach is required, then ```wpscan --stealthy --url blog.tld``` can be used.
|
41
|
+
As a result, when using the ```--enumerate``` option, don't forget to set the ```--plugins-detection``` accordingly, as its default is 'passive'.
|
42
|
+
|
43
|
+
For more options, open a terminal and type ```wpscan --help``` (if you built wpscan from the source, you should type the command outside of the git repo)
|
44
|
+
|
45
|
+
The DB is located at ~/.wpscan/db
|
46
|
+
|
47
|
+
WPScan can load all options (including the --url) from configuration files, the following locations are checked (order: first to last):
|
48
|
+
|
49
|
+
* ~/.wpscan/cli_options.json
|
50
|
+
* ~/.wpscan/cli_options.yml
|
51
|
+
* pwd/.wpscan/cli_options.json
|
52
|
+
* pwd/.wpscan/cli_options.yml
|
53
|
+
|
54
|
+
If those files exist, options from them will be loaded and overridden if found twice.
|
55
|
+
|
56
|
+
e.g:
|
57
|
+
|
58
|
+
~/.wpscan/cli_options.yml:
|
59
|
+
```
|
60
|
+
proxy: 'http://127.0.0.1:8080'
|
61
|
+
verbose: true
|
62
|
+
```
|
63
|
+
|
64
|
+
pwd/.wpscan/cli_options.yml:
|
65
|
+
```
|
66
|
+
proxy: 'socks5://127.0.0.1:9090'
|
67
|
+
url: 'http://target.tld'
|
68
|
+
```
|
69
|
+
|
70
|
+
Running ```wpscan``` in the current directory (pwd), is the same as ```wpscan -v --proxy socks5://127.0.0.1:9090 --url http://target.tld```
|
71
|
+
|
72
|
+
# PROJECT HOME
|
73
|
+
|
74
|
+
[https://wpscan.org](https://wpscan.org)
|
75
|
+
|
76
|
+
# VULNERABILITY DATABASE
|
77
|
+
|
78
|
+
[https://wpvulndb.com](https://wpvulndb.com)
|
7
79
|
|
8
80
|
# LICENSE
|
9
81
|
|
@@ -83,72 +155,3 @@ Running WPScan against websites without prior mutual consent may be illegal in y
|
|
83
155
|
### 11. Trademark
|
84
156
|
|
85
157
|
The "wpscan" term is a registered trademark. This License does not grant the use of the "wpscan" trademark or the use of the WPScan logo.
|
86
|
-
|
87
|
-
# INSTALL
|
88
|
-
|
89
|
-
## Prerequisites:
|
90
|
-
|
91
|
-
- Ruby >= 2.2.2 - Recommended: 2.3.3
|
92
|
-
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
93
|
-
- RubyGems - Recommended: latest
|
94
|
-
|
95
|
-
|
96
|
-
### From RubyGems:
|
97
|
-
|
98
|
-
```gem install wpscan```
|
99
|
-
|
100
|
-
### From sources:
|
101
|
-
|
102
|
-
Prerequisites: Git
|
103
|
-
|
104
|
-
```git clone https://github.com/wpscanteam/wpscan-v3```
|
105
|
-
|
106
|
-
```cd wpscan```
|
107
|
-
|
108
|
-
```bundle install && rake install```
|
109
|
-
|
110
|
-
# Docker
|
111
|
-
|
112
|
-
Pull the repo with ```docker pull wpscanteam/wpscan-v3```
|
113
|
-
|
114
|
-
# Usage
|
115
|
-
|
116
|
-
```wpscan --url blog.tld``` This will scan the blog using default options with a good compromise between speed and accuracy. For example, the plugins will be checked passively but their version with a mixed detection mode (passively + aggressively). Potential config backup files will also be checked, along with other interesting findings. If a more stealthy approach is required, then ```wpscan --stealthy --url blog.tld``` can be used.
|
117
|
-
As a result, when using the ```--enumerate``` option, don't forget to set the ```--plugins-detection``` accordingly, as its default is 'passive'.
|
118
|
-
|
119
|
-
For more options, open a terminal and type ```wpscan --help``` (if you built wpscan from the source, you should type the command outside of the git repo)
|
120
|
-
|
121
|
-
The DB is located at ~/.wpscan/db
|
122
|
-
|
123
|
-
WPScan can load all options (including the --url) from configuration files, the following locations are checked (order: first to last):
|
124
|
-
|
125
|
-
* ~/.wpscan/cli_options.json
|
126
|
-
* ~/.wpscan/cli_options.yml
|
127
|
-
* pwd/.wpscan/cli_options.json
|
128
|
-
* pwd/.wpscan/cli_options.yml
|
129
|
-
|
130
|
-
If those files exist, options from them will be loaded and overridden if found twice.
|
131
|
-
|
132
|
-
e.g:
|
133
|
-
|
134
|
-
~/.wpscan/cli_options.yml:
|
135
|
-
```
|
136
|
-
proxy: 'http://127.0.0.1:8080'
|
137
|
-
verbose: true
|
138
|
-
```
|
139
|
-
|
140
|
-
pwd/.wpscan/cli_options.yml:
|
141
|
-
```
|
142
|
-
proxy: 'socks5://127.0.0.1:9090'
|
143
|
-
url: 'http://target.tld'
|
144
|
-
```
|
145
|
-
|
146
|
-
Running ```wpscan``` in the current directory (pwd), is the same as ```wpscan -v --proxy socks5://127.0.0.1:9090 --url http://target.tld```
|
147
|
-
|
148
|
-
# PROJECT HOME
|
149
|
-
|
150
|
-
[https://wpscan.org](https://wpscan.org)
|
151
|
-
|
152
|
-
# VULNERABILITY DATABASE
|
153
|
-
|
154
|
-
[https://wpvulndb.com](https://wpvulndb.com)
|
data/app/controllers.rb
CHANGED
@@ -3,5 +3,5 @@ require_relative 'controllers/custom_directories'
|
|
3
3
|
require_relative 'controllers/wp_version'
|
4
4
|
require_relative 'controllers/main_theme'
|
5
5
|
require_relative 'controllers/enumeration'
|
6
|
-
require_relative 'controllers/
|
6
|
+
require_relative 'controllers/password_attack'
|
7
7
|
require_relative 'controllers/aliases'
|
@@ -16,7 +16,7 @@ module WPScan
|
|
16
16
|
enum_plugins if enum_plugins?(enum)
|
17
17
|
enum_themes if enum_themes?(enum)
|
18
18
|
|
19
|
-
%i[timthumbs config_backups medias].each do |key|
|
19
|
+
%i[timthumbs config_backups db_exports medias].each do |key|
|
20
20
|
send("enum_#{key}".to_sym) if enum.key?(key)
|
21
21
|
end
|
22
22
|
|
@@ -4,7 +4,8 @@ module WPScan
|
|
4
4
|
class Enumeration < CMSScanner::Controller::Base
|
5
5
|
def cli_options
|
6
6
|
cli_enum_choices + cli_plugins_opts + cli_themes_opts +
|
7
|
-
cli_timthumbs_opts + cli_config_backups_opts +
|
7
|
+
cli_timthumbs_opts + cli_config_backups_opts + cli_db_exports_opts +
|
8
|
+
cli_medias_opts + cli_users_opts
|
8
9
|
end
|
9
10
|
|
10
11
|
# @return [ Array<OptParseValidator::OptBase> ]
|
@@ -14,26 +15,27 @@ module WPScan
|
|
14
15
|
OptMultiChoices.new(
|
15
16
|
['--enumerate [OPTS]', '-e', 'Enumeration Process'],
|
16
17
|
choices: {
|
17
|
-
vp:
|
18
|
-
ap:
|
19
|
-
p:
|
20
|
-
vt:
|
21
|
-
at:
|
22
|
-
t:
|
23
|
-
tt:
|
24
|
-
cb:
|
25
|
-
|
26
|
-
|
18
|
+
vp: OptBoolean.new(['--vulnerable-plugins']),
|
19
|
+
ap: OptBoolean.new(['--all-plugins']),
|
20
|
+
p: OptBoolean.new(['--plugins']),
|
21
|
+
vt: OptBoolean.new(['--vulnerable-themes']),
|
22
|
+
at: OptBoolean.new(['--all-themes']),
|
23
|
+
t: OptBoolean.new(['--themes']),
|
24
|
+
tt: OptBoolean.new(['--timthumbs']),
|
25
|
+
cb: OptBoolean.new(['--config-backups']),
|
26
|
+
dbe: OptBoolean.new(['--db-exports']),
|
27
|
+
u: OptIntegerRange.new(['--users', 'User IDs range. e.g: u1-5'], value_if_empty: '1-10'),
|
28
|
+
m: OptIntegerRange.new(['--medias', 'Media IDs range. e.g m1-15'], value_if_empty: '1-100')
|
27
29
|
},
|
28
|
-
value_if_empty: 'vp,vt,tt,cb,u,m',
|
30
|
+
value_if_empty: 'vp,vt,tt,cb,dbe,u,m',
|
29
31
|
incompatible: [%i[vp ap p], %i[vt at t]],
|
30
32
|
default: { all_plugins: true, config_backups: true }
|
31
33
|
),
|
32
34
|
OptRegexp.new(
|
33
35
|
[
|
34
36
|
'--exclude-content-based REGEXP_OR_STRING',
|
35
|
-
'Exclude all responses
|
36
|
-
'Regexp delimiters are not required.'
|
37
|
+
'Exclude all responses matching the Regexp (case insensitive) during parts of the enumeration.',
|
38
|
+
'Both the headers and body are checked. Regexp delimiters are not required.'
|
37
39
|
], options: Regexp::IGNORECASE
|
38
40
|
)
|
39
41
|
]
|
@@ -110,7 +112,22 @@ module WPScan
|
|
110
112
|
),
|
111
113
|
OptChoice.new(
|
112
114
|
['--config-backups-detection MODE',
|
113
|
-
'Use the supplied mode to enumerate
|
115
|
+
'Use the supplied mode to enumerate Config Backups, instead of the global (--detection-mode) mode.'],
|
116
|
+
choices: %w[mixed passive aggressive], normalize: :to_sym
|
117
|
+
)
|
118
|
+
]
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [ Array<OptParseValidator::OptBase> ]
|
122
|
+
def cli_db_exports_opts
|
123
|
+
[
|
124
|
+
OptFilePath.new(
|
125
|
+
['--db-exports-list FILE-PATH', 'List of DB exports\' paths to use'],
|
126
|
+
exists: true, default: File.join(DB_DIR, 'db_exports.txt')
|
127
|
+
),
|
128
|
+
OptChoice.new(
|
129
|
+
['--db-exports-detection MODE',
|
130
|
+
'Use the supplied mode to enumerate DB Exports, instead of the global (--detection-mode) mode.'],
|
114
131
|
choices: %w[mixed passive aggressive], normalize: :to_sym
|
115
132
|
)
|
116
133
|
]
|
@@ -136,6 +136,13 @@ module WPScan
|
|
136
136
|
output('config_backups', config_backups: target.config_backups(opts))
|
137
137
|
end
|
138
138
|
|
139
|
+
def enum_db_exports
|
140
|
+
opts = default_opts('db_exports').merge(list: parsed_options[:db_exports_list])
|
141
|
+
|
142
|
+
output('@info', msg: 'Enumerating DB Exports') if user_interaction?
|
143
|
+
output('db_exports', db_exports: target.db_exports(opts))
|
144
|
+
end
|
145
|
+
|
139
146
|
def enum_medias
|
140
147
|
opts = default_opts('medias').merge(range: parsed_options[:enumerate][:medias])
|
141
148
|
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module WPScan
|
2
|
+
module Controller
|
3
|
+
# Password Attack Controller
|
4
|
+
class PasswordAttack < CMSScanner::Controller::Base
|
5
|
+
def cli_options
|
6
|
+
[
|
7
|
+
OptFilePath.new(
|
8
|
+
['--passwords FILE-PATH', '-P',
|
9
|
+
'List of passwords to use during the password attack.',
|
10
|
+
'If no --username/s option supplied, user enumeration will be run.'],
|
11
|
+
exists: true
|
12
|
+
),
|
13
|
+
OptSmartList.new(['--usernames LIST', '-U', 'List of usernames to use during the password attack.']),
|
14
|
+
OptInteger.new(['--multicall-max-passwords MAX_PWD',
|
15
|
+
'Maximum number of passwords to send by request with XMLRPC multicall'],
|
16
|
+
default: 500),
|
17
|
+
OptChoice.new(['--password-attack ATTACK',
|
18
|
+
'Force the supplied attack to be used rather than automatically determining one.'],
|
19
|
+
choices: %w[wp-login xmlrpc xmlrpc-multicall],
|
20
|
+
normalize: %i[downcase underscore to_sym])
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
return unless parsed_options[:passwords]
|
26
|
+
|
27
|
+
if user_interaction?
|
28
|
+
output('@info',
|
29
|
+
msg: "Performing password attack on #{attacker.titleize} against #{users.size} user/s")
|
30
|
+
end
|
31
|
+
|
32
|
+
attack_opts = {
|
33
|
+
show_progression: user_interaction?,
|
34
|
+
multicall_max_passwords: parsed_options[:multicall_max_passwords]
|
35
|
+
}
|
36
|
+
|
37
|
+
begin
|
38
|
+
found = []
|
39
|
+
|
40
|
+
attacker.attack(users, passwords(parsed_options[:passwords]), attack_opts) do |user|
|
41
|
+
found << user
|
42
|
+
|
43
|
+
attacker.progress_bar.log("[SUCCESS] - #{user.username} / #{user.password}")
|
44
|
+
end
|
45
|
+
ensure
|
46
|
+
output('users', users: found)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [ CMSScanner::Finders::Finder ] The finder used to perform the attack
|
51
|
+
def attacker
|
52
|
+
@attacker ||= attacker_from_cli_options || attacker_from_automatic_detection
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [ WPScan::XMLRPC ]
|
56
|
+
def xmlrpc
|
57
|
+
@xmlrpc ||= target.xmlrpc
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [ CMSScanner::Finders::Finder ]
|
61
|
+
def attacker_from_cli_options
|
62
|
+
return unless parsed_options[:password_attack]
|
63
|
+
|
64
|
+
case parsed_options[:password_attack]
|
65
|
+
when :wp_login
|
66
|
+
WPScan::Finders::Passwords::WpLogin.new(target)
|
67
|
+
when :xmlrpc
|
68
|
+
WPScan::Finders::Passwords::XMLRPC.new(xmlrpc)
|
69
|
+
when :xmlrpc_multicall
|
70
|
+
WPScan::Finders::Passwords::XMLRPCMulticall.new(xmlrpc)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [ CMSScanner::Finders::Finder ]
|
75
|
+
def attacker_from_automatic_detection
|
76
|
+
if xmlrpc&.enabled? && xmlrpc.available_methods.include?('wp.getUsersBlogs')
|
77
|
+
wp_version = target.wp_version
|
78
|
+
|
79
|
+
if wp_version && wp_version < '4.4'
|
80
|
+
WPScan::Finders::Passwords::XMLRPCMulticall.new(xmlrpc)
|
81
|
+
else
|
82
|
+
WPScan::Finders::Passwords::XMLRPC.new(xmlrpc)
|
83
|
+
end
|
84
|
+
else
|
85
|
+
WPScan::Finders::Passwords::WpLogin.new(target)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [ Array<Users> ] The users to brute force
|
90
|
+
def users
|
91
|
+
return target.users unless parsed_options[:usernames]
|
92
|
+
|
93
|
+
parsed_options[:usernames].reduce([]) do |acc, elem|
|
94
|
+
acc << CMSScanner::User.new(elem.chomp)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param [ String ] wordlist_path
|
99
|
+
#
|
100
|
+
# @return [ Array<String> ]
|
101
|
+
def passwords(wordlist_path)
|
102
|
+
@passwords ||= File.open(wordlist_path).reduce([]) do |acc, elem|
|
103
|
+
acc << elem.chomp
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/app/finders.rb
CHANGED
@@ -5,9 +5,11 @@ require_relative 'finders/main_theme'
|
|
5
5
|
require_relative 'finders/timthumb_version'
|
6
6
|
require_relative 'finders/timthumbs'
|
7
7
|
require_relative 'finders/config_backups'
|
8
|
+
require_relative 'finders/db_exports'
|
8
9
|
require_relative 'finders/medias'
|
9
10
|
require_relative 'finders/users'
|
10
11
|
require_relative 'finders/plugins'
|
11
12
|
require_relative 'finders/plugin_version'
|
12
13
|
require_relative 'finders/theme_version'
|
13
14
|
require_relative 'finders/themes'
|
15
|
+
require_relative 'finders/passwords'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'db_exports/known_locations'
|
2
|
+
|
3
|
+
module WPScan
|
4
|
+
module Finders
|
5
|
+
module DbExports
|
6
|
+
# DB Exports Finder
|
7
|
+
class Base
|
8
|
+
include CMSScanner::Finders::SameTypeFinder
|
9
|
+
|
10
|
+
# @param [ WPScan::Target ] target
|
11
|
+
def initialize(target)
|
12
|
+
finders << DbExports::KnownLocations.new(target)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module WPScan
|
2
|
+
module Finders
|
3
|
+
module DbExports
|
4
|
+
# DB Exports finder
|
5
|
+
# See https://github.com/wpscanteam/wpscan-v3/issues/62
|
6
|
+
class KnownLocations < CMSScanner::Finders::Finder
|
7
|
+
include CMSScanner::Finders::Finder::Enumerator
|
8
|
+
|
9
|
+
# @param [ Hash ] opts
|
10
|
+
# @option opts [ String ] :list
|
11
|
+
# @option opts [ Boolean ] :show_progression
|
12
|
+
#
|
13
|
+
# @return [ Array<DBExport> ]
|
14
|
+
def aggressive(opts = {})
|
15
|
+
found = []
|
16
|
+
|
17
|
+
enumerate(potential_urls(opts), opts) do |res|
|
18
|
+
next unless res.code == 200 && res.body =~ /INSERT INTO/
|
19
|
+
|
20
|
+
found << WPScan::DbExport.new(res.request.url, found_by: DIRECT_ACCESS, confidence: 100)
|
21
|
+
end
|
22
|
+
|
23
|
+
found
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param [ Hash ] opts
|
27
|
+
# @option opts [ String ] :list Mandatory
|
28
|
+
#
|
29
|
+
# @return [ Hash ]
|
30
|
+
def potential_urls(opts = {})
|
31
|
+
urls = {}
|
32
|
+
domain_name = target.uri.host[/(^[\w|-]+)/, 1]
|
33
|
+
|
34
|
+
File.open(opts[:list]).each_with_index do |path, index|
|
35
|
+
path.gsub!('{domain_name}', domain_name)
|
36
|
+
|
37
|
+
urls[target.url(path.chomp)] = index
|
38
|
+
end
|
39
|
+
|
40
|
+
urls
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_progress_bar(opts = {})
|
44
|
+
super(opts.merge(title: ' Checking DB Exports -'))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|