Compare commits

...

43 Commits

Author SHA1 Message Date
erwanlr
adff971d62 Bumps version 2019-03-10 09:47:41 +00:00
erwanlr
23b22f71b8 Reduces confidence of wp-cron detection 2019-03-10 08:02:51 +00:00
erwanlr
fee3671e32 Adds wp-cron.php detection - Fixes #1299 2019-03-10 07:53:12 +00:00
erwanlr
26c6be7268 Fixes #1307 2019-03-10 07:11:48 +00:00
erwanlr
01c5bcf2be Adds DFs 2019-03-09 16:19:25 +00:00
erwanlr
1ab8a5ab98 Updates deps 2019-03-07 19:37:01 +00:00
erwanlr
b54aaca28a Adds missing lines 2019-03-04 07:40:45 +00:00
erwanlr
86a29ae000 Adds DF 2019-03-04 07:35:21 +00:00
erwanlr
a5dbee93ff Adds DFs 2019-03-02 10:43:45 +00:00
Christian Mehlmauer
e0465e6e10 remove line 2019-02-28 08:41:19 +01:00
Christian Mehlmauer
7da48b9dd1 readme linting 2019-02-28 08:18:01 +01:00
Christian Mehlmauer
a64895c3a6 remove UTF characters from license 2019-02-28 08:13:42 +01:00
erwanlr
21f1a5d4c4 Adds DFs 2019-02-23 08:27:27 +00:00
erwanlr
d60f79ca33 Adds DFs 2019-02-16 13:20:51 +00:00
Erwan
2d5cea5033 Adds missing #to_s calls again 2019-02-11 21:14:40 +01:00
erwanlr
b0615215fe Adds missing #to_s calls 2019-02-11 20:03:05 +00:00
erwanlr
7a0f98b2cb Uses Pathname#join rather than File#join when possible 2019-02-11 19:56:07 +00:00
erwanlr
cdc1dab4a6 Bumps version 2019-02-11 11:48:49 +00:00
erwanlr
431739ab19 Updates Rubocop dep 2019-02-11 10:44:29 +00:00
erwanlr
1780399050 Fixes #1277 2019-02-10 15:32:30 +00:00
erwanlr
eb75d38716 Fixes #1284 2019-02-10 13:47:19 +00:00
erwanlr
06f82d78f4 Ref #1285 - Adds comment about the pagination 2019-02-10 10:49:03 +00:00
erwanlr
dee4da1c0e Fixes #1285 2019-02-10 10:45:54 +00:00
erwanlr
e341ec7c60 Adds DFs 2019-02-10 09:44:17 +00:00
Erwan
9146609e4a Update Readme, Fixes #1286 2019-02-03 20:46:03 +01:00
erwanlr
f90615ca41 Adds DF 2019-02-03 07:08:05 +00:00
erwanlr
8a2a6a05ff Adds DFs 2019-01-27 10:54:13 +00:00
Erwan
5a787f8ed5 Adds a note about bug in Ruby 2.5.x, Ref #1283 2019-01-25 20:14:14 +00:00
erwanlr
a904053002 Adds DFs 2019-01-20 17:04:32 +00:00
Erwan
70ecd30dcc Merge pull request #1276 from wpscanteam/dependabot/bundler/rubocop-tw-0.63.0
Update rubocop requirement from ~> 0.62.0 to ~> 0.63.0
2019-01-17 09:32:24 +00:00
dependabot[bot]
b0976d7e47 Update rubocop requirement from ~> 0.62.0 to ~> 0.63.0
Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop/commits/v0.63.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-17 05:54:18 +00:00
erwanlr
bb5e55016c Adds DFs 2019-01-13 16:56:13 +00:00
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
240 changed files with 35339 additions and 465 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

10
LICENSE
View File

@@ -1,14 +1,14 @@
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.
1. Definitions 1. Definitions
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
@@ -59,7 +59,7 @@ WPScan is provided under an AS-IS basis and without any support, updates or main
8. Disclaimer of Warranty 8. Disclaimer of Warranty
WPScan is provided under this License on an as is basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the WPScan is free of defects, merchantable, fit for a particular purpose or non-infringing. WPScan is provided under this License on an "as is" basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the WPScan is free of defects, merchantable, fit for a particular purpose or non-infringing.
9. Limitation of Liability 9. Limitation of Liability

View File

@@ -7,23 +7,28 @@
# INSTALL # INSTALL
## Prerequisites: ## Prerequisites
- (Optional but highly recommended: [RVM](https://rvm.io/rvm/install))
- Ruby >= 2.3 - Recommended: latest - Ruby >= 2.3 - Recommended: latest
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault - Ruby 2.5.0 to 2.5.3 can cause an 'undefined symbol: rmpd_util_str_to_d' error in some systems, see [#1283](https://github.com/wpscanteam/wpscan/issues/1283)
- Curl >= 7.21 - Recommended: latest
- The 7.29 has a segfault
- RubyGems - Recommended: latest - RubyGems - Recommended: latest
### From RubyGems: ### From RubyGems (Recommended)
``` ```shell
gem install wpscan gem install wpscan
``` ```
### From sources: On MacOSX, if a ```Gem::FilePermissionError``` is raised due to the Apple's System Integrity Protection (SIP), either install RVM and install wpscan again, or run ```sudo gem install -n /usr/local/bin wpscan``` (see [#1286](https://github.com/wpscanteam/wpscan/issues/1286))
### From sources (NOT Recommended)
Prerequisites: Git Prerequisites: Git
``` ```shell
git clone https://github.com/wpscanteam/wpscan git clone https://github.com/wpscanteam/wpscan
cd wpscan/ cd wpscan/
@@ -31,19 +36,28 @@ cd wpscan/
bundle install && rake install bundle install && rake install
``` ```
# Updating
You can update the local database by using ```wpscan --update```
Updating WPScan itself is either done via ```gem update wpscan``` or the packages manager (this is quite important for distributions such as in Kali Linux: ```apt-get update && apt-get upgrade```) depending how WPScan was (pre)installed
# Docker # Docker
Pull the repo with ```docker pull wpscanteam/wpscan``` Pull the repo with ```docker pull wpscanteam/wpscan```
Enumerating usernames Enumerating usernames
```
```shell
docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u
``` ```
Enumerating a range of usernames Enumerating a range of usernames
```
```shell
docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u1-100 docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u1-100
``` ```
** replace u1-100 with a range of your choice. ** replace u1-100 with a range of your choice.
# Usage # Usage
@@ -57,41 +71,44 @@ The DB is located at ~/.wpscan/db
WPScan can load all options (including the --url) from configuration files, the following locations are checked (order: first to last): WPScan can load all options (including the --url) from configuration files, the following locations are checked (order: first to last):
* ~/.wpscan/cli_options.json - ~/.wpscan/cli_options.json
* ~/.wpscan/cli_options.yml - ~/.wpscan/cli_options.yml
* pwd/.wpscan/cli_options.json - pwd/.wpscan/cli_options.json
* pwd/.wpscan/cli_options.yml - pwd/.wpscan/cli_options.yml
If those files exist, options from them will be loaded and overridden if found twice. If those files exist, options from them will be loaded and overridden if found twice.
e.g: e.g:
~/.wpscan/cli_options.yml: ~/.wpscan/cli_options.yml:
```
```yml
proxy: 'http://127.0.0.1:8080' proxy: 'http://127.0.0.1:8080'
verbose: true verbose: true
``` ```
pwd/.wpscan/cli_options.yml: pwd/.wpscan/cli_options.yml:
```
```yml
proxy: 'socks5://127.0.0.1:9090' proxy: 'socks5://127.0.0.1:9090'
url: 'http://target.tld' 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 Enumerating usernames
```
```shell
wpscan --url https://target.tld/ --enumerate u wpscan --url https://target.tld/ --enumerate u
``` ```
Enumerating a range of usernames Enumerating a range of usernames
```
```shell
wpscan --url https://target.tld/ --enumerate u1-100 wpscan --url https://target.tld/ --enumerate u1-100
``` ```
** replace u1-100 with a range of your choice.
** replace u1-100 with a range of your choice.
# PROJECT HOME # PROJECT HOME
@@ -105,7 +122,7 @@ wpscan --url https://target.tld/ --enumerate u1-100
## 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.
@@ -115,7 +132,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
@@ -136,8 +153,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

@@ -71,7 +71,7 @@ module WPScan
exit(WPScan::ExitCode::VULNERABLE) exit(WPScan::ExitCode::VULNERABLE)
end end
raise NotWordPressError unless target.wordpress? || parsed_options[:force] raise NotWordPressError unless target.wordpress?(parsed_options[:detection_mode]) || parsed_options[:force]
end end
# Loads the related server module in the target # Loads the related server module in the target

View File

@@ -98,7 +98,7 @@ module WPScan
[ [
OptFilePath.new( OptFilePath.new(
['--timthumbs-list FILE-PATH', 'List of timthumbs\' location to use'], ['--timthumbs-list FILE-PATH', 'List of timthumbs\' location to use'],
exists: true, default: File.join(DB_DIR, 'timthumbs-v3.txt'), advanced: true exists: true, default: DB_DIR.join('timthumbs-v3.txt').to_s, advanced: true
), ),
OptChoice.new( OptChoice.new(
['--timthumbs-detection MODE', ['--timthumbs-detection MODE',
@@ -113,7 +113,7 @@ module WPScan
[ [
OptFilePath.new( OptFilePath.new(
['--config-backups-list FILE-PATH', 'List of config backups\' filenames to use'], ['--config-backups-list FILE-PATH', 'List of config backups\' filenames to use'],
exists: true, default: File.join(DB_DIR, 'config_backups.txt'), advanced: true exists: true, default: DB_DIR.join('config_backups.txt').to_s, advanced: true
), ),
OptChoice.new( OptChoice.new(
['--config-backups-detection MODE', ['--config-backups-detection MODE',
@@ -128,7 +128,7 @@ module WPScan
[ [
OptFilePath.new( OptFilePath.new(
['--db-exports-list FILE-PATH', 'List of DB exports\' paths to use'], ['--db-exports-list FILE-PATH', 'List of DB exports\' paths to use'],
exists: true, default: File.join(DB_DIR, 'db_exports.txt'), advanced: true exists: true, default: DB_DIR.join('db_exports.txt').to_s, advanced: true
), ),
OptChoice.new( OptChoice.new(
['--db-exports-detection MODE', ['--db-exports-detection MODE',

View File

@@ -3,9 +3,10 @@ module WPScan
# Enumeration Methods # Enumeration Methods
class Enumeration < CMSScanner::Controller::Base class Enumeration < CMSScanner::Controller::Base
# @param [ String ] type (plugins or themes) # @param [ String ] type (plugins or themes)
# @param [ Symbol ] detection_mode
# #
# @return [ String ] The related enumration message depending on the parsed_options and type supplied # @return [ String ] The related enumration message depending on the parsed_options and type supplied
def enum_message(type) def enum_message(type, detection_mode)
return unless %w[plugins themes].include?(type) return unless %w[plugins themes].include?(type)
details = if parsed_options[:enumerate][:"vulnerable_#{type}"] details = if parsed_options[:enumerate][:"vulnerable_#{type}"]
@@ -16,7 +17,20 @@ module WPScan
'Most Popular' 'Most Popular'
end end
"Enumerating #{details} #{type.capitalize}" "Enumerating #{details} #{type.capitalize} #{enum_detection_message(detection_mode)}"
end
# @param [ Symbol ] detection_mode
#
# @return [ String ]
def enum_detection_message(detection_mode)
detection_method = if detection_mode == :mixed
'Passive and Aggressive'
else
detection_mode.to_s.capitalize
end
"(via #{detection_method} Methods)"
end end
# @param [ String ] type (plugins, themes etc) # @param [ String ] type (plugins, themes etc)
@@ -49,12 +63,15 @@ module WPScan
sort: true sort: true
) )
output('@info', msg: enum_message('plugins')) if user_interaction? output('@info', msg: enum_message('plugins', opts[:mode])) if user_interaction?
# Enumerate the plugins & find their versions to avoid doing that when #version # Enumerate the plugins & find their versions to avoid doing that when #version
# is called in the view # is called in the view
plugins = target.plugins(opts) plugins = target.plugins(opts)
output('@info', msg: 'Checking Plugin Versions') if user_interaction? && !plugins.empty? if user_interaction? && !plugins.empty?
output('@info',
msg: "Checking Plugin Versions #{enum_detection_message(opts[:version_detection][:mode])}")
end
plugins.each(&:version) plugins.each(&:version)
@@ -92,12 +109,15 @@ module WPScan
sort: true sort: true
) )
output('@info', msg: enum_message('themes')) if user_interaction? output('@info', msg: enum_message('themes', opts[:mode])) if user_interaction?
# Enumerate the themes & find their versions to avoid doing that when #version # Enumerate the themes & find their versions to avoid doing that when #version
# is called in the view # is called in the view
themes = target.themes(opts) themes = target.themes(opts)
output('@info', msg: 'Checking Theme Versions') if user_interaction? && !themes.empty? if user_interaction? && !themes.empty?
output('@info',
msg: "Checking Theme Versions #{enum_detection_message(opts[:version_detection][:mode])}")
end
themes.each(&:version) themes.each(&:version)
@@ -125,21 +145,21 @@ module WPScan
def enum_timthumbs def enum_timthumbs
opts = default_opts('timthumbs').merge(list: parsed_options[:timthumbs_list]) opts = default_opts('timthumbs').merge(list: parsed_options[:timthumbs_list])
output('@info', msg: 'Enumerating Timthumbs') if user_interaction? output('@info', msg: "Enumerating Timthumbs #{enum_detection_message(opts[:mode])}") if user_interaction?
output('timthumbs', timthumbs: target.timthumbs(opts)) output('timthumbs', timthumbs: target.timthumbs(opts))
end end
def enum_config_backups def enum_config_backups
opts = default_opts('config_backups').merge(list: parsed_options[:config_backups_list]) opts = default_opts('config_backups').merge(list: parsed_options[:config_backups_list])
output('@info', msg: 'Enumerating Config Backups') if user_interaction? output('@info', msg: "Enumerating Config Backups #{enum_detection_message(opts[:mode])}") if user_interaction?
output('config_backups', config_backups: target.config_backups(opts)) output('config_backups', config_backups: target.config_backups(opts))
end end
def enum_db_exports def enum_db_exports
opts = default_opts('db_exports').merge(list: parsed_options[:db_exports_list]) opts = default_opts('db_exports').merge(list: parsed_options[:db_exports_list])
output('@info', msg: 'Enumerating DB Exports') if user_interaction? output('@info', msg: "Enumerating DB Exports #{enum_detection_message(opts[:mode])}") if user_interaction?
output('db_exports', db_exports: target.db_exports(opts)) output('db_exports', db_exports: target.db_exports(opts))
end end
@@ -147,7 +167,9 @@ module WPScan
opts = default_opts('medias').merge(range: parsed_options[:enumerate][:medias]) opts = default_opts('medias').merge(range: parsed_options[:enumerate][:medias])
if user_interaction? if user_interaction?
output('@info', msg: 'Enumerating Medias (Permalink setting must be set to "Plain" for those to be detected)') output('@info',
msg: "Enumerating Medias #{enum_detection_message(opts[:mode])} "\
'(Permalink setting must be set to "Plain" for those to be detected)')
end end
output('medias', medias: target.medias(opts)) output('medias', medias: target.medias(opts))
@@ -166,7 +188,7 @@ module WPScan
list: parsed_options[:users_list] list: parsed_options[:users_list]
) )
output('@info', msg: 'Enumerating Users') if user_interaction? output('@info', msg: "Enumerating Users #{enum_detection_message(opts[:mode])}") if user_interaction?
output('users', users: target.users(opts)) output('users', users: target.users(opts))
end end

View File

@@ -65,8 +65,12 @@ module WPScan
when :wp_login when :wp_login
WPScan::Finders::Passwords::WpLogin.new(target) WPScan::Finders::Passwords::WpLogin.new(target)
when :xmlrpc when :xmlrpc
raise XMLRPCNotDetected unless xmlrpc
WPScan::Finders::Passwords::XMLRPC.new(xmlrpc) WPScan::Finders::Passwords::XMLRPC.new(xmlrpc)
when :xmlrpc_multicall when :xmlrpc_multicall
raise XMLRPCNotDetected unless xmlrpc
WPScan::Finders::Passwords::XMLRPCMulticall.new(xmlrpc) WPScan::Finders::Passwords::XMLRPCMulticall.new(xmlrpc)
end end
end end

View File

@@ -1,4 +1,5 @@
require_relative 'interesting_findings/readme' require_relative 'interesting_findings/readme'
require_relative 'interesting_findings/wp_cron'
require_relative 'interesting_findings/multisite' require_relative 'interesting_findings/multisite'
require_relative 'interesting_findings/debug_log' require_relative 'interesting_findings/debug_log'
require_relative 'interesting_findings/backup_db' require_relative 'interesting_findings/backup_db'
@@ -23,7 +24,7 @@ module WPScan
%w[ %w[
Readme DebugLog FullPathDisclosure BackupDB DuplicatorInstallerLog Readme DebugLog FullPathDisclosure BackupDB DuplicatorInstallerLog
Multisite MuPlugins Registration UploadDirectoryListing TmmDbMigrate Multisite MuPlugins Registration UploadDirectoryListing TmmDbMigrate
UploadSQLDump EmergencyPwdResetScript UploadSQLDump EmergencyPwdResetScript WPCron
].each do |f| ].each do |f|
finders << InterestingFindings.const_get(f).new(target) finders << InterestingFindings.const_get(f).new(target)
end end

View File

@@ -0,0 +1,31 @@
module WPScan
module Finders
module InterestingFindings
# wp-cron.php finder
class WPCron < CMSScanner::Finders::Finder
# @return [ InterestingFinding ]
def aggressive(_opts = {})
res = Browser.get(wp_cron_url)
return unless res.code == 200
WPScan::WPCron.new(
wp_cron_url,
confidence: 60,
found_by: DIRECT_ACCESS,
references: {
url: [
'https://www.iplocation.net/defend-wordpress-from-ddos',
'https://github.com/wpscanteam/wpscan/issues/1299'
]
}
)
end
def wp_cron_url
@wp_cron_url ||= target.url('wp-cron.php')
end
end
end
end
end

View File

@@ -4,20 +4,29 @@ module WPScan
# WP JSON API # WP JSON API
# #
# Since 4.7 - Need more investigation as it seems WP 4.7.1 reduces the exposure, see https://github.com/wpscanteam/wpscan/issues/1038) # Since 4.7 - Need more investigation as it seems WP 4.7.1 reduces the exposure, see https://github.com/wpscanteam/wpscan/issues/1038)
# For the pagination, see https://github.com/wpscanteam/wpscan/issues/1285
# #
class WpJsonApi < CMSScanner::Finders::Finder class WpJsonApi < CMSScanner::Finders::Finder
MAX_PER_PAGE = 100 # See https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/
# @param [ Hash ] opts # @param [ Hash ] opts
# #
# @return [ Array<User> ] # @return [ Array<User> ]
def aggressive(_opts = {}) def aggressive(_opts = {})
found = [] found = []
current_page = 0
JSON.parse(Browser.get(api_url).body)&.each do |user| loop do
found << CMSScanner::User.new(user['slug'], current_page += 1
id: user['id'],
found_by: found_by, res = Typhoeus.get(api_url, params: { per_page: MAX_PER_PAGE, page: current_page })
confidence: 100,
interesting_entries: [api_url]) total_pages ||= res.headers['X-WP-TotalPages'].to_i
users_in_page = users_from_response(res)
found += users_in_page
break if current_page >= total_pages || users_in_page.empty?
end end
found found
@@ -25,6 +34,23 @@ module WPScan
found found
end end
# @param [ Typhoeus::Response ] response
#
# @return [ Array<User> ] The users from the response
def users_from_response(response)
found = []
JSON.parse(response.body)&.each do |user|
found << CMSScanner::User.new(user['slug'],
id: user['id'],
found_by: found_by,
confidence: 100,
interesting_entries: [response.effective_url])
end
found
end
# @return [ String ] The URL of the API listing the Users # @return [ String ] The URL of the API listing the Users
def api_url def api_url
@api_url ||= target.url('wp-json/wp/v2/users/') @api_url ||= target.url('wp-json/wp/v2/users/')

View File

@@ -42,4 +42,7 @@ module WPScan
class UploadSQLDump < InterestingFinding class UploadSQLDump < InterestingFinding
end end
class WPCron < InterestingFinding
end
end end

View File

@@ -33,7 +33,7 @@ module WPScan
include CMSScanner include CMSScanner
APP_DIR = Pathname.new(__FILE__).dirname.join('..', 'app').expand_path APP_DIR = Pathname.new(__FILE__).dirname.join('..', 'app').expand_path
DB_DIR = File.join(Dir.home, '.wpscan', 'db') DB_DIR = Pathname.new(Dir.home).join('.wpscan', 'db')
# Override, otherwise it would be returned as 'wp_scan' # Override, otherwise it would be returned as 'wp_scan'
# #

View File

@@ -5,7 +5,7 @@ module WPScan
# @return [ String ] The path to the user agents list # @return [ String ] The path to the user agents list
def user_agents_list def user_agents_list
@user_agents_list ||= File.join(DB_DIR, 'user-agents.txt') @user_agents_list ||= DB_DIR.join('user-agents.txt').to_s
end end
# @return [ String ] # @return [ String ]

View File

@@ -4,7 +4,7 @@ module WPScan
class Base class Base
# @return [ String ] # @return [ String ]
def self.db_file def self.db_file
@db_file ||= File.join(DB_DIR, 'dynamic_finders.yml') @db_file ||= DB_DIR.join('dynamic_finders.yml').to_s
end end
# @return [ Hash ] # @return [ Hash ]

View File

@@ -33,7 +33,7 @@ module WPScan
# @return [ String ] # @return [ String ]
def self.wp_fingerprints_path def self.wp_fingerprints_path
@wp_fingerprints_path ||= File.join(DB_DIR, 'wp_fingerprints.json') @wp_fingerprints_path ||= DB_DIR.join('wp_fingerprints.json').to_s
end end
# @return [ Hash ] # @return [ Hash ]

View File

@@ -4,7 +4,7 @@ module WPScan
class Plugin < WpItem class Plugin < WpItem
# @return [ String ] # @return [ String ]
def self.db_file def self.db_file
@db_file ||= File.join(DB_DIR, 'plugins.json') @db_file ||= DB_DIR.join('plugins.json').to_s
end end
end end
end end

View File

@@ -4,7 +4,7 @@ module WPScan
class Theme < WpItem class Theme < WpItem
# @return [ String ] # @return [ String ]
def self.db_file def self.db_file
@db_file ||= File.join(DB_DIR, 'themes.json') @db_file ||= DB_DIR.join('themes.json').to_s
end end
end end
end end

View File

@@ -15,11 +15,11 @@ module WPScan
attr_reader :repo_directory attr_reader :repo_directory
def initialize(repo_directory) def initialize(repo_directory)
@repo_directory = repo_directory @repo_directory = Pathname.new(repo_directory).expand_path
FileUtils.mkdir_p(repo_directory) unless Dir.exist?(repo_directory) FileUtils.mkdir_p(repo_directory.to_s) unless Dir.exist?(repo_directory.to_s)
raise "#{repo_directory} is not writable" unless Pathname.new(repo_directory).writable? raise "#{repo_directory} is not writable" unless repo_directory.writable?
delete_old_files delete_old_files
end end
@@ -41,7 +41,7 @@ module WPScan
# @return [ String ] # @return [ String ]
def last_update_file def last_update_file
@last_update_file ||= File.join(repo_directory, '.last_update') @last_update_file ||= repo_directory.join('.last_update').to_s
end end
# @return [ Boolean ] # @return [ Boolean ]
@@ -54,7 +54,7 @@ module WPScan
# @return [ Boolean ] # @return [ Boolean ]
def missing_files? def missing_files?
FILES.each do |file| FILES.each do |file|
return true unless File.exist?(File.join(repo_directory, file)) return true unless File.exist?(repo_directory.join(file))
end end
false false
end end
@@ -85,16 +85,18 @@ module WPScan
res.body.chomp res.body.chomp
end end
# @return [ String ]
def local_file_path(filename) def local_file_path(filename)
File.join(repo_directory, filename.to_s) repo_directory.join(filename.to_s).to_s
end end
def local_file_checksum(filename) def local_file_checksum(filename)
Digest::SHA512.file(local_file_path(filename)).hexdigest Digest::SHA512.file(local_file_path(filename)).hexdigest
end end
# @return [ String ]
def backup_file_path(filename) def backup_file_path(filename)
File.join(repo_directory, "#{filename}.back") repo_directory.join("#{filename}.back").to_s
end end
def create_backup(filename) def create_backup(filename)

View File

@@ -4,7 +4,7 @@ module WPScan
class Version < WpItem class Version < WpItem
# @return [ String ] # @return [ String ]
def self.db_file def self.db_file
@db_file ||= File.join(DB_DIR, 'wordpresses.json') @db_file ||= DB_DIR.join('wordpresses.json').to_s
end end
end end
end end

View File

@@ -6,3 +6,4 @@ end
require_relative 'errors/http' require_relative 'errors/http'
require_relative 'errors/update' require_relative 'errors/update'
require_relative 'errors/wordpress' require_relative 'errors/wordpress'
require_relative 'errors/xmlrpc'

View File

@@ -0,0 +1,8 @@
module WPScan
# XML-RPC Not Detected
class XMLRPCNotDetected < Error
def to_s
'The XML-RPC Interface was not detected.'
end
end
end

View File

@@ -18,10 +18,10 @@ module WPScan
alias registration_enabled? registration_enabled alias registration_enabled? registration_enabled
alias mu_plugins? mu_plugins alias mu_plugins? mu_plugins
# @param [ Symbol ] detection_mode
#
# @return [ Boolean ] # @return [ Boolean ]
def wordpress? def wordpress?(detection_mode)
# res = Browser.get(url)
in_scope_urls(homepage_res) do |url| in_scope_urls(homepage_res) do |url|
return true if Addressable::URI.parse(url).path.match(WORDPRESS_PATTERN) return true if Addressable::URI.parse(url).path.match(WORDPRESS_PATTERN)
end end
@@ -32,6 +32,14 @@ module WPScan
return true unless comments_from_page(/wordpress/i, homepage_res).empty? return true unless comments_from_page(/wordpress/i, homepage_res).empty?
if %i[mixed aggressive].include?(detection_mode)
%w[wp-admin/install.php wp-login.php].each do |path|
in_scope_urls(Browser.get_and_follow_location(url(path))).each do |url|
return true if Addressable::URI.parse(url).path.match(WORDPRESS_PATTERN)
end
end
end
false false
end end

View File

@@ -1,4 +1,4 @@
# Version # Version
module WPScan module WPScan
VERSION = '3.4.2'.freeze VERSION = '3.4.5'.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/' }
@@ -167,7 +165,7 @@ describe WPScan::Controller::Core do
before do before do
expect(core).to receive(:load_server_module) expect(core).to receive(:load_server_module)
expect(core.target).to receive(:wordpress?).and_return(true) expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
end end
it 'calls the formatter when started and finished to update the db' do it 'calls the formatter when started and finished to update the db' do
@@ -210,7 +208,7 @@ describe WPScan::Controller::Core do
context 'when wordpress' do context 'when wordpress' do
it 'does not raise an error' do it 'does not raise an error' do
expect(core.target).to receive(:wordpress?).and_return(true) expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
expect { core.before_scan }.to_not raise_error expect { core.before_scan }.to_not raise_error
end end
@@ -218,7 +216,7 @@ describe WPScan::Controller::Core do
context 'when not wordpress' do context 'when not wordpress' do
it 'raises an error' do it 'raises an error' do
expect(core.target).to receive(:wordpress?).and_return(false) expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
expect { core.before_scan }.to raise_error(WPScan::NotWordPressError) expect { core.before_scan }.to raise_error(WPScan::NotWordPressError)
end end
@@ -239,7 +237,7 @@ describe WPScan::Controller::Core do
context 'when wordpress' do context 'when wordpress' do
before do before do
expect(core).to receive(:load_server_module) expect(core).to receive(:load_server_module)
expect(core.target).to receive(:wordpress?).and_return(true) expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
end end
it 'does not raise any error' do it 'does not raise any error' do
@@ -250,7 +248,7 @@ describe WPScan::Controller::Core do
context 'when not wordpress' do context 'when not wordpress' do
before do before do
expect(core).to receive(:load_server_module) expect(core).to receive(:load_server_module)
expect(core.target).to receive(:wordpress?).and_return(false) expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
end end
context 'when no --force' do context 'when no --force' do

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/' }
@@ -16,10 +14,11 @@ describe WPScan::Controller::Enumeration do
end end
describe '#enum_message' do describe '#enum_message' do
after { expect(controller.enum_message(type)).to eql @expected } after { expect(controller.enum_message(type, detection_mode)).to eql @expected }
context 'when type argument is incorrect' do context 'when type argument is incorrect' do
let(:type) { 'spec' } let(:type) { 'spec' }
let(:detection_mode) { :mixed }
it 'returns nil' do it 'returns nil' do
@expected = nil @expected = nil
@@ -29,28 +28,31 @@ describe WPScan::Controller::Enumeration do
%w[plugins themes].each do |t| %w[plugins themes].each do |t|
context "type = #{t}" do context "type = #{t}" do
let(:type) { t } let(:type) { t }
let(:detection_mode) { :mixed }
context 'when vulnerable' do context 'when vulnerable' do
let(:cli_args) { "#{super()} -e v#{type[0]}" } let(:cli_args) { "#{super()} -e v#{type[0]}" }
it 'returns the expected string' do it 'returns the expected string' do
@expected = "Enumerating Vulnerable #{type.capitalize}" @expected = "Enumerating Vulnerable #{type.capitalize} (via Passive and Aggressive Methods)"
end end
end end
context 'when all' do context 'when all' do
let(:cli_args) { "#{super()} -e a#{type[0]}" } let(:cli_args) { "#{super()} -e a#{type[0]}" }
let(:detection_mode) { :passive }
it 'returns the expected string' do it 'returns the expected string' do
@expected = "Enumerating All #{type.capitalize}" @expected = "Enumerating All #{type.capitalize} (via Passive Methods)"
end end
end end
context 'when most popular' do context 'when most popular' do
let(:cli_args) { "#{super()} -e #{type[0]}" } let(:cli_args) { "#{super()} -e #{type[0]}" }
let(:detection_mode) { :aggressive }
it 'returns the expected string' do it 'returns the expected string' do
@expected = "Enumerating Most Popular #{type.capitalize}" @expected = "Enumerating Most Popular #{type.capitalize} (via Aggressive Methods)"
end end
end end
end end

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/' }
@@ -68,6 +66,29 @@ describe WPScan::Controller::PasswordAttack do
end end
context 'when xmlrpc' do context 'when xmlrpc' do
context 'when xmlrpc not detected on target' do
before do
expect(controller.target).to receive(:xmlrpc).and_return(nil)
end
context 'when single xmlrpc' do
let(:attack) { 'xmlrpc' }
it 'raises an error' do
expect { controller.attacker }.to raise_error(WPScan::XMLRPCNotDetected)
end
end
context 'when xmlrpc-multicall' do
let(:attack) { 'xmlrpc-multicall' }
it 'raises an error' do
expect { controller.attacker }.to raise_error(WPScan::XMLRPCNotDetected)
end
end
end
context 'when xmlrpc detected on target' do
before do before do
expect(controller.target).to receive(:xmlrpc).and_return(WPScan::XMLRPC.new("#{target_url}/xmlrpc.php")) expect(controller.target).to receive(:xmlrpc).and_return(WPScan::XMLRPC.new("#{target_url}/xmlrpc.php"))
end end
@@ -91,6 +112,7 @@ describe WPScan::Controller::PasswordAttack do
end end
end end
end end
end
context 'when automatic detection' do context 'when automatic detection' do
before { expect(controller.target).to receive(:xmlrpc).and_return(xmlrpc) } before { expect(controller.target).to receive(:xmlrpc).and_return(xmlrpc) }

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,11 +1,9 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'config_backups') } let(:fixtures) { FINDERS_FIXTURES.join('config_backups') }
let(:opts) { { list: File.join(WPScan::DB_DIR, 'config_backups.txt') } } let(:opts) { { list: WPScan::DB_DIR.join('config_backups.txt').to_s } }
describe '#aggressive' do describe '#aggressive' do
before do before do
@@ -25,7 +23,7 @@ describe WPScan::Finders::ConfigBackups::KnownFilenames do
context 'when some files exist' do context 'when some files exist' do
let(:files) { ['%23wp-config.php%23', 'wp-config.bak'] } let(:files) { ['%23wp-config.php%23', 'wp-config.bak'] }
let(:config_backup) { File.read(File.join(fixtures, 'wp-config.php')) } let(:config_backup) { File.read(fixtures.join('wp-config.php')) }
before do before do
files.each do |file| files.each do |file|

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,11 +1,9 @@
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) }
let(:url) { 'http://ex.lo/aa/' } let(:url) { 'http://ex.lo/aa/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'db_exports') } let(:fixtures) { FINDERS_FIXTURES.join('db_exports') }
let(:opts) { { list: File.join(WPScan::DB_DIR, 'db_exports.txt') } } let(:opts) { { list: WPScan::DB_DIR.join('db_exports.txt').to_s } }
describe '#potential_urls' do describe '#potential_urls' do
before do before do
@@ -42,7 +40,7 @@ describe WPScan::Finders::DbExports::KnownLocations do
context 'when some files exist' do context 'when some files exist' do
let(:files) { %w[ex.sql backups/db_backup.sql] } let(:files) { %w[ex.sql backups/db_backup.sql] }
let(:db_export) { File.read(File.join(fixtures, 'dump.sql')) } let(:db_export) { File.read(fixtures.join('dump.sql')) }
before do before do
files.each do |file| files.each do |file|

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,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'backup_db') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'backup_db') }
let(:wp_content) { 'wp-content' } let(:wp_content) { 'wp-content' }
let(:dir_url) { target.url("#{wp_content}/backup-db/") } let(:dir_url) { target.url("#{wp_content}/backup-db/") }
@@ -53,7 +51,7 @@ describe WPScan::Finders::InterestingFindings::BackupDB do
end end
context 'when directory listing enabled' do context 'when directory listing enabled' do
let(:body) { File.read(File.join(fixtures, 'dir_listing.html')) } let(:body) { File.read(fixtures.join('dir_listing.html')) }
it 'returns the expected interesting_findings attribute' do it 'returns the expected interesting_findings attribute' do
@expected_entries = %w[sqldump.sql test.txt] @expected_entries = %w[sqldump.sql test.txt]

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'debug_log') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'debug_log') }
let(:wp_content) { 'wp-content' } let(:wp_content) { 'wp-content' }
let(:log_url) { target.url("#{wp_content}/debug.log") } let(:log_url) { target.url("#{wp_content}/debug.log") }
@@ -20,7 +18,7 @@ describe WPScan::Finders::InterestingFindings::DebugLog do
end end
context 'when a log file' do context 'when a log file' do
let(:body) { File.read(File.join(fixtures, 'debug.log')) } let(:body) { File.read(fixtures.join('debug.log')) }
it 'returns the InterestingFinding' do it 'returns the InterestingFinding' do
expect(finder.aggressive).to eql WPScan::DebugLog.new( expect(finder.aggressive).to eql WPScan::DebugLog.new(

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'duplicator_installer_log') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'duplicator_installer_log') }
let(:filename) { 'installer-log.txt' } let(:filename) { 'installer-log.txt' }
let(:log_url) { target.url(filename) } let(:log_url) { target.url(filename) }
@@ -21,7 +19,7 @@ describe WPScan::Finders::InterestingFindings::DuplicatorInstallerLog do
end end
context 'when the body matches' do context 'when the body matches' do
let(:body) { File.read(File.join(fixtures, filename)) } let(:body) { File.read(fixtures.join(filename)) }
it 'returns the InterestingFinding' do it 'returns the InterestingFinding' do
expect(finder.aggressive).to eql WPScan::DuplicatorInstallerLog.new( expect(finder.aggressive).to eql WPScan::DuplicatorInstallerLog.new(

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'emergency_pwd_reset_script') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'emergency_pwd_reset_script') }
describe '#aggressive' do describe '#aggressive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'fpd') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'fpd') }
let(:file_url) { target.url('wp-includes/rss-functions.php') } let(:file_url) { target.url('wp-includes/rss-functions.php') }
describe '#aggressive' do describe '#aggressive' do
@@ -20,7 +18,7 @@ describe WPScan::Finders::InterestingFindings::FullPathDisclosure do
end end
context 'when a log file' do context 'when a log file' do
let(:body) { File.read(File.join(fixtures, 'rss_functions.php')) } let(:body) { File.read(fixtures.join('rss_functions.php')) }
it 'returns the InterestingFinding' do it 'returns the InterestingFinding' do
found = finder.aggressive found = finder.aggressive

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'mu_plugins') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'mu_plugins') }
describe '#passive' do describe '#passive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'multisite') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'multisite') }
describe '#aggressive' do describe '#aggressive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'readme') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'readme') }
describe '#aggressive' do describe '#aggressive' do
before do before do
@@ -22,7 +20,7 @@ describe WPScan::Finders::InterestingFindings::Readme do
# TODO: case when multiple files are present ? (should return only the first one found) # TODO: case when multiple files are present ? (should return only the first one found)
context 'when a file exists' do context 'when a file exists' do
let(:file) { finder.potential_files.sample } let(:file) { finder.potential_files.sample }
let(:readme) { File.read(File.join(fixtures, 'readme-3.9.2.html')) } let(:readme) { File.read(fixtures.join('readme-3.9.2.html')) }
before { stub_request(:get, target.url(file)).to_return(body: readme) } before { stub_request(:get, target.url(file)).to_return(body: readme) }

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'registration') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'registration') }
describe '#aggressive' do describe '#aggressive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'tmm_db_migrate') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'tmm_db_migrate') }
describe '#aggressive' do describe '#aggressive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'upload_directory_listing') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'upload_directory_listing') }
let(:wp_content) { 'wp-content' } let(:wp_content) { 'wp-content' }
describe '#aggressive' do describe '#aggressive' do

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'upload_sql_dump') } let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'upload_sql_dump') }
let(:wp_content) { 'wp-content' } let(:wp_content) { 'wp-content' }
describe '#aggressive' do describe '#aggressive' do
@@ -23,7 +21,7 @@ describe WPScan::Finders::InterestingFindings::UploadSQLDump do
context 'when a 200' do context 'when a 200' do
before do before do
stub_request(:get, finder.dump_url) stub_request(:get, finder.dump_url)
.to_return(status: 200, body: File.read(File.join(fixtures, fixture))) .to_return(status: 200, body: File.read(fixtures.join(fixture)))
end end
context 'when the body does not match a SQL dump' do context 'when the body does not match a SQL dump' do

View File

@@ -0,0 +1,30 @@
describe WPScan::Finders::InterestingFindings::WPCron do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://ex.lo/' }
let(:wp_content) { 'wp-content' }
before { expect(target).to receive(:sub_dir).at_least(1).and_return(false) }
describe '#aggressive' do
before { stub_request(:get, finder.wp_cron_url).to_return(status: status) }
context 'when 200' do
let(:status) { 200 }
it 'returns the InterestingFinding' do
expect(finder.aggressive).to eql WPScan::WPCron.new(
finder.wp_cron_url,
confidence: 60,
found_by: described_class::DIRECT_ACCESS
)
end
end
context 'otherwise' do
let(:status) { 403 }
its(:aggressive) { should be_nil }
end
end
end

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,14 +1,12 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'main_theme', 'css_style') } let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'css_style') }
describe '#passive' do describe '#passive' do
after do after do
stub_request(:get, url).to_return(body: File.read(File.join(fixtures, fixture))) stub_request(:get, url).to_return(body: File.read(fixtures.join(fixture)))
expect(finder.passive).to eql @expected expect(finder.passive).to eql @expected
end end

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'main_theme', 'urls_in_homepage') } let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'urls_in_homepage') }
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
let(:type) { 'themes' } let(:type) { 'themes' }
@@ -17,7 +15,7 @@ describe WPScan::Finders::MainTheme::UrlsInHomepage do
describe '#passive' do describe '#passive' do
before do before do
stub_request(:get, /.*.css/) stub_request(:get, /.*.css/)
stub_request(:get, target.url).to_return(body: File.read(File.join(fixtures, 'found.html'))) stub_request(:get, target.url).to_return(body: File.read(fixtures.join('found.html')))
end end
it 'returns the expected Themes' do it 'returns the expected Themes' do

View File

@@ -1,14 +1,12 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'main_theme', 'woo_framework_meta_generator') } let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'woo_framework_meta_generator') }
describe '#passive' do describe '#passive' do
after do after do
stub_request(:get, url).to_return(body: File.read(File.join(fixtures, @file))) stub_request(:get, url).to_return(body: File.read(fixtures.join(@file)))
expect(finder.passive).to eql @expected expect(finder.passive).to eql @expected
end end

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,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'medias', 'attachment_brute_forcing') } let(:fixtures) { FINDERS_FIXTURES.join('medias', 'attachment_brute_forcing') }
describe '#aggressive' do describe '#aggressive' do
xit xit

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,10 +1,8 @@
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) }
let(:target) { WPScan::Target.new('http://wp.lab/') } let(:target) { WPScan::Target.new('http://wp.lab/') }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'plugin_version', 'readme') } let(:fixtures) { FINDERS_FIXTURES.join('plugin_version', 'readme') }
def version(number, found_by, confidence) def version(number, found_by, confidence)
WPScan::Version.new( WPScan::Version.new(
@@ -28,7 +26,7 @@ describe WPScan::Finders::PluginVersion::Readme do
after do after do
stub_request(:get, /.*/).to_return(status: 404) stub_request(:get, /.*/).to_return(status: 404)
stub_request(:get, readme_url).to_return(body: File.read(File.join(fixtures, @file))) stub_request(:get, readme_url).to_return(body: File.read(fixtures.join(@file)))
expect(finder.aggressive).to eql @expected expect(finder.aggressive).to eql @expected
end end

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,11 +1,9 @@
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) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') } let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }
let(:expected_all) { df_expected_all['plugins'] } let(:expected_all) { df_expected_all['plugins'] }
let(:item_class) { WPScan::Plugin } let(:item_class) { WPScan::Plugin }

View File

@@ -1,11 +1,9 @@
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) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') } let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }
let(:expected_all) { df_expected_all['plugins'] } let(:expected_all) { df_expected_all['plugins'] }
let(:item_class) { WPScan::Plugin } let(:item_class) { WPScan::Plugin }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Plugins::ConfigParser do describe WPScan::Finders::Plugins::ConfigParser do
xit xit
@@ -7,7 +5,7 @@ describe WPScan::Finders::Plugins::ConfigParser 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) }
# let(:url) { 'http://wp.lab/' } # let(:url) { 'http://wp.lab/' }
# let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') } # let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }
# #
# let(:expected_all) { df_expected_all['plugins'] } # let(:expected_all) { df_expected_all['plugins'] }
# let(:item_class) { WPScan::Plugin } # let(:item_class) { WPScan::Plugin }

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') } let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }
def plugin(slug) def plugin(slug)
WPScan::Plugin.new(slug, target) WPScan::Plugin.new(slug, target)
@@ -31,7 +29,7 @@ describe WPScan::Finders::Plugins::HeaderPattern do
context 'when headers' do context 'when headers' do
before { expect(target).to receive(:content_dir).and_return('wp-content') } before { expect(target).to receive(:content_dir).and_return('wp-content') }
let(:headers) { JSON.parse(File.read(File.join(fixtures, 'header_pattern_passive_all.html'))) } let(:headers) { JSON.parse(File.read(fixtures.join('header_pattern_passive_all.html'))) }
it 'returns the expected plugins' do it 'returns the expected plugins' do
@expected = [] @expected = []

View File

@@ -1,11 +1,9 @@
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) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') } let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }
let(:expected_all) { df_expected_all['plugins'] } let(:expected_all) { df_expected_all['plugins'] }
let(:item_class) { WPScan::Plugin } let(:item_class) { WPScan::Plugin }

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'plugins', 'known_locations') } let(:fixtures) { FINDERS_FIXTURES.join('plugins', 'known_locations') }
describe '#aggressive' do describe '#aggressive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') } let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }
describe '#passive' do describe '#passive' do
its(:passive) { should be nil } its(:passive) { should be nil }

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'plugins', 'urls_in_homepage') } let(:fixtures) { FINDERS_FIXTURES.join('plugins', 'urls_in_homepage') }
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
let(:type) { 'plugins' } let(:type) { 'plugins' }
@@ -17,7 +15,7 @@ describe WPScan::Finders::Plugins::UrlsInHomepage do
describe '#passive' do describe '#passive' do
before do before do
stub_request(:get, finder.target.url) stub_request(:get, finder.target.url)
.to_return(body: File.read(File.join(fixtures, 'found.html'))) .to_return(body: File.read(fixtures.join('found.html')))
expect(finder.target).to receive(:content_dir).at_least(1).and_return('wp-content') expect(finder.target).to receive(:content_dir).at_least(1).and_return('wp-content')
end end

View File

@@ -1,11 +1,9 @@
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) }
let(:target) { WPScan::Target.new(url) } let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') } let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }
let(:expected_all) { df_expected_all['plugins'] } let(:expected_all) { df_expected_all['plugins'] }
let(:item_class) { WPScan::Plugin } let(:item_class) { WPScan::Plugin }

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,13 +1,11 @@
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) }
let(:target) { WPScan::Target.new('http://wp.lab/') } let(:target) { WPScan::Target.new('http://wp.lab/') }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'theme_version', 'style') } let(:fixtures) { FINDERS_FIXTURES.join('theme_version', 'style') }
before :all do before :all do
Typhoeus::Config.cache = WPScan::Cache::Typhoeus.new(File.join(SPECS, 'cache')) Typhoeus::Config.cache = WPScan::Cache::Typhoeus.new(SPECS.join('cache'))
end end
before do before do
@@ -79,7 +77,7 @@ describe WPScan::Finders::ThemeVersion::Style do
'no_version' => nil 'no_version' => nil
}.each do |file, expected_version| }.each do |file, expected_version|
context "when #{file}" do context "when #{file}" do
let(:style_body) { File.new(File.join(fixtures, "#{file}.css")) } let(:style_body) { File.new(fixtures.join("#{file}.css")) }
it 'returns the expected version' do it 'returns the expected version' do
expected = if expected_version expected = if expected_version

View File

@@ -1,10 +1,8 @@
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) }
let(:target) { WPScan::Target.new('http://wp.lab/') } let(:target) { WPScan::Target.new('http://wp.lab/') }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'theme_version', 'woo_framework_meta_generator') } let(:fixtures) { FINDERS_FIXTURES.join('theme_version', 'woo_framework_meta_generator') }
before do before do
expect(target).to receive(:content_dir).and_return('wp-content') expect(target).to receive(:content_dir).and_return('wp-content')
@@ -13,7 +11,7 @@ describe WPScan::Finders::ThemeVersion::WooFrameworkMetaGenerator do
describe '#passive' do describe '#passive' do
after do after do
stub_request(:get, target.url).to_return(body: File.read(File.join(fixtures, 'editorial-1.3.5.html'))) stub_request(:get, target.url).to_return(body: File.read(fixtures.join('editorial-1.3.5.html')))
expect(finder.passive).to eql @expected expect(finder.passive).to eql @expected
end end

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,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'themes', 'known_locations') } let(:fixtures) { FINDERS_FIXTURES.join('themes', 'known_locations') }
describe '#aggressive' do describe '#aggressive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'themes', 'urls_in_homepage') } let(:fixtures) { FINDERS_FIXTURES.join('themes', 'urls_in_homepage') }
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
let(:type) { 'themes' } let(:type) { 'themes' }

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,13 +1,11 @@
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) }
let(:url) { 'http://ex.lo/timthumb.php' } let(:url) { 'http://ex.lo/timthumb.php' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'timthumb_version', 'bad_request') } let(:fixtures) { FINDERS_FIXTURES.join('timthumb_version', 'bad_request') }
describe '#aggressive' do describe '#aggressive' do
before { stub_request(:get, url).to_return(body: File.read(File.join(fixtures, file))) } before { stub_request(:get, url).to_return(body: File.read(fixtures.join(file))) }
after { expect(finder.aggressive).to eql @expected } after { expect(finder.aggressive).to eql @expected }
context 'when no version' do context 'when no version' do

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,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'timthumbs', 'known_locations') } let(:fixtures) { FINDERS_FIXTURES.join('timthumbs', 'known_locations') }
describe '#aggressive' do describe '#aggressive' do
xit xit

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,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'author_id_brute_forcing') } let(:fixtures) { FINDERS_FIXTURES.join('users', 'author_id_brute_forcing') }
describe '#aggressive' do describe '#aggressive' do
xit xit
@@ -26,7 +24,7 @@ describe WPScan::Finders::Users::AuthorIdBruteForcing do
'2.9.2', '2.9.2-permalink' '2.9.2', '2.9.2-permalink'
].each do |file| ].each do |file|
it "returns 'admin' from #{file}.html" do it "returns 'admin' from #{file}.html" do
body = File.read(File.join(fixtures, "#{file}.html")) body = File.read(fixtures.join("#{file}.html"))
res = Typhoeus::Response.new(body: body) res = Typhoeus::Response.new(body: body)
expect(finder.username_from_response(res)).to eql 'admin' expect(finder.username_from_response(res)).to eql 'admin'
@@ -42,7 +40,7 @@ describe WPScan::Finders::Users::AuthorIdBruteForcing do
'2.9.2', '2.9.2-permalink' '2.9.2', '2.9.2-permalink'
].each do |file| ].each do |file|
it "returns 'admin display_name' from #{file}.html" do it "returns 'admin display_name' from #{file}.html" do
body = File.read(File.join(fixtures, "#{file}.html")) body = File.read(fixtures.join("#{file}.html"))
expect(finder.display_name_from_body(body)).to eql 'admin display_name' expect(finder.display_name_from_body(body)).to eql 'admin display_name'
end end
@@ -52,7 +50,7 @@ describe WPScan::Finders::Users::AuthorIdBruteForcing do
context 'when no display_name' do context 'when no display_name' do
['4.1.1', '3.0', '2.9.2'].each do |file| ['4.1.1', '3.0', '2.9.2'].each do |file|
it "returns nil for #{file}-empty.html" do it "returns nil for #{file}-empty.html" do
body = File.read(File.join(fixtures, "#{file}-empty.html")) body = File.read(fixtures.join("#{file}-empty.html"))
expect(finder.display_name_from_body(body)).to eql nil expect(finder.display_name_from_body(body)).to eql nil
end end

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'author_posts') } let(:fixtures) { FINDERS_FIXTURES.join('users', 'author_posts') }
describe '#passive' do describe '#passive' do
xit xit
@@ -12,7 +10,7 @@ describe WPScan::Finders::Users::AuthorPosts do
describe '#potential_usernames' do describe '#potential_usernames' do
it 'returns the expected usernames' do it 'returns the expected usernames' do
res = Typhoeus::Response.new(body: File.read(File.join(fixtures, 'potential_usernames.html'))) res = Typhoeus::Response.new(body: File.read(fixtures.join('potential_usernames.html')))
results = finder.potential_usernames(res) results = finder.potential_usernames(res)

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'login_error_messages') } let(:fixtures) { FINDERS_FIXTURES.join('users', 'login_error_messages') }
describe '#aggressive' do describe '#aggressive' do
xit xit

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'oembed_api') } let(:fixtures) { FINDERS_FIXTURES.join('users', 'oembed_api') }
describe '#aggressive' do describe '#aggressive' do
before do before do
@@ -20,14 +18,14 @@ describe WPScan::Finders::Users::OembedApi do
context 'when a JSON response' do context 'when a JSON response' do
context 'when 404' do context 'when 404' do
let(:body) { File.read(File.join(fixtures, '404.json')) } let(:body) { File.read(fixtures.join('404.json')) }
its(:aggressive) { should eql([]) } its(:aggressive) { should eql([]) }
end end
context 'when 200' do context 'when 200' do
context 'when author_url present' do context 'when author_url present' do
let(:body) { File.read(File.join(fixtures, '200_author_url.json')) } let(:body) { File.read(fixtures.join('200_author_url.json')) }
it 'returns the expected array of users' do it 'returns the expected array of users' do
users = finder.aggressive users = finder.aggressive
@@ -44,7 +42,7 @@ describe WPScan::Finders::Users::OembedApi do
end end
context 'when author_url not present but author_name' do context 'when author_url not present but author_name' do
let(:body) { File.read(File.join(fixtures, '200_author_name.json')) } let(:body) { File.read(fixtures.join('200_author_name.json')) }
it 'returns the expected array of users' do it 'returns the expected array of users' do
users = finder.aggressive users = finder.aggressive

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { Pathname.new(FINDERS_FIXTURES).join('users', 'rss_generator') } let(:fixtures) { FINDERS_FIXTURES.join('users', 'rss_generator') }
let(:rss_fixture) { File.read(fixtures.join('feed.xml')) } let(:rss_fixture) { File.read(fixtures.join('feed.xml')) }
describe '#passive, #aggressive' do describe '#passive, #aggressive' do
@@ -41,7 +39,7 @@ describe WPScan::Finders::Users::RSSGenerator do
end end
context 'when RSS link in homepage' do context 'when RSS link in homepage' do
let(:homepage_fixture) { File.join(fixtures, 'homepage_links.html') } let(:homepage_fixture) { fixtures.join('homepage_links.html') }
it 'returns the expected from #passive' do it 'returns the expected from #passive' do
stub_request(:get, target.url('feed/')).to_return(body: rss_fixture) stub_request(:get, target.url('feed/')).to_return(body: rss_fixture)

View File

@@ -1,15 +1,17 @@
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) }
let(:url) { 'http://wp.lab/' } let(:url) { 'http://wp.lab/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'wp_json_api') } let(:fixtures) { FINDERS_FIXTURES.join('users', 'wp_json_api') }
describe '#aggressive' do describe '#aggressive' do
before { allow(target).to receive(:sub_dir).and_return(false) }
context 'when only one page of results' do
before do before do
allow(target).to receive(:sub_dir).and_return(false) stub_request(:get, finder.api_url)
stub_request(:get, finder.api_url).to_return(body: body) .with(query: { page: 1, per_page: 100 })
.to_return(body: body, headers: {})
end end
context 'when not a JSON response' do context 'when not a JSON response' do
@@ -20,13 +22,13 @@ describe WPScan::Finders::Users::WpJsonApi do
context 'when a JSON response' do context 'when a JSON response' do
context 'when unauthorised' do context 'when unauthorised' do
let(:body) { File.read(File.join(fixtures, '401.json')) } let(:body) { File.read(fixtures.join('401.json')) }
its(:aggressive) { should eql([]) } its(:aggressive) { should eql([]) }
end end
context 'when limited exposure (WP >= 4.7.1)' do context 'when limited exposure (WP >= 4.7.1)' do
let(:body) { File.read(File.join(fixtures, '4.7.2.json')) } let(:body) { File.read(fixtures.join('4.7.2.json')) }
it 'returns the expected array of users' do it 'returns the expected array of users' do
users = finder.aggressive users = finder.aggressive
@@ -38,9 +40,42 @@ describe WPScan::Finders::Users::WpJsonApi do
expect(user.id).to eql 1 expect(user.id).to eql 1
expect(user.username).to eql 'admin' expect(user.username).to eql 'admin'
expect(user.confidence).to eql 100 expect(user.confidence).to eql 100
expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/'] expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/?page=1&per_page=100']
end end
end end
end end
end end
context 'when multiple pages of results' do
before do
stub_request(:get, finder.api_url)
.with(query: { page: 1, per_page: 100 })
.to_return(body: File.read(fixtures.join('4.7.2.json')), headers: { 'X-WP-TotalPages' => 2 })
stub_request(:get, finder.api_url)
.with(query: { page: 2, per_page: 100 })
.to_return(body: File.read(fixtures.join('4.7.2-2.json')), headers: { 'X-WP-TotalPages' => 2 })
end
it 'returns the expected array of users' do
users = finder.aggressive
expect(users.size).to eql 2
user = users.first
expect(user.id).to eql 1
expect(user.username).to eql 'admin'
expect(user.confidence).to eql 100
expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/?page=1&per_page=100']
user = users.second
expect(user.id).to eql 20
expect(user.username).to eql 'user'
expect(user.confidence).to eql 100
expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/?page=2&per_page=100']
end
end
end
end end

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Finders::Users::YoastSeoAuthorSitemap do describe WPScan::Finders::Users::YoastSeoAuthorSitemap 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::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) }

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { Pathname.new(FINDERS_FIXTURES).join('wp_version', 'atom_generator') } let(:fixtures) { FINDERS_FIXTURES.join('wp_version', 'atom_generator') }
let(:atom_fixture) { File.read(fixtures.join('feed', 'atom')) } let(:atom_fixture) { File.read(fixtures.join('feed', 'atom')) }
describe '#passive, #aggressive' do describe '#passive, #aggressive' do
@@ -38,7 +36,7 @@ describe WPScan::Finders::WpVersion::AtomGenerator do
end end
context 'when atom links in homepage' do context 'when atom links in homepage' do
let(:homepage_fixture) { File.join(fixtures, 'links.html') } let(:homepage_fixture) { fixtures.join('links.html') }
it 'returns the expected from #passive' do it 'returns the expected from #passive' do
stub_request(:get, target.url('?feed=atom')).to_return(body: atom_fixture) stub_request(:get, target.url('?feed=atom')).to_return(body: atom_fixture)

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'rdf_generator') } let(:fixtures) { FINDERS_FIXTURES.join('wp_version', 'rdf_generator') }
xit xit
end end

View File

@@ -1,14 +1,12 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'readme') } let(:fixtures) { FINDERS_FIXTURES.join('wp_version', 'readme') }
let(:readme_url) { url + 'readme.html' } let(:readme_url) { url + 'readme.html' }
describe '#aggressive' do describe '#aggressive' do
before { stub_request(:get, readme_url).to_return(body: File.read(File.join(fixtures, file))) } before { stub_request(:get, readme_url).to_return(body: File.read(fixtures.join(file))) }
after do after do
expect(target).to receive(:sub_dir).and_return(false) expect(target).to receive(:sub_dir).and_return(false)

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'rss_generator') } let(:fixtures) { FINDERS_FIXTURES.join('wp_version', 'rss_generator') }
xit xit
end end

View File

@@ -1,10 +1,8 @@
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) }
let(:url) { 'http://ex.lo/' } let(:url) { 'http://ex.lo/' }
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'unique_fingerprinting') } let(:fixtures) { FINDERS_FIXTURES.join('wp_version', 'unique_fingerprinting') }
xit xit
end end

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) }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Media do describe WPScan::Media do
subject(:media) { described_class.new(url) } subject(:media) { described_class.new(url) }
let(:url) { 'http://e.oeg/?attachment_id=2' } let(:url) { 'http://e.oeg/?attachment_id=2' }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::Plugin do describe WPScan::Plugin do
subject(:plugin) { described_class.new(slug, blog, opts) } subject(:plugin) { described_class.new(slug, blog, opts) }
let(:slug) { 'spec' } let(:slug) { 'spec' }

View File

@@ -1,18 +1,16 @@
require 'spec_helper'
describe WPScan::Theme do describe WPScan::Theme do
subject(:theme) { described_class.new(slug, blog, opts) } subject(:theme) { described_class.new(slug, blog, opts) }
let(:slug) { 'spec' } let(:slug) { 'spec' }
let(:blog) { WPScan::Target.new('http://wp.lab/') } let(:blog) { WPScan::Target.new('http://wp.lab/') }
let(:opts) { {} } let(:opts) { {} }
let(:fixtures) { File.join(FIXTURES, 'models', 'theme') } let(:fixtures) { FIXTURES.join('models', 'theme') }
before { expect(blog).to receive(:content_dir).at_least(1).and_return('wp-content') } before { expect(blog).to receive(:content_dir).at_least(1).and_return('wp-content') }
describe '#new' do describe '#new' do
before do before do
stub_request(:get, /.*\.css\z/) stub_request(:get, /.*\.css\z/)
.to_return(body: File.read(File.join(fixtures, 'style.css'))) .to_return(body: File.read(fixtures.join('style.css')))
end end
its(:url) { should eql 'http://wp.lab/wp-content/themes/spec/' } its(:url) { should eql 'http://wp.lab/wp-content/themes/spec/' }
@@ -39,7 +37,7 @@ describe WPScan::Theme do
describe '#version' do describe '#version' do
after do after do
stub_request(:get, /.*\.css\z/) stub_request(:get, /.*\.css\z/)
.to_return(body: File.read(File.join(fixtures, 'style.css'))) .to_return(body: File.read(fixtures.join('style.css')))
expect(WPScan::Finders::ThemeVersion::Base).to receive(:find).with(theme, @expected_opts) expect(WPScan::Finders::ThemeVersion::Base).to receive(:find).with(theme, @expected_opts)
theme.version(version_opts) theme.version(version_opts)
@@ -93,7 +91,7 @@ describe WPScan::Theme do
describe '#parent_theme' do describe '#parent_theme' do
before do before do
stub_request(:get, blog.url('wp-content/themes/spec/style.css')) stub_request(:get, blog.url('wp-content/themes/spec/style.css'))
.to_return(body: File.read(File.join(fixtures, main_theme))) .to_return(body: File.read(fixtures.join(main_theme)))
end end
context 'when no template' do context 'when no template' do
@@ -110,7 +108,7 @@ describe WPScan::Theme do
before do before do
stub_request(:get, parent_url) stub_request(:get, parent_url)
.to_return(body: File.read(File.join(fixtures, 'style.css'))) .to_return(body: File.read(fixtures.join('style.css')))
end end
%w[child_style windows_line_endings].each do |fixture| %w[child_style windows_line_endings].each do |fixture|

View File

@@ -1,9 +1,7 @@
require 'spec_helper'
describe WPScan::Timthumb do describe WPScan::Timthumb do
subject(:timthumb) { described_class.new(url, opts) } subject(:timthumb) { described_class.new(url, opts) }
let(:url) { 'http://wp.lab/wp-content/timthumb.php' } let(:url) { 'http://wp.lab/wp-content/timthumb.php' }
let(:fixtures) { File.join(FIXTURES, 'models', 'timthumb') } let(:fixtures) { FIXTURES.join('models', 'timthumb') }
let(:opts) { {} } let(:opts) { {} }
describe '#new' do describe '#new' do
@@ -61,7 +59,7 @@ describe WPScan::Timthumb do
describe '#webshot_enabled?' do describe '#webshot_enabled?' do
before do before do
stub_request(:get, /#{timthumb.url}\?src=.*&webshot=1/i) stub_request(:get, /#{timthumb.url}\?src=.*&webshot=1/i)
.to_return(body: File.read(File.join(fixtures, fixture))) .to_return(body: File.read(fixtures.join(fixture)))
end end
context 'when enabled' do context 'when enabled' do

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::WpItem do describe WPScan::WpItem do
subject(:wp_item) { described_class.new(slug, blog, opts) } subject(:wp_item) { described_class.new(slug, blog, opts) }
let(:slug) { 'test_item' } let(:slug) { 'test_item' }

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::WpVersion do describe WPScan::WpVersion do
describe '#new' do describe '#new' do
context 'when invalid number' do context 'when invalid number' do

View File

@@ -1,5 +1,3 @@
require 'spec_helper'
describe WPScan::XMLRPC do describe WPScan::XMLRPC do
subject(:xml_rpc) { described_class.new('http//e.org/xmlrpc.php') } subject(:xml_rpc) { described_class.new('http//e.org/xmlrpc.php') }

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