wpscan 3.7.8 → 3.7.9
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 +1 -1
- data/app/controllers/custom_directories.rb +1 -3
- data/app/finders/interesting_findings/mu_plugins.rb +1 -1
- data/app/finders/main_theme/css_style_in_homepage.rb +1 -1
- data/app/finders/users/author_id_brute_forcing.rb +8 -6
- data/app/finders/users/author_posts.rb +1 -1
- data/app/finders/wp_items/urls_in_page.rb +6 -2
- data/lib/wpscan/db/updater.rb +5 -5
- data/lib/wpscan/db/vuln_api.rb +6 -7
- data/lib/wpscan/target/platform/wordpress.rb +9 -4
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +2 -1
- data/lib/wpscan/version.rb +1 -1
- metadata +22 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8351294d3eedeff4b00824a523541cac828c5d43a1852900e606dc22c7676f5
|
4
|
+
data.tar.gz: d589d01854ee40dd87e073ab636745607434d7fdd1f3e48c269276c68a3fe918
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6845cdd64b1f715a80b3c932da5e072b465dea4d1af6ec5db67de2585ce8f3366c19ba40071a0de7a6887c79b5db87631630fbad5df4e9de174e29d84afdb5f5
|
7
|
+
data.tar.gz: 3bb25f129cb00c8a0087d32f88c1423de1bc2d014268d45956e7052134242c3fadeba08cdb183596ce556c76036a08534efc8ef7395a2023d0d614d49185af7c
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
<p align="center">
|
17
17
|
<a href="https://badge.fury.io/rb/wpscan" target="_blank"><img src="https://badge.fury.io/rb/wpscan.svg"></a>
|
18
|
-
<a href="https://
|
18
|
+
<a href="https://github.com/wpscanteam/wpscan/actions?query=workflow%3ABuild" target="_blank"><img src="https://github.com/wpscanteam/wpscan/workflows/Build/badge.svg"></a>
|
19
19
|
<a href="https://codeclimate.com/github/wpscanteam/wpscan" target="_blank"><img src="https://codeclimate.com/github/wpscanteam/wpscan/badges/gpa.svg"></a>
|
20
20
|
</p>
|
21
21
|
|
@@ -18,9 +18,7 @@ module WPScan
|
|
18
18
|
target.content_dir = ParsedCli.wp_content_dir if ParsedCli.wp_content_dir
|
19
19
|
target.plugins_dir = ParsedCli.wp_plugins_dir if ParsedCli.wp_plugins_dir
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
raise Error::WpContentDirNotDetected
|
21
|
+
raise Error::WpContentDirNotDetected unless target.content_dir
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
@@ -9,7 +9,7 @@ module WPScan
|
|
9
9
|
def passive(_opts = {})
|
10
10
|
pattern = %r{#{target.content_dir}/mu\-plugins/}i
|
11
11
|
|
12
|
-
target.in_scope_uris(target.homepage_res) do |uri|
|
12
|
+
target.in_scope_uris(target.homepage_res, '(//@href|//@src)[contains(., "mu-plugins")]') do |uri|
|
13
13
|
next unless uri.path&.match?(pattern)
|
14
14
|
|
15
15
|
url = target.url('wp-content/mu-plugins/')
|
@@ -20,7 +20,7 @@ module WPScan
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def passive_from_css_href(res, opts)
|
23
|
-
target.in_scope_uris(res, '//
|
23
|
+
target.in_scope_uris(res, '//link/@href[contains(., "style.css")]') do |uri|
|
24
24
|
next unless uri.path =~ %r{/themes/([^\/]+)/style.css\z}i
|
25
25
|
|
26
26
|
return create_theme(Regexp.last_match[1], uri.to_s, opts)
|
@@ -71,11 +71,13 @@ module WPScan
|
|
71
71
|
return username, 'Display Name', 50 if username
|
72
72
|
end
|
73
73
|
|
74
|
-
# @param [ String ]
|
74
|
+
# @param [ String, Addressable::URI ] uri
|
75
75
|
#
|
76
76
|
# @return [ String, nil ]
|
77
|
-
def username_from_author_url(
|
78
|
-
|
77
|
+
def username_from_author_url(uri)
|
78
|
+
uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI)
|
79
|
+
|
80
|
+
uri.path[%r{/author/([^/\b]+)/?}i, 1]
|
79
81
|
end
|
80
82
|
|
81
83
|
# @param [ Typhoeus::Response ] res
|
@@ -83,12 +85,12 @@ module WPScan
|
|
83
85
|
# @return [ String, nil ] The username found
|
84
86
|
def username_from_response(res)
|
85
87
|
# Permalink enabled
|
86
|
-
target.in_scope_uris(res, '
|
87
|
-
username = username_from_author_url(uri
|
88
|
+
target.in_scope_uris(res, '//@href[contains(., "author/")]') do |uri|
|
89
|
+
username = username_from_author_url(uri)
|
88
90
|
return username if username
|
89
91
|
end
|
90
92
|
|
91
|
-
# No permalink
|
93
|
+
# No permalink, TODO Maybe use xpath to extract the classes ?
|
92
94
|
res.body[/<body class="archive author author-([^\s]+)[ "]/i, 1]
|
93
95
|
end
|
94
96
|
|
@@ -45,7 +45,7 @@ module WPScan
|
|
45
45
|
def potential_usernames(res)
|
46
46
|
usernames = []
|
47
47
|
|
48
|
-
target.in_scope_uris(res, '//a/@href') do |uri, node|
|
48
|
+
target.in_scope_uris(res, '//a/@href[contains(., "author")]') do |uri, node|
|
49
49
|
if uri.path =~ %r{/author/([^/\b]+)/?\z}i
|
50
50
|
usernames << [Regexp.last_match[1], 'Author Pattern', 100]
|
51
51
|
elsif /author=[0-9]+/.match?(uri.query)
|
@@ -8,11 +8,15 @@ module WPScan
|
|
8
8
|
# @param [ String ] type plugins / themes
|
9
9
|
# @param [ Boolean ] uniq Wether or not to apply the #uniq on the results
|
10
10
|
#
|
11
|
-
# @return [Array<String> ] The plugins/themes detected in the href, src attributes of the
|
11
|
+
# @return [ Array<String> ] The plugins/themes detected in the href, src attributes of the page
|
12
12
|
def items_from_links(type, uniq = true)
|
13
13
|
found = []
|
14
|
+
xpath = format(
|
15
|
+
'(//@href|//@src|//@data-src)[contains(., "%s")]',
|
16
|
+
type == 'plugins' ? target.plugins_dir : target.content_dir
|
17
|
+
)
|
14
18
|
|
15
|
-
target.in_scope_uris(page_res) do |uri|
|
19
|
+
target.in_scope_uris(page_res, xpath) do |uri|
|
16
20
|
next unless uri.to_s =~ item_attribute_pattern(type)
|
17
21
|
|
18
22
|
slug = Regexp.last_match[1]&.strip
|
data/lib/wpscan/db/updater.rb
CHANGED
@@ -67,13 +67,13 @@ module WPScan
|
|
67
67
|
# @return [ Hash ] The params for Typhoeus::Request
|
68
68
|
# @note Those params can't be overriden by CLI options
|
69
69
|
def request_params
|
70
|
-
@request_params ||=
|
70
|
+
@request_params ||= Browser.instance.default_connect_request_params.merge(
|
71
71
|
timeout: 600,
|
72
72
|
connecttimeout: 300,
|
73
73
|
accept_encoding: 'gzip, deflate',
|
74
74
|
cache_ttl: 0,
|
75
|
-
headers: { 'User-Agent' => Browser.instance.default_user_agent
|
76
|
-
|
75
|
+
headers: { 'User-Agent' => Browser.instance.default_user_agent }
|
76
|
+
)
|
77
77
|
end
|
78
78
|
|
79
79
|
# @return [ String ] The raw file URL associated with the given filename
|
@@ -85,7 +85,7 @@ module WPScan
|
|
85
85
|
def remote_file_checksum(filename)
|
86
86
|
url = "#{remote_file_url(filename)}.sha512"
|
87
87
|
|
88
|
-
res =
|
88
|
+
res = Typhoeus.get(url, request_params)
|
89
89
|
raise Error::Download, res if res.timed_out? || res.code != 200
|
90
90
|
|
91
91
|
res.body.chomp
|
@@ -126,7 +126,7 @@ module WPScan
|
|
126
126
|
file_path = local_file_path(filename)
|
127
127
|
file_url = remote_file_url(filename)
|
128
128
|
|
129
|
-
res =
|
129
|
+
res = Typhoeus.get(file_url, request_params)
|
130
130
|
raise Error::Download, res if res.timed_out? || res.code != 200
|
131
131
|
|
132
132
|
File.open(file_path, 'wb') { |f| f.write(res.body) }
|
data/lib/wpscan/db/vuln_api.rb
CHANGED
@@ -23,7 +23,8 @@ module WPScan
|
|
23
23
|
return {} unless token
|
24
24
|
return {} if path.end_with?('/latest') # Remove this when api/v4 is up
|
25
25
|
|
26
|
-
|
26
|
+
# Typhoeus.get is used rather than Browser.get to avoid merging irrelevant params from the CLI
|
27
|
+
res = Typhoeus.get(uri.join(path), default_request_params.merge(params))
|
27
28
|
|
28
29
|
return {} if res.code == 404 # This is for API inconsistencies when dots in path
|
29
30
|
return JSON.parse(res.body) if NON_ERROR_CODES.include?(res.code)
|
@@ -65,16 +66,14 @@ module WPScan
|
|
65
66
|
end
|
66
67
|
|
67
68
|
# @return [ Hash ]
|
68
|
-
|
69
|
-
|
69
|
+
# @note Those params can not be overriden by CLI options
|
70
|
+
def self.default_request_params
|
71
|
+
Browser.instance.default_connect_request_params.merge(
|
70
72
|
headers: {
|
71
|
-
'Host' => uri.host, # Reset in case user provided a --vhost for the target
|
72
|
-
'Referer' => nil, # Removes referer set by the cmsscanner to the target url
|
73
|
-
'CF-Connecting-IP' => nil, # Removes in case user provided one for the target
|
74
73
|
'User-Agent' => Browser.instance.default_user_agent,
|
75
74
|
'Authorization' => "Token token=#{token}"
|
76
75
|
}
|
77
|
-
|
76
|
+
)
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
@@ -32,8 +32,12 @@ module WPScan
|
|
32
32
|
|
33
33
|
if %i[mixed aggressive].include?(detection_mode)
|
34
34
|
%w[wp-admin/install.php wp-login.php].each do |path|
|
35
|
-
|
36
|
-
|
35
|
+
res = Browser.get_and_follow_location(url(path))
|
36
|
+
|
37
|
+
next unless res.code == 200
|
38
|
+
|
39
|
+
in_scope_uris(res, '//link/@href|//script/@src') do |uri|
|
40
|
+
return true if WORDPRESS_PATTERN.match?(uri.path)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
@@ -44,7 +48,7 @@ module WPScan
|
|
44
48
|
# @param [ Typhoeus::Response ] response
|
45
49
|
# @return [ Boolean ]
|
46
50
|
def wordpress_from_meta_comments_or_scripts?(response)
|
47
|
-
in_scope_uris(response) do |uri|
|
51
|
+
in_scope_uris(response, '//link/@href|//script/@src|//img/@src') do |uri|
|
48
52
|
return true if WORDPRESS_PATTERN.match?(uri.path) || WP_JSON_OEMBED_PATTERN.match?(uri.path)
|
49
53
|
end
|
50
54
|
|
@@ -100,8 +104,9 @@ module WPScan
|
|
100
104
|
|
101
105
|
unless content_dir
|
102
106
|
pattern = %r{https?://s\d\.wp\.com#{WORDPRESS_PATTERN}}i.freeze
|
107
|
+
xpath = '(//@href|//@src)[contains(., "wp.com")]'
|
103
108
|
|
104
|
-
uris_from_page(homepage_res) do |uri|
|
109
|
+
uris_from_page(homepage_res, xpath) do |uri|
|
105
110
|
return true if uri.to_s.match?(pattern)
|
106
111
|
end
|
107
112
|
end
|
@@ -105,9 +105,10 @@ module WPScan
|
|
105
105
|
|
106
106
|
# url_pattern is from CMSScanner::Target
|
107
107
|
pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i
|
108
|
+
xpath = '(//@src|//@href|//@data-src)[contains(., "xmlrpc.php") or contains(., "wp-includes/")]'
|
108
109
|
|
109
110
|
[homepage_res, error_404_res].each do |page_res|
|
110
|
-
in_scope_uris(page_res) do |uri|
|
111
|
+
in_scope_uris(page_res, xpath) do |uri|
|
111
112
|
return @sub_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
|
112
113
|
end
|
113
114
|
end
|
data/lib/wpscan/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wpscan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.7.
|
4
|
+
version: 3.7.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WPScanTeam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cms_scanner
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.8.
|
19
|
+
version: 0.8.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.8.
|
26
|
+
version: 0.8.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.6'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: coveralls
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.8.0
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.8.0
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: memory_profiler
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +100,14 @@ dependencies:
|
|
114
100
|
requirements:
|
115
101
|
- - "~>"
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
103
|
+
version: 0.80.0
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
108
|
- - "~>"
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.
|
110
|
+
version: 0.80.0
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: rubocop-performance
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +128,28 @@ dependencies:
|
|
142
128
|
requirements:
|
143
129
|
- - "~>"
|
144
130
|
- !ruby/object:Gem::Version
|
145
|
-
version: 0.
|
131
|
+
version: 0.18.2
|
146
132
|
type: :development
|
147
133
|
prerelease: false
|
148
134
|
version_requirements: !ruby/object:Gem::Requirement
|
149
135
|
requirements:
|
150
136
|
- - "~>"
|
151
137
|
- !ruby/object:Gem::Version
|
152
|
-
version: 0.
|
138
|
+
version: 0.18.2
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: simplecov-lcov
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.8.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.8.0
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: stackprof
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|