Compare commits

...

46 Commits

Author SHA1 Message Date
erwanlr
abdf285c69 Bumps version 2019-01-11 11:53:11 +00:00
erwanlr
fd4da23d4f Creates simplecov exetrnal config 2019-01-11 11:13:49 +00:00
erwanlr
bb8f58c83b Updates deps 2019-01-11 11:12:34 +00:00
erwanlr
077da6ae86 Moves require spec_helper to config file 2019-01-11 11:11:56 +00:00
erwanlr
d5222d7e9a Adds DFs 2019-01-07 14:58:03 +00:00
erwanlr
01702c127b Tries to fix Travis again 2019-01-07 11:47:58 +00:00
Erwan
87902cbfb4 Tries to fix Travis builds 2019-01-07 10:54:05 +00:00
ethicalhack3r
fcaa393ffe Update license 2019-01-07 10:54:24 +01:00
ethicalhack3r
18bac6e792 Update to Ruby 2.6.0 2019-01-07 10:16:32 +01:00
erwanlr
9a21efebe3 Updates DFs 2018-12-28 22:50:05 +00:00
erwanlr
357182ef17 Adds DFs 2018-12-28 22:43:41 +00:00
erwanlr
5fad540a4c Bumps version 2018-12-28 13:35:01 +00:00
erwanlr
c1fc153420 Updates Deps, ref #1266 2018-12-28 11:17:37 +00:00
erwanlr
73a1974f85 Bumps version 2018-12-13 22:16:45 +00:00
erwanlr
dec73c21b6 Fixes #1264 2018-12-13 22:11:37 +00:00
erwanlr
46a00cc864 Adds DFs 2018-12-07 14:59:03 +00:00
erwanlr
62455be165 Deletes useless specs 2018-12-06 22:54:17 +00:00
erwanlr
17ef5ef918 Reverts spec changes 2018-12-06 22:52:10 +00:00
erwanlr
922b6fffd0 Fixes specs 2018-12-06 21:46:13 +00:00
erwanlr
b47bf006d0 Removes useless spec 2018-12-06 21:44:54 +00:00
erwanlr
d60269f4bc Adds DFs 2018-12-06 21:41:00 +00:00
erwanlr
1ce057a78e Adds DFs 2018-12-06 15:54:15 +00:00
erwanlr
a0fe04b990 Fixes #1260 2018-12-06 02:51:23 +00:00
erwanlr
31c9172e19 Removes false positive DFs 2018-12-03 15:37:09 +00:00
erwanlr
7f23cbef71 Adds DFs 2018-12-03 15:08:56 +00:00
Ryan Dewhurst
4884defaed Add some references to interesting findings 2018-11-22 15:04:43 +01:00
erwanlr
3039218c40 Adds DFs 2018-11-18 11:45:58 +00:00
erwanlr
8bbc2f32ae Bumps version 2018-11-12 16:11:14 +00:00
erwanlr
4ca46ab3ba Fixes #1241 2018-11-12 15:57:17 +00:00
erwanlr
7442c72d01 Fixes #1244 2018-11-08 20:28:24 +00:00
erwanlr
01cd8350bc Fixes 1242 2018-11-08 19:16:47 +00:00
erwanlr
8b5ea589db Ref #1241 2018-11-08 19:04:40 +00:00
Erwan
3555ca1d1e Merge pull request #1223 from taha-abbasi/patch-1
Added username enumeration instructions
2018-11-07 11:40:41 +00:00
erwanlr
ae034a47ed Removes FP DFs 2018-11-03 19:36:55 +00:00
erwanlr
ec3862c930 Adds DFs 2018-11-03 19:27:52 +00:00
erwanlr
c63804d1c5 Bumps version 2018-11-02 19:51:57 +00:00
erwanlr
c5e6752f75 Fixes #1232 2018-11-02 19:33:38 +00:00
erwanlr
e4f3e9d11c Fixes spec 2018-11-02 17:52:43 +00:00
erwanlr
f3713536b9 Adds missing spec files 2018-11-02 16:36:10 +00:00
erwanlr
fb751c0a51 Fixes #1228 2018-11-02 13:40:46 +00:00
erwanlr
9d3464055a Updates deps 2018-11-02 08:36:22 +00:00
erwanlr
0fea814f5d Fixes #1237 2018-11-02 08:33:21 +00:00
Ryan Dewhurst
ae70a6df9d Merge pull request #1233 from FenrirSec/fix_wordpress_hosted
Fixed pattern matching on target.wordpress_hosted
2018-10-29 13:46:50 +01:00
lp1
4afc756ccd Added spec for the new regex 2018-10-29 12:11:28 +01:00
lp1
adc5841261 Fixed too restrictive pattern matching on target.wordpress_hosted attribute 2018-10-25 18:09:04 +02:00
Taha Abbasi
804a8c34c6 Added username enumeration instructions
Added username enumeration instructions, and username enumeration with range instructions for use with Docker and without.
2018-10-08 13:39:11 -04:00
234 changed files with 35691 additions and 309 deletions

1
.rspec
View File

@@ -1,2 +1,3 @@
--color --color
--fail-fast --fail-fast
--require spec_helper

View File

@@ -1 +1 @@
2.5.3 2.6.0

4
.simplecov Normal file
View File

@@ -0,0 +1,4 @@
SimpleCov.start do
add_filter '/spec/'
add_filter 'helper'
end

View File

@@ -20,10 +20,11 @@ rvm:
- 2.5.1 - 2.5.1
- 2.5.2 - 2.5.2
- 2.5.3 - 2.5.3
- 2.6.0
- ruby-head - ruby-head
before_install: before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- "gem update --system" - gem update --system
matrix: matrix:
allow_failures: allow_failures:
- rvm: ruby-head - rvm: ruby-head

View File

@@ -1,6 +1,6 @@
WPScan Public Source License WPScan Public Source License
The WPScan software (henceforth referred to simply as "WPScan") is dual-licensed - Copyright 2011-2018 WPScan Team. The WPScan software (henceforth referred to simply as "WPScan") is dual-licensed - Copyright 2011-2019 WPScan Team.
Cases that include commercialization of WPScan require a commercial, non-free license. Otherwise, WPScan can be used without charge under the terms set out below. Cases that include commercialization of WPScan require a commercial, non-free license. Otherwise, WPScan can be used without charge under the terms set out below.
@@ -8,7 +8,7 @@ Cases that include commercialization of WPScan require a commercial, non-free li
1.1 “License” means this document. 1.1 “License” means this document.
1.2 “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns WPScan. 1.2 “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns WPScan.
1.3 “WPScan Team” means WPScans core developers, an updated list of whom can be found within the CREDITS file. 1.3 “WPScan Team” means WPScans core developers.
2. Commercialization 2. Commercialization
@@ -29,8 +29,6 @@ Example cases which do not require a commercial license, and thus fall under the
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org. If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org.
We may grant commercial licenses at no monetary cost at our own discretion if the commercial usage is deemed by the WPScan Team to significantly benefit WPScan.
Free-use Terms and Conditions; Free-use Terms and Conditions;
3. Redistribution 3. Redistribution

View File

@@ -35,6 +35,17 @@ bundle install && rake install
Pull the repo with ```docker pull wpscanteam/wpscan``` Pull the repo with ```docker pull wpscanteam/wpscan```
Enumerating usernames
```
docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u
```
Enumerating a range of usernames
```
docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u1-100
```
** replace u1-100 with a range of your choice.
# Usage # Usage
```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. ```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.
@@ -69,6 +80,19 @@ url: 'http://target.tld'
Running ```wpscan``` in the current directory (pwd), is the same as ```wpscan -v --proxy socks5://127.0.0.1:9090 --url http://target.tld``` Running ```wpscan``` in the current directory (pwd), is the same as ```wpscan -v --proxy socks5://127.0.0.1:9090 --url http://target.tld```
Enumerating usernames
```
wpscan --url https://target.tld/ --enumerate u
```
Enumerating a range of usernames
```
wpscan --url https://target.tld/ --enumerate u1-100
```
** replace u1-100 with a range of your choice.
# PROJECT HOME # PROJECT HOME
[https://wpscan.org](https://wpscan.org) [https://wpscan.org](https://wpscan.org)
@@ -81,7 +105,7 @@ Running ```wpscan``` in the current directory (pwd), is the same as ```wpscan -v
## WPScan Public Source License ## WPScan Public Source License
The WPScan software (henceforth referred to simply as "WPScan") is dual-licensed - Copyright 2011-2018 WPScan Team. The WPScan software (henceforth referred to simply as "WPScan") is dual-licensed - Copyright 2011-2019 WPScan Team.
Cases that include commercialization of WPScan require a commercial, non-free license. Otherwise, WPScan can be used without charge under the terms set out below. Cases that include commercialization of WPScan require a commercial, non-free license. Otherwise, WPScan can be used without charge under the terms set out below.
@@ -91,7 +115,7 @@ Cases that include commercialization of WPScan require a commercial, non-free li
1.2 "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns WPScan. 1.2 "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns WPScan.
1.3 "WPScan Team" means WPScans core developers, an updated list of whom can be found within the CREDITS file. 1.3 "WPScan Team" means WPScans core developers.
### 2. Commercialization ### 2. Commercialization
@@ -112,8 +136,6 @@ Example cases which do not require a commercial license, and thus fall under the
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org. If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org.
We may grant commercial licenses at no monetary cost at our own discretion if the commercial usage is deemed by the WPScan Team to significantly benefit WPScan.
Free-use Terms and Conditions; Free-use Terms and Conditions;
### 3. Redistribution ### 3. Redistribution

View File

@@ -11,7 +11,7 @@ module WPScan
return unless [200, 403].include?(res.code) && !target.homepage_or_404?(res) return unless [200, 403].include?(res.code) && !target.homepage_or_404?(res)
WPScan::InterestingFinding.new( WPScan::BackupDB.new(
url, url,
confidence: 70, confidence: 70,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -9,9 +9,10 @@ module WPScan
return unless target.debug_log?(path) return unless target.debug_log?(path)
WPScan::InterestingFinding.new( WPScan::DebugLog.new(
target.url(path), target.url(path),
confidence: 100, found_by: DIRECT_ACCESS confidence: 100, found_by: DIRECT_ACCESS,
references: { url: 'https://codex.wordpress.org/Debugging_in_WordPress' }
) )
end end
end end

View File

@@ -10,7 +10,7 @@ module WPScan
return unless res.body =~ /DUPLICATOR INSTALL-LOG/ return unless res.body =~ /DUPLICATOR INSTALL-LOG/
WPScan::InterestingFinding.new( WPScan::DuplicatorInstallerLog.new(
url, url,
confidence: 100, confidence: 100,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -10,7 +10,7 @@ module WPScan
return unless res.code == 200 && !target.homepage_or_404?(res) return unless res.code == 200 && !target.homepage_or_404?(res)
WPScan::InterestingFinding.new( WPScan::EmergencyPwdResetScript.new(
url, url,
confidence: res.body =~ /password/i ? 100 : 40, confidence: res.body =~ /password/i ? 100 : 40,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -10,11 +10,12 @@ module WPScan
return if fpd_entries.empty? return if fpd_entries.empty?
WPScan::InterestingFinding.new( WPScan::FullPathDisclosure.new(
target.url(path), target.url(path),
confidence: 100, confidence: 100,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,
interesting_entries: fpd_entries interesting_entries: fpd_entries,
references: { url: 'https://www.owasp.org/index.php/Full_Path_Disclosure' }
) )
end end
end end

View File

@@ -12,7 +12,7 @@ module WPScan
url = target.url('wp-content/mu-plugins/') url = target.url('wp-content/mu-plugins/')
return WPScan::InterestingFinding.new( return WPScan::MuPlugins.new(
url, url,
confidence: 70, confidence: 70,
found_by: 'URLs In Homepage (Passive Detection)', found_by: 'URLs In Homepage (Passive Detection)',
@@ -35,7 +35,7 @@ module WPScan
target.mu_plugins = true target.mu_plugins = true
WPScan::InterestingFinding.new( WPScan::MuPlugins.new(
url, url,
confidence: 80, confidence: 80,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -15,7 +15,7 @@ module WPScan
target.multisite = true target.multisite = true
WPScan::InterestingFinding.new( WPScan::Multisite.new(
url, url,
confidence: 100, confidence: 100,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -10,7 +10,7 @@ module WPScan
res = Browser.get(url) res = Browser.get(url)
if res.code == 200 && res.body =~ /wordpress/i if res.code == 200 && res.body =~ /wordpress/i
return WPScan::InterestingFinding.new(url, confidence: 100, found_by: DIRECT_ACCESS) return WPScan::Readme.new(url, confidence: 100, found_by: DIRECT_ACCESS)
end end
end end
nil nil

View File

@@ -18,7 +18,7 @@ module WPScan
target.registration_enabled = true target.registration_enabled = true
WPScan::InterestingFinding.new( WPScan::Registration.new(
res.effective_url, res.effective_url,
confidence: 100, confidence: 100,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -11,7 +11,7 @@ module WPScan
return unless res.code == 200 && res.headers['Content-Type'] =~ %r{\Aapplication/zip}i return unless res.code == 200 && res.headers['Content-Type'] =~ %r{\Aapplication/zip}i
WPScan::InterestingFinding.new( WPScan::TmmDbMigrate.new(
url, url,
confidence: 100, confidence: 100,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -11,7 +11,7 @@ module WPScan
url = target.url(path) url = target.url(path)
WPScan::InterestingFinding.new( WPScan::UploadDirectoryListing.new(
url, url,
confidence: 100, confidence: 100,
found_by: DIRECT_ACCESS, found_by: DIRECT_ACCESS,

View File

@@ -3,7 +3,7 @@ module WPScan
module InterestingFindings module InterestingFindings
# UploadSQLDump finder # UploadSQLDump finder
class UploadSQLDump < CMSScanner::Finders::Finder class UploadSQLDump < CMSScanner::Finders::Finder
SQL_PATTERN = /(?:(?:(?:DROP|CREATE) TABLE)|INSERT INTO)/ SQL_PATTERN = /(?:(?:(?:DROP|CREATE) TABLE)|INSERT INTO)/.freeze
# @return [ InterestingFinding ] # @return [ InterestingFinding ]
def aggressive(_opts = {}) def aggressive(_opts = {})
@@ -12,7 +12,7 @@ module WPScan
return unless res.code == 200 && res.body =~ SQL_PATTERN return unless res.code == 200 && res.body =~ SQL_PATTERN
WPScan::InterestingFinding.new( WPScan::UploadSQLDump.new(
url, url,
confidence: 100, confidence: 100,
found_by: DIRECT_ACCESS found_by: DIRECT_ACCESS

View File

@@ -3,9 +3,9 @@ module WPScan
module MainTheme module MainTheme
# From the WooFramework meta generators # From the WooFramework meta generators
class WooFrameworkMetaGenerator < CMSScanner::Finders::Finder class WooFrameworkMetaGenerator < CMSScanner::Finders::Finder
THEME_PATTERN = %r{<meta name="generator" content="([^\s"]+)\s?([^"]+)?"\s+/?>} THEME_PATTERN = %r{<meta name="generator" content="([^\s"]+)\s?([^"]+)?"\s+/?>}.freeze
FRAMEWORK_PATTERN = %r{<meta name="generator" content="WooFramework\s?([^"]+)?"\s+/?>} FRAMEWORK_PATTERN = %r{<meta name="generator" content="WooFramework\s?([^"]+)?"\s+/?>}.freeze
PATTERN = /#{THEME_PATTERN}\s+#{FRAMEWORK_PATTERN}/i PATTERN = /#{THEME_PATTERN}\s+#{FRAMEWORK_PATTERN}/i.freeze
def passive(opts = {}) def passive(opts = {})
return unless target.homepage_res.body =~ PATTERN return unless target.homepage_res.body =~ PATTERN

View File

@@ -4,6 +4,7 @@ require_relative 'users/oembed_api'
require_relative 'users/rss_generator' require_relative 'users/rss_generator'
require_relative 'users/author_id_brute_forcing' require_relative 'users/author_id_brute_forcing'
require_relative 'users/login_error_messages' require_relative 'users/login_error_messages'
require_relative 'users/yoast_seo_author_sitemap.rb'
module WPScan module WPScan
module Finders module Finders
@@ -19,6 +20,7 @@ module WPScan
Users::WpJsonApi.new(target) << Users::WpJsonApi.new(target) <<
Users::OembedApi.new(target) << Users::OembedApi.new(target) <<
Users::RSSGenerator.new(target) << Users::RSSGenerator.new(target) <<
Users::YoastSeoAuthorSitemap.new(target) <<
Users::AuthorIdBruteForcing.new(target) << Users::AuthorIdBruteForcing.new(target) <<
Users::LoginErrorMessages.new(target) Users::LoginErrorMessages.new(target)
end end

View File

@@ -14,29 +14,35 @@ module WPScan
# @param [ Hash ] opts # @param [ Hash ] opts
# #
# TODO: make this code pretty :x
#
# @return [ Array<User> ] # @return [ Array<User> ]
def aggressive(_opts = {}) def aggressive(_opts = {})
found = []
found_by_msg = 'Oembed API - %s (Aggressive Detection)'
oembed_data = JSON.parse(Browser.get(api_url).body) oembed_data = JSON.parse(Browser.get(api_url).body)
details = user_details_from_oembed_data(oembed_data)
return [] unless details
[CMSScanner::User.new(details[0],
found_by: format(found_by_msg, details[1]),
confidence: details[2],
interesting_entries: [api_url])]
rescue JSON::ParserError
[]
end
def user_details_from_oembed_data(oembed_data)
return unless oembed_data
if oembed_data['author_url'] =~ %r{/author/([^/]+)/?\z} if oembed_data['author_url'] =~ %r{/author/([^/]+)/?\z}
details = [Regexp.last_match[1], 'Author URL', 90] details = [Regexp.last_match[1], 'Author URL', 90]
elsif oembed_data['author_name'] && !oembed_data['author_name'].empty? elsif oembed_data['author_name'] && !oembed_data['author_name'].empty?
details = [oembed_data['author_name'].delete(' '), 'Author Name', 70] details = [oembed_data['author_name'], 'Author Name', 70]
end end
return unless details details
end
found << CMSScanner::User.new(details[0], def found_by_msg
found_by: format(found_by_msg, details[1]), 'Oembed API - %s (Aggressive Detection)'
confidence: details[2],
interesting_entries: [api_url])
rescue JSON::ParserError
found
end end
# @return [ String ] The URL of the API listing the Users # @return [ String ] The URL of the API listing the Users

View File

@@ -0,0 +1,34 @@
module WPScan
module Finders
module Users
# The YOAST SEO plugin has an author-sitemap.xml which can leak usernames
# See https://github.com/wpscanteam/wpscan/issues/1228
class YoastSeoAuthorSitemap < CMSScanner::Finders::Finder
# @param [ Hash ] opts
#
# @return [ Array<User> ]
def aggressive(_opts = {})
found = []
Browser.get(sitemap_url).html.xpath('//url/loc').each do |user_tag|
username = user_tag.text.to_s[%r{/author/([^\/]+)/}, 1]
next unless username && !username.strip.empty?
found << CMSScanner::User.new(username,
found_by: found_by,
confidence: 100,
interesting_entries: [sitemap_url])
end
found
end
# @return [ String ] The URL of the author-sitemap
def sitemap_url
@sitemap_url ||= target.url('author-sitemap.xml')
end
end
end
end
end

View File

@@ -3,4 +3,43 @@ module WPScan
class InterestingFinding < CMSScanner::InterestingFinding class InterestingFinding < CMSScanner::InterestingFinding
include References include References
end end
#
# Empty classes for the #type to be correctly displayed (as taken from the self.class from the parent)
#
class BackupDB < InterestingFinding
end
class DebugLog < InterestingFinding
end
class DuplicatorInstallerLog < InterestingFinding
end
class EmergencyPwdResetScript < InterestingFinding
end
class FullPathDisclosure < InterestingFinding
end
class MuPlugins < InterestingFinding
end
class Multisite < InterestingFinding
end
class Readme < InterestingFinding
end
class Registration < InterestingFinding
end
class TmmDbMigrate < InterestingFinding
end
class UploadDirectoryListing < InterestingFinding
end
class UploadSQLDump < InterestingFinding
end
end end

View File

@@ -53,7 +53,12 @@ module WPScan
# @return [ String ] # @return [ String ]
def release_date def release_date
@release_date ||= db_data['release_date'] @release_date ||= db_data['release_date'] || 'Unknown'
end
# @return [ String ]
def status
@status ||= db_data['status'] || 'Unknown'
end end
end end
end end

View File

@@ -1,5 +1,5 @@
<% if @version -%> <% if @version -%>
<%= info_icon %> WordPress version <%= @version.number %> identified (Released on <%= @version.release_date %>). <%= info_icon %> WordPress version <%= @version.number %> identified (<%= @version.status.capitalize %>, released on <%= @version.release_date %>).
<%= render('@finding', item: @version) -%> <%= render('@finding', item: @version) -%>
<% else -%> <% else -%>
<%= notice_icon %> The WordPress version could not be detected. <%= notice_icon %> The WordPress version could not be detected.

View File

@@ -2,6 +2,7 @@
"version": { "version": {
"number": <%= @version.number.to_json %>, "number": <%= @version.number.to_json %>,
"release_date": <%= @version.release_date.to_json %>, "release_date": <%= @version.release_date.to_json %>,
"status": <%= @version.status.to_json %>,
<%= render('@finding', item: @version) -%> <%= render('@finding', item: @version) -%>
}, },
<% else -%> <% else -%>

View File

@@ -16,9 +16,7 @@ require 'securerandom'
require 'wpscan/helper' require 'wpscan/helper'
require 'wpscan/db' require 'wpscan/db'
require 'wpscan/version' require 'wpscan/version'
require 'wpscan/errors/wordpress' require 'wpscan/errors'
require 'wpscan/errors/http'
require 'wpscan/errors/update'
require 'wpscan/browser' require 'wpscan/browser'
require 'wpscan/target' require 'wpscan/target'
require 'wpscan/finders' require 'wpscan/finders'

View File

@@ -60,12 +60,11 @@ module WPScan
end end
# @return [ Hash ] The params for Typhoeus::Request # @return [ Hash ] The params for Typhoeus::Request
# @note Those params can't be overriden by CLI options
def request_params def request_params
{ {
ssl_verifyhost: 2, timeout: 600,
ssl_verifypeer: true, connecttimeout: 300,
timeout: 300,
connecttimeout: 120,
accept_encoding: 'gzip, deflate', accept_encoding: 'gzip, deflate',
cache_ttl: 0 cache_ttl: 0
} }

8
lib/wpscan/errors.rb Normal file
View File

@@ -0,0 +1,8 @@
module WPScan
class Error < StandardError
end
end
require_relative 'errors/http'
require_relative 'errors/update'
require_relative 'errors/wordpress'

View File

@@ -1,6 +1,6 @@
module WPScan module WPScan
# HTTP Error # HTTP Error
class HTTPError < StandardError class HTTPError < Error
attr_reader :response attr_reader :response
# @param [ Typhoeus::Response ] res # @param [ Typhoeus::Response ] res

View File

@@ -1,6 +1,6 @@
module WPScan module WPScan
# Error raised when there is a missing DB file and --no-update supplied # Error raised when there is a missing DB file and --no-update supplied
class MissingDatabaseFile < StandardError class MissingDatabaseFile < Error
def to_s def to_s
'Update required, you can not run a scan if a database file is missing.' 'Update required, you can not run a scan if a database file is missing.'
end end

View File

@@ -1,20 +1,20 @@
module WPScan module WPScan
# WordPress hosted (*.wordpress.com) # WordPress hosted (*.wordpress.com)
class WordPressHostedError < StandardError class WordPressHostedError < Error
def to_s def to_s
'Scanning *.wordpress.com hosted blogs is not supported.' 'Scanning *.wordpress.com hosted blogs is not supported.'
end end
end end
# Not WordPress Error # Not WordPress Error
class NotWordPressError < StandardError class NotWordPressError < Error
def to_s def to_s
'The remote website is up, but does not seem to be running WordPress.' 'The remote website is up, but does not seem to be running WordPress.'
end end
end end
# Invalid Wp Version (used in the WpVersion#new) # Invalid Wp Version (used in the WpVersion#new)
class InvalidWordPressVersion < StandardError class InvalidWordPressVersion < Error
def to_s def to_s
'The WordPress version is invalid' 'The WordPress version is invalid'
end end

View File

@@ -9,7 +9,7 @@ module WPScan
module WordPress module WordPress
include CMSScanner::Target::Platform::PHP include CMSScanner::Target::Platform::PHP
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i.freeze
# These methods are used in the associated interesting_findings finders # These methods are used in the associated interesting_findings finders
# to keep the boolean state of the finding rather than re-check the whole thing again # to keep the boolean state of the finding rather than re-check the whole thing again
@@ -41,7 +41,7 @@ module WPScan
end end
def wordpress_hosted? def wordpress_hosted?
uri.host =~ /wordpress.com$/i ? true : false uri.host =~ /\.wordpress\.com$/i ? true : false
end end
# @param [ String ] username # @param [ String ] username

View File

@@ -1,4 +1,4 @@
# Version # Version
module WPScan module WPScan
VERSION = '3.3.2'.freeze VERSION = '3.4.3'.freeze
end end

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Controller::Aliases do describe WPScan::Controller::Aliases do
subject(:controller) { described_class.new } subject(:controller) { described_class.new }
let(:target_url) { 'http://ex.lo/' } let(:target_url) { 'http://ex.lo/' }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Controller::Core do describe WPScan::Controller::Core do
subject(:core) { described_class.new } subject(:core) { described_class.new }
let(:target_url) { 'http://ex.lo/' } let(:target_url) { 'http://ex.lo/' }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Controller::CustomDirectories do describe WPScan::Controller::CustomDirectories do
subject(:controller) { described_class.new } subject(:controller) { described_class.new }
let(:target_url) { 'http://ex.lo/' } let(:target_url) { 'http://ex.lo/' }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Controller::Enumeration do describe WPScan::Controller::Enumeration do
subject(:controller) { described_class.new } subject(:controller) { described_class.new }
let(:target_url) { 'http://wp.lab/' } let(:target_url) { 'http://wp.lab/' }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Controller::PasswordAttack do describe WPScan::Controller::PasswordAttack do
subject(:controller) { described_class.new } subject(:controller) { described_class.new }
let(:target_url) { 'http://ex.lo/' } let(:target_url) { 'http://ex.lo/' }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
def it_calls_the_formatter_with_the_correct_parameter(version) def it_calls_the_formatter_with_the_correct_parameter(version)
it 'calls the formatter with the correct parameter' do it 'calls the formatter with the correct parameter' do
expect(controller.formatter).to receive(:output) expect(controller.formatter).to receive(:output)

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::ConfigBackups::KnownFilenames do describe WPScan::Finders::ConfigBackups::KnownFilenames do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::ConfigBackups::Base do describe WPScan::Finders::ConfigBackups::Base do
subject(:config_backups) { described_class.new(target) } subject(:config_backups) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::DbExports::KnownLocations do describe WPScan::Finders::DbExports::KnownLocations do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::DbExports::Base do describe WPScan::Finders::DbExports::Base do
subject(:db_exports) { described_class.new(target) } subject(:db_exports) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::BackupDB do describe WPScan::Finders::InterestingFindings::BackupDB do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
@@ -37,7 +35,7 @@ describe WPScan::Finders::InterestingFindings::BackupDB do
after do after do
found = finder.aggressive found = finder.aggressive
expect(found).to eql WPScan::InterestingFinding.new( expect(found).to eql WPScan::BackupDB.new(
dir_url, dir_url,
confidence: 70, confidence: 70,
found_by: described_class::DIRECT_ACCESS found_by: described_class::DIRECT_ACCESS

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::DebugLog do describe WPScan::Finders::InterestingFindings::DebugLog do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
@@ -23,7 +21,7 @@ describe WPScan::Finders::InterestingFindings::DebugLog do
let(:body) { File.read(File.join(fixtures, 'debug.log')) } let(:body) { File.read(File.join(fixtures, 'debug.log')) }
it 'returns the InterestingFinding' do it 'returns the InterestingFinding' do
expect(finder.aggressive).to eql WPScan::InterestingFinding.new( expect(finder.aggressive).to eql WPScan::DebugLog.new(
log_url, log_url,
confidence: 100, confidence: 100,
found_by: described_class::DIRECT_ACCESS found_by: described_class::DIRECT_ACCESS

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::DuplicatorInstallerLog do describe WPScan::Finders::InterestingFindings::DuplicatorInstallerLog do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
@@ -24,7 +22,7 @@ describe WPScan::Finders::InterestingFindings::DuplicatorInstallerLog do
let(:body) { File.read(File.join(fixtures, filename)) } let(:body) { File.read(File.join(fixtures, filename)) }
it 'returns the InterestingFinding' do it 'returns the InterestingFinding' do
expect(finder.aggressive).to eql WPScan::InterestingFinding.new( expect(finder.aggressive).to eql WPScan::DuplicatorInstallerLog.new(
log_url, log_url,
confidence: 100, confidence: 100,
found_by: described_class::DIRECT_ACCESS found_by: described_class::DIRECT_ACCESS

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::EmergencyPwdResetScript do describe WPScan::Finders::InterestingFindings::EmergencyPwdResetScript do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::FullPathDisclosure do describe WPScan::Finders::InterestingFindings::FullPathDisclosure do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
@@ -25,7 +23,7 @@ describe WPScan::Finders::InterestingFindings::FullPathDisclosure do
it 'returns the InterestingFinding' do it 'returns the InterestingFinding' do
found = finder.aggressive found = finder.aggressive
expect(found).to eql WPScan::InterestingFinding.new( expect(found).to eql WPScan::FullPathDisclosure.new(
file_url, file_url,
confidence: 100, confidence: 100,
found_by: described_class::DIRECT_ACCESS found_by: described_class::DIRECT_ACCESS

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::MuPlugins do describe WPScan::Finders::InterestingFindings::MuPlugins do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::Multisite do describe WPScan::Finders::InterestingFindings::Multisite do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::Readme do describe WPScan::Finders::InterestingFindings::Readme do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
@@ -27,7 +25,7 @@ describe WPScan::Finders::InterestingFindings::Readme do
before { stub_request(:get, target.url(file)).to_return(body: readme) } before { stub_request(:get, target.url(file)).to_return(body: readme) }
it 'returns the expected InterestingFinding' do it 'returns the expected InterestingFinding' do
expected = WPScan::InterestingFinding.new( expected = WPScan::Readme.new(
target.url(file), target.url(file),
confidence: 100, confidence: 100,
found_by: described_class::DIRECT_ACCESS found_by: described_class::DIRECT_ACCESS

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::Registration do describe WPScan::Finders::InterestingFindings::Registration do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::TmmDbMigrate do describe WPScan::Finders::InterestingFindings::TmmDbMigrate do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::UploadDirectoryListing do describe WPScan::Finders::InterestingFindings::UploadDirectoryListing do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::UploadSQLDump do describe WPScan::Finders::InterestingFindings::UploadSQLDump do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
@@ -38,7 +36,7 @@ describe WPScan::Finders::InterestingFindings::UploadSQLDump do
let(:fixture) { 'dump.sql' } let(:fixture) { 'dump.sql' }
it 'returns the interesting findings' do it 'returns the interesting findings' do
@expected = WPScan::InterestingFinding.new( @expected = WPScan::UploadSQLDump.new(
finder.dump_url, finder.dump_url,
confidence: 100, confidence: 100,
found_by: described_class::DIRECT_ACCESS found_by: described_class::DIRECT_ACCESS

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::InterestingFindings::Base do describe WPScan::Finders::InterestingFindings::Base do
subject(:files) { described_class.new(target) } subject(:files) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::MainTheme::CssStyle do describe WPScan::Finders::MainTheme::CssStyle do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::MainTheme::UrlsInHomepage do describe WPScan::Finders::MainTheme::UrlsInHomepage do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::MainTheme::WooFrameworkMetaGenerator do describe WPScan::Finders::MainTheme::WooFrameworkMetaGenerator do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::MainTheme::Base do describe WPScan::Finders::MainTheme::Base do
subject(:main_theme) { described_class.new(target) } subject(:main_theme) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Medias::AttachmentBruteForcing do describe WPScan::Finders::Medias::AttachmentBruteForcing do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Medias::Base do describe WPScan::Finders::Medias::Base do
subject(:media) { described_class.new(target) } subject(:media) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::PluginVersion::Readme do describe WPScan::Finders::PluginVersion::Readme do
subject(:finder) { described_class.new(plugin) } subject(:finder) { described_class.new(plugin) }
let(:plugin) { WPScan::Plugin.new('spec', target) } let(:plugin) { WPScan::Plugin.new('spec', target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
# If this file is tested alone (rspec path-to-this-file), then there will be an error about # If this file is tested alone (rspec path-to-this-file), then there will be an error about
# constants not being intilialized. This is due to the Dynamic Finders. # constants not being intilialized. This is due to the Dynamic Finders.

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::BodyPattern do describe WPScan::Finders::Plugins::BodyPattern do
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::Comment do describe WPScan::Finders::Plugins::Comment do
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::ConfigParser do describe WPScan::Finders::Plugins::ConfigParser do
xit xit

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::HeaderPattern do describe WPScan::Finders::Plugins::HeaderPattern do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::JavascriptVar do describe WPScan::Finders::Plugins::JavascriptVar do
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::KnownLocations do describe WPScan::Finders::Plugins::KnownLocations do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::QueryParameter do describe WPScan::Finders::Plugins::QueryParameter do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::UrlsInHomepage do describe WPScan::Finders::Plugins::UrlsInHomepage do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::Xpath do describe WPScan::Finders::Plugins::Xpath do
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::Base do describe WPScan::Finders::Plugins::Base do
subject(:plugins) { described_class.new(target) } subject(:plugins) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::ThemeVersion::Style do describe WPScan::Finders::ThemeVersion::Style do
subject(:finder) { described_class.new(theme) } subject(:finder) { described_class.new(theme) }
let(:theme) { WPScan::Theme.new('spec', target) } let(:theme) { WPScan::Theme.new('spec', target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::ThemeVersion::WooFrameworkMetaGenerator do describe WPScan::Finders::ThemeVersion::WooFrameworkMetaGenerator do
subject(:finder) { described_class.new(theme) } subject(:finder) { described_class.new(theme) }
let(:theme) { WPScan::Theme.new(slug, target) } let(:theme) { WPScan::Theme.new(slug, target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::ThemeVersion::Base do describe WPScan::Finders::ThemeVersion::Base do
subject(:theme_version) { described_class.new(theme) } subject(:theme_version) { described_class.new(theme) }
let(:theme) { WPScan::Plugin.new(slug, target) } let(:theme) { WPScan::Plugin.new(slug, target) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Themes::KnownLocations do describe WPScan::Finders::Themes::KnownLocations do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Themes::UrlsInHomepage do describe WPScan::Finders::Themes::UrlsInHomepage do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Themes::Base do describe WPScan::Finders::Themes::Base do
subject(:themes) { described_class.new(target) } subject(:themes) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::TimthumbVersion::BadRequest do describe WPScan::Finders::TimthumbVersion::BadRequest do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Timthumb.new(url) } let(:target) { WPScan::Timthumb.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::TimthumbVersion::Base do describe WPScan::Finders::TimthumbVersion::Base do
subject(:timthumb_version) { described_class.new(target) } subject(:timthumb_version) { described_class.new(target) }
let(:target) { WPScan::Timthumb.new(url) } let(:target) { WPScan::Timthumb.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Timthumbs::KnownLocations do describe WPScan::Finders::Timthumbs::KnownLocations do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Timthumbs::Base do describe WPScan::Finders::Timthumbs::Base do
subject(:timthumb) { described_class.new(target) } subject(:timthumb) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::AuthorIdBruteForcing do describe WPScan::Finders::Users::AuthorIdBruteForcing do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::AuthorPosts do describe WPScan::Finders::Users::AuthorPosts do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::LoginErrorMessages do describe WPScan::Finders::Users::LoginErrorMessages do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::OembedApi do describe WPScan::Finders::Users::OembedApi do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
@@ -7,6 +5,59 @@ describe WPScan::Finders::Users::OembedApi do
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'oembed_api') } let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'oembed_api') }
describe '#aggressive' do describe '#aggressive' do
xit before do
allow(target).to receive(:sub_dir).and_return(false)
stub_request(:get, finder.api_url).to_return(body: body)
end
context 'when not a JSON response' do
let(:body) { '' }
its(:aggressive) { should eql([]) }
end
context 'when a JSON response' do
context 'when 404' do
let(:body) { File.read(File.join(fixtures, '404.json')) }
its(:aggressive) { should eql([]) }
end
context 'when 200' do
context 'when author_url present' do
let(:body) { File.read(File.join(fixtures, '200_author_url.json')) }
it 'returns the expected array of users' do
users = finder.aggressive
expect(users.size).to eql 1
user = users.first
expect(user.username).to eql 'admin'
expect(user.confidence).to eql 90
expect(user.found_by).to eql 'Oembed API - Author URL (Aggressive Detection)'
expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/oembed/1.0/embed?url=http://wp.lab/&format=json']
end
end
context 'when author_url not present but author_name' do
let(:body) { File.read(File.join(fixtures, '200_author_name.json')) }
it 'returns the expected array of users' do
users = finder.aggressive
expect(users.size).to eql 1
user = users.first
expect(user.username).to eql 'admin sa'
expect(user.confidence).to eql 70
expect(user.found_by).to eql 'Oembed API - Author Name (Aggressive Detection)'
expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/oembed/1.0/embed?url=http://wp.lab/&format=json']
end
end
end
end
end end
end end

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::RSSGenerator do describe WPScan::Finders::Users::RSSGenerator do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::WpJsonApi do describe WPScan::Finders::Users::WpJsonApi do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
@@ -8,7 +6,6 @@ describe WPScan::Finders::Users::WpJsonApi do
describe '#aggressive' do describe '#aggressive' do
before do before do
# allow(target).to receive(:content_dir).and_return('wp-content')
allow(target).to receive(:sub_dir).and_return(false) allow(target).to receive(:sub_dir).and_return(false)
stub_request(:get, finder.api_url).to_return(body: body) stub_request(:get, finder.api_url).to_return(body: body)
end end

View File

@@ -0,0 +1,46 @@
describe WPScan::Finders::Users::YoastSeoAuthorSitemap do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('users', 'yoast_seo_author_sitemap') }
describe '#aggressive' do
before do
allow(target).to receive(:sub_dir).and_return(false)
stub_request(:get, finder.sitemap_url).to_return(body: body)
end
context 'when not an XML response' do
let(:body) { '' }
its(:aggressive) { should eql([]) }
end
context 'when an XML response' do
context 'when no usernames disclosed' do
let(:body) { File.read(fixtures.join('no_usernames.xml')) }
its(:aggressive) { should eql([]) }
end
context 'when usernames disclosed' do
let(:body) { File.read(fixtures.join('usernames.xml')) }
it 'returns the expected array of users' do
users = finder.aggressive
expect(users.size).to eql 2
expect(users.first.username).to eql 'editor'
expect(users.first.confidence).to eql 100
expect(users.first.interesting_entries).to eql ['http://wp.lab/author-sitemap.xml']
expect(users.last.username).to eql 'admin'
expect(users.last.confidence).to eql 100
expect(users.last.interesting_entries).to eql ['http://wp.lab/author-sitemap.xml']
end
end
end
end
end

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::Base do describe WPScan::Finders::Users::Base do
subject(:user) { described_class.new(target) } subject(:user) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
@@ -8,7 +6,8 @@ describe WPScan::Finders::Users::Base do
describe '#finders' do describe '#finders' do
it 'contains the expected finders' do it 'contains the expected finders' do
expect(user.finders.map { |f| f.class.to_s.demodulize }) expect(user.finders.map { |f| f.class.to_s.demodulize })
.to eq %w[AuthorPosts WpJsonApi OembedApi RSSGenerator AuthorIdBruteForcing LoginErrorMessages] .to eq %w[AuthorPosts WpJsonApi OembedApi RSSGenerator YoastSeoAuthorSitemap
AuthorIdBruteForcing LoginErrorMessages]
end end
end end
end end

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::WpVersion::AtomGenerator do describe WPScan::Finders::WpVersion::AtomGenerator do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::WpVersion::RDFGenerator do describe WPScan::Finders::WpVersion::RDFGenerator do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::WpVersion::Readme do describe WPScan::Finders::WpVersion::Readme do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::WpVersion::RSSGenerator do describe WPScan::Finders::WpVersion::RSSGenerator do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::WpVersion::UniqueFingerprinting do describe WPScan::Finders::WpVersion::UniqueFingerprinting do
subject(:finder) { described_class.new(target) } subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
# If this file is tested alone (rspec path-to-this-file), then there will be an error about # If this file is tested alone (rspec path-to-this-file), then there will be an error about
# constants not being intilialized. This is due to the Dynamic Finders. # constants not being intilialized. This is due to the Dynamic Finders.

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::InterestingFinding do describe WPScan::InterestingFinding do
it_behaves_like WPScan::References do it_behaves_like WPScan::References do
subject(:finding) { described_class.new('http://e.org/file.php', opts) } subject(:finding) { described_class.new('http://e.org/file.php', opts) }

Some files were not shown because too many files have changed in this diff Show More