Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bff063805 | ||
|
|
53d9956829 | ||
|
|
6e98678c3c | ||
|
|
f0f21f5ac2 | ||
|
|
aa233b1c4d | ||
|
|
93f9123f45 | ||
|
|
5c710d88e4 | ||
|
|
ded70ff743 | ||
|
|
9df7443aa4 | ||
|
|
8362975691 | ||
|
|
49771419ae | ||
|
|
d344f84824 | ||
|
|
89c0b8d4d0 | ||
|
|
3c74ee8d97 | ||
|
|
785c6efa5b | ||
|
|
4e2bf5322e | ||
|
|
54ed148c87 | ||
|
|
b08e298eba | ||
|
|
89e2088357 | ||
|
|
f3cc35bd74 | ||
|
|
a007d283e5 | ||
|
|
70902aa013 | ||
|
|
91151fc53b | ||
|
|
d4ee82dac5 | ||
|
|
88d3c26113 | ||
|
|
054a4ee6aa | ||
|
|
c291022753 | ||
|
|
2fc488b602 | ||
|
|
009ddd690e | ||
|
|
88b5cd8751 | ||
|
|
cfd19d02b1 | ||
|
|
19ce30d862 | ||
|
|
c6df6e0e89 | ||
|
|
e942a5bcf6 | ||
|
|
c0f5163d07 | ||
|
|
f5aa9f117f | ||
|
|
498d93377d | ||
|
|
52242e706b | ||
|
|
22d69a1bf9 | ||
|
|
0b1fa13696 | ||
|
|
19b15b5327 | ||
|
|
e63e96f5ed | ||
|
|
e8ac8f26a7 | ||
|
|
13e4327de4 | ||
|
|
c22a1ed12a | ||
|
|
be5662b5f1 | ||
|
|
6e840ca920 | ||
|
|
8492190f4c | ||
|
|
93ab6ee2a0 | ||
|
|
7075e01886 | ||
|
|
436a83434c | ||
|
|
d270391b56 | ||
|
|
7f2762eb6f | ||
|
|
2cc5bb0311 | ||
|
|
d697127261 | ||
|
|
825523a851 | ||
|
|
0f3f9cac33 | ||
|
|
f9b545b100 | ||
|
|
943bfc39b3 | ||
|
|
b1a8f445c6 | ||
|
|
5435df4345 | ||
|
|
8e9d29e94f | ||
|
|
1afa761f09 | ||
|
|
d626913ce9 | ||
|
|
9c52e4a5ee | ||
|
|
72c2c1992b | ||
|
|
e1b4b5e8e5 | ||
|
|
0243522854 | ||
|
|
5118c68f45 | ||
|
|
442884b5c5 |
18
.dockerignore
Normal file
18
.dockerignore
Normal file
@@ -0,0 +1,18 @@
|
||||
git/
|
||||
bundle/
|
||||
.idea/
|
||||
.yardoc/
|
||||
cache/
|
||||
coverage/
|
||||
spec/
|
||||
dev/
|
||||
.*
|
||||
**/*.md
|
||||
*.md
|
||||
Dockerfile
|
||||
**/*.orig
|
||||
*.orig
|
||||
CREDITS
|
||||
data.zip
|
||||
DISCLAIMER.txt
|
||||
example.conf.json
|
||||
@@ -2,8 +2,7 @@ language: ruby
|
||||
sudo: false
|
||||
cache: bundler
|
||||
rvm:
|
||||
# Still not in Travis :(
|
||||
# - 2.1.9
|
||||
- 2.1.9
|
||||
- 2.2.0
|
||||
- 2.2.1
|
||||
- 2.2.2
|
||||
@@ -13,6 +12,8 @@ rvm:
|
||||
- 2.3.1
|
||||
before_install:
|
||||
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
||||
before_script:
|
||||
- "unzip -o $TRAVIS_BUILD_DIR/data.zip -d $TRAVIS_BUILD_DIR"
|
||||
script: bundle exec rspec
|
||||
notifications:
|
||||
email:
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,6 +1,31 @@
|
||||
# Changelog
|
||||
## Master
|
||||
[Work in progress](https://github.com/wpscanteam/wpscan/compare/2.9.1...master)
|
||||
[Work in progress](https://github.com/wpscanteam/wpscan/compare/2.9.2...master)
|
||||
|
||||
## Version 2.9.2
|
||||
Released: 2016-11-15
|
||||
|
||||
* Fixed error when detecting plugins with UTF-8 characters
|
||||
* Use all possible finders to verify a detected version
|
||||
* Fix error when detecting a WordPress version not in our database
|
||||
* Added some additional clarification on error messages
|
||||
* Upgrade terminal-table gem
|
||||
* Add --cache-dir option
|
||||
* Add --disable-tls-checks options
|
||||
* Improve/add additional plugin passive detections
|
||||
* Remove scripts when calculating page hashes
|
||||
* Many other small bug fixes.
|
||||
|
||||
WPScan Database Statistics:
|
||||
* Total tracked wordpresses: 194
|
||||
* Total tracked plugins: 63703
|
||||
* Total tracked themes: 13835
|
||||
* Total vulnerable wordpresses: 177
|
||||
* Total vulnerable plugins: 1382
|
||||
* Total vulnerable themes: 379
|
||||
* Total wordpress vulnerabilities: 2617
|
||||
* Total plugin vulnerabilities: 2190
|
||||
* Total theme vulnerabilities: 452
|
||||
|
||||
## Version 2.9.1
|
||||
Released: 2016-05-06
|
||||
|
||||
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
FROM ruby:2.3-slim
|
||||
MAINTAINER WPScan Team <team@wpscan.org>
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends -qq -y install curl git ca-certificates openssl libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev build-essential procps
|
||||
|
||||
RUN useradd -d /wpscan wpscan
|
||||
RUN echo "gem: --no-ri --no-rdoc" > /etc/gemrc
|
||||
RUN mkdir /wpscan
|
||||
|
||||
COPY . /wpscan
|
||||
|
||||
WORKDIR /wpscan
|
||||
|
||||
RUN bundle install --without test
|
||||
RUN chown -R wpscan:wpscan /wpscan
|
||||
|
||||
USER wpscan
|
||||
RUN /wpscan/wpscan.rb --update --verbose --no-color
|
||||
|
||||
ENTRYPOINT ["/wpscan/wpscan.rb"]
|
||||
CMD ["--help"]
|
||||
9
Gemfile
9
Gemfile
@@ -1,13 +1,10 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'typhoeus', '>=0.8.0'
|
||||
gem 'nokogiri', '>=1.6.7.1'
|
||||
gem 'typhoeus', '>=1.0.0'
|
||||
gem 'nokogiri', '>=1.6.7.2'
|
||||
gem 'addressable'
|
||||
gem 'yajl-ruby' # Better JSON parser regarding memory usage
|
||||
# TODO: update the below when terminal-table 1.5.3+ is released.
|
||||
# See issue #841 for details
|
||||
# (and delete the Terminal module in lib/common/hacks.rb)
|
||||
gem 'terminal-table', '~>1.4.5'
|
||||
gem 'terminal-table', '>=1.6.0'
|
||||
gem 'ruby-progressbar', '>=1.6.0'
|
||||
|
||||
group :test do
|
||||
|
||||
4
LICENSE
4
LICENSE
@@ -68,3 +68,7 @@ To the extent permitted under Law, WPScan is provided under an AS-IS basis. The
|
||||
10. Disclaimer
|
||||
|
||||
Running WPScan against websites without prior mutual consent may be illegal in your country. The WPScan Team accept no liability and are not responsible for any misuse or damage caused by WPScan.
|
||||
|
||||
11. Trademark
|
||||
|
||||
The "wpscan" term is a registered trademark. This License does not grant the use of the "wpscan" trademark or the use of the WPScan logo.
|
||||
|
||||
133
README.md
133
README.md
@@ -4,16 +4,17 @@
|
||||
[](https://travis-ci.org/wpscanteam/wpscan)
|
||||
[](https://codeclimate.com/github/wpscanteam/wpscan)
|
||||
[](https://gemnasium.com/wpscanteam/wpscan)
|
||||
[](https://hub.docker.com/r/wpscanteam/wpscan/)
|
||||
|
||||
#### LICENSE
|
||||
# LICENSE
|
||||
|
||||
#### WPScan Public Source License
|
||||
## WPScan Public Source License
|
||||
|
||||
The WPScan software (henceforth referred to simply as "WPScan") is dual-licensed - Copyright 2011-2016 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.
|
||||
|
||||
##### 1. Definitions
|
||||
### 1. Definitions
|
||||
|
||||
1.1 "License" means this document.
|
||||
|
||||
@@ -21,7 +22,7 @@ Cases that include commercialization of WPScan require a commercial, non-free li
|
||||
|
||||
1.3 "WPScan Team" means WPScan’s core developers, an updated list of whom can be found within the CREDITS file.
|
||||
|
||||
##### 2. Commercialization
|
||||
### 2. Commercialization
|
||||
|
||||
A commercial use is one intended for commercial advantage or monetary compensation.
|
||||
|
||||
@@ -44,7 +45,7 @@ We may grant commercial licenses at no monetary cost at our own discretion if th
|
||||
|
||||
Free-use Terms and Conditions;
|
||||
|
||||
##### 3. Redistribution
|
||||
### 3. Redistribution
|
||||
|
||||
Redistribution is permitted under the following conditions:
|
||||
|
||||
@@ -52,35 +53,39 @@ Redistribution is permitted under the following conditions:
|
||||
- Unmodified Copyright notices are provided with WPScan.
|
||||
- Does not conflict with the commercialization clause.
|
||||
|
||||
##### 4. Copying
|
||||
### 4. Copying
|
||||
|
||||
Copying is permitted so long as it does not conflict with the Redistribution clause.
|
||||
|
||||
##### 5. Modification
|
||||
### 5. Modification
|
||||
|
||||
Modification is permitted so long as it does not conflict with the Redistribution clause.
|
||||
|
||||
##### 6. Contributions
|
||||
### 6. Contributions
|
||||
|
||||
Any Contributions assume the Contributor grants the WPScan Team the unlimited, non-exclusive right to reuse, modify and relicense the Contributor's content.
|
||||
|
||||
##### 7. Support
|
||||
### 7. Support
|
||||
|
||||
WPScan is provided under an AS-IS basis and without any support, updates or maintenance. Support, updates and maintenance may be given according to the sole discretion of the WPScan Team.
|
||||
|
||||
##### 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.
|
||||
|
||||
##### 9. Limitation of Liability
|
||||
### 9. Limitation of Liability
|
||||
|
||||
To the extent permitted under Law, WPScan is provided under an AS-IS basis. The WPScan Team shall never, and without any limit, be liable for any damage, cost, expense or any other payment incurred as a result of WPScan's actions, failure, bugs and/or any other interaction between WPScan and end-equipment, computers, other software or any 3rd party, end-equipment, computer or services.
|
||||
|
||||
##### 10. Disclaimer
|
||||
### 10. Disclaimer
|
||||
|
||||
Running WPScan against websites without prior mutual consent may be illegal in your country. The WPScan Team accept no liability and are not responsible for any misuse or damage caused by WPScan.
|
||||
|
||||
#### INSTALL
|
||||
### 11. Trademark
|
||||
|
||||
The "wpscan" term is a registered trademark. This License does not grant the use of the "wpscan" trademark or the use of the WPScan logo.
|
||||
|
||||
# INSTALL
|
||||
|
||||
WPScan comes pre-installed on the following Linux distributions:
|
||||
|
||||
@@ -90,69 +95,44 @@ WPScan comes pre-installed on the following Linux distributions:
|
||||
- [SamuraiWTF](http://samurai.inguardians.com/)
|
||||
- [BlackArch](http://blackarch.org/)
|
||||
|
||||
Prerequisites:
|
||||
Windows is not supported
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Ruby >= 2.1.9 - Recommended: 2.3.1
|
||||
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
||||
- RubyGems - Recommended: latest
|
||||
- Git
|
||||
|
||||
Windows is not supported.
|
||||
If installed from Github update the code base with ```git pull```. The databases are updated with ```wpscan.rb --update```.
|
||||
### Installing dependencies on Ubuntu
|
||||
|
||||
####Installing on Ubuntu:
|
||||
sudo apt-get install libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev ruby-dev build-essential libgmp-dev zlib1g-dev
|
||||
|
||||
Before Ubuntu 14.04:
|
||||
|
||||
sudo apt-get install libcurl4-openssl-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev ruby-dev
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler && bundle install --without test
|
||||
|
||||
From Ubuntu 14.04:
|
||||
|
||||
sudo apt-get install libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev ruby-dev build-essential libgmp-dev
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler && bundle install --without test
|
||||
|
||||
####Installing on Debian:
|
||||
### Installing dependencies on Debian
|
||||
|
||||
sudo apt-get install git ruby ruby-dev libcurl4-openssl-dev make zlib1g-dev
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler
|
||||
bundle install --without test --path vendor/bundle
|
||||
|
||||
####Installing on Fedora:
|
||||
### Installing dependencies on Fedora
|
||||
|
||||
sudo dnf install gcc ruby-devel libxml2 libxml2-devel libxslt libxslt-devel libcurl-devel patch rpm-build
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler && bundle install --without test
|
||||
|
||||
####Installing on Archlinux:
|
||||
### Installing dependencies on Arch Linux
|
||||
|
||||
pacman -Syu ruby
|
||||
pacman -Syu libyaml
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler && bundle install --without test
|
||||
gem install typhoeus
|
||||
gem install nokogiri
|
||||
|
||||
####Installing on Mac OSX:
|
||||
### Installing dependencies on Mac OSX
|
||||
|
||||
Apple Xcode, Command Line Tools and the libffi are needed (to be able to install the FFI gem), See [http://stackoverflow.com/questions/17775115/cant-setup-ruby-environment-installing-fii-gem-error](http://stackoverflow.com/questions/17775115/cant-setup-ruby-environment-installing-fii-gem-error)
|
||||
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler && sudo bundle install --without test
|
||||
## Installing with RVM (recommended)
|
||||
|
||||
####Installing with RVM (recommended):
|
||||
If you are using GNOME Terminal, there are some steps required before executing the commands. See here for more information:
|
||||
https://rvm.io/integration/gnome-terminal#integrating-rvm-with-gnome-terminal
|
||||
|
||||
# Install all prerequisites for your OS (look above)
|
||||
cd ~
|
||||
curl -sSL https://rvm.io/mpapis.asc | gpg --import -
|
||||
curl -sSL https://get.rvm.io | bash -s stable
|
||||
source ~/.rvm/scripts/rvm
|
||||
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
|
||||
@@ -165,7 +145,26 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
||||
gem install bundler
|
||||
bundle install --without test
|
||||
|
||||
#### KNOWN ISSUES
|
||||
## Installing manually (not recommended)
|
||||
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler && bundle install --without test
|
||||
|
||||
# DOCKER
|
||||
Pull the repo with `docker pull wpscanteam/wpscan`
|
||||
|
||||
## Start WPScan
|
||||
|
||||
```
|
||||
docker run --rm wpscanteam/wpscan -u http://yourblog.com [options]
|
||||
```
|
||||
|
||||
For the available Options, please see https://github.com/wpscanteam/wpscan#wpscan-arguments
|
||||
|
||||
Published on https://hub.docker.com/r/wpscanteam/wpscan/
|
||||
|
||||
# KNOWN ISSUES
|
||||
|
||||
- Typhoeus segmentation fault
|
||||
|
||||
@@ -208,7 +207,7 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
||||
|
||||
See [https://github.com/wpscanteam/wpscan/issues/148](https://github.com/wpscanteam/wpscan/issues/148)
|
||||
|
||||
#### WPSCAN ARGUMENTS
|
||||
# WPSCAN ARGUMENTS
|
||||
|
||||
--update Update the database to the latest version.
|
||||
--url | -u <target url> The WordPress URL/domain to scan.
|
||||
@@ -232,12 +231,17 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
||||
You do not need to provide the regexp delimiters, but you must write the quotes (simple or double).
|
||||
--config-file | -c <config file> Use the specified config file, see the example.conf.json.
|
||||
--user-agent | -a <User-Agent> Use the specified User-Agent.
|
||||
--cookie <String> String to read cookies from.
|
||||
--cookie <string> String to read cookies from.
|
||||
--random-agent | -r Use a random User-Agent.
|
||||
--follow-redirection If the target url has a redirection, it will be followed without asking if you wanted to do so or not
|
||||
--batch Never ask for user input, use the default behaviour.
|
||||
--no-color Do not use colors in the output.
|
||||
--wp-content-dir <wp content dir> WPScan try to find the content directory (ie wp-content) by scanning the index page, however you can specified it.
|
||||
--log Creates a log.txt file with WPScan's output.
|
||||
--no-banner Prevents the WPScan banner from being displayed.
|
||||
--disable-accept-header Prevents WPScan sending the Accept HTTP header.
|
||||
--disable-referer Prevents setting the Referer header.
|
||||
--disable-tls-checks Disables SSL/TLS certificate verification.
|
||||
--wp-content-dir <wp content dir> WPScan try to find the content directory (ie wp-content) by scanning the index page, however you can specify it.
|
||||
Subdirectories are allowed.
|
||||
--wp-plugins-dir <wp plugins dir> Same thing than --wp-content-dir but for the plugins directory.
|
||||
If not supplied, WPScan will use wp-content-dir/plugins. Subdirectories are allowed
|
||||
@@ -248,17 +252,18 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
||||
--wordlist | -w <wordlist> Supply a wordlist for the password brute forcer.
|
||||
--username | -U <username> Only brute force the supplied username.
|
||||
--usernames <path-to-file> Only brute force the usernames from the file.
|
||||
--threads | -t <number of threads> The number of threads to use when multi-threading requests.
|
||||
--cache-dir <cache-directory> Set the cache directory.
|
||||
--cache-ttl <cache-ttl> Typhoeus cache TTL.
|
||||
--request-timeout <request-timeout> Request Timeout.
|
||||
--connect-timeout <connect-timeout> Connect Timeout.
|
||||
--threads | -t <number of threads> The number of threads to use when multi-threading requests.
|
||||
--max-threads <max-threads> Maximum Threads.
|
||||
--throttle <milliseconds> Milliseconds to wait before doing another web request. If used, the --threads should be set to 1.
|
||||
--help | -h This help screen.
|
||||
--verbose | -v Verbose output.
|
||||
--version Output the current version and exit.
|
||||
|
||||
#### WPSCAN EXAMPLES
|
||||
# WPSCAN EXAMPLES
|
||||
|
||||
Do 'non-intrusive' checks...
|
||||
|
||||
@@ -292,26 +297,22 @@ Debug output...
|
||||
|
||||
```ruby wpscan.rb --url www.example.com --debug-output 2>debug.log```
|
||||
|
||||
#### PROJECT HOME
|
||||
# PROJECT HOME
|
||||
|
||||
[http://www.wpscan.org](http://www.wpscan.org)
|
||||
|
||||
#### VULNERABILITY DATABASE
|
||||
# VULNERABILITY DATABASE
|
||||
|
||||
[https://wpvulndb.com](https://wpvulndb.com)
|
||||
|
||||
#### GIT REPOSITORY
|
||||
# GIT REPOSITORY
|
||||
|
||||
[https://github.com/wpscanteam/wpscan](https://github.com/wpscanteam/wpscan)
|
||||
|
||||
#### ISSUES
|
||||
# ISSUES
|
||||
|
||||
[https://github.com/wpscanteam/wpscan/issues](https://github.com/wpscanteam/wpscan/issues)
|
||||
|
||||
#### DEVELOPER DOCUMENTATION
|
||||
# DEVELOPER DOCUMENTATION
|
||||
|
||||
[http://rdoc.info/github/wpscanteam/wpscan/frames](http://rdoc.info/github/wpscanteam/wpscan/frames)
|
||||
|
||||
#### SPECIAL THANKS
|
||||
|
||||
[RandomStorm](https://www.randomstorm.com)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env ruby
|
||||
# encoding: UTF-8
|
||||
|
||||
require File.dirname(__FILE__) + '/../lib/wpscan/wpscan_helper'
|
||||
require File.expand_path(File.join(__dir__, '..', 'lib', 'wpscan', 'wpscan_helper'))
|
||||
|
||||
wordpress_json = json(WORDPRESSES_FILE)
|
||||
plugins_json = json(PLUGINS_FILE)
|
||||
@@ -14,6 +14,6 @@ puts "* Total tracked themes: #{themes_json.count}"
|
||||
puts "* Total vulnerable wordpresses: #{wordpress_json.select { |item| !wordpress_json[item]['vulnerabilities'].empty? }.count}"
|
||||
puts "* Total vulnerable plugins: #{plugins_json.select { |item| !plugins_json[item]['vulnerabilities'].empty? }.count}"
|
||||
puts "* Total vulnerable themes: #{themes_json.select { |item| !themes_json[item]['vulnerabilities'].empty? }.count}"
|
||||
puts "* Total wordpress vulnerabilities: #{}"
|
||||
puts "* Total plugin vulnerabilities: #{}"
|
||||
puts "* Total theme vulnerabilities: #{}"
|
||||
puts "* Total wordpress vulnerabilities: #{wordpress_json.map {|k,v| v['vulnerabilities'].count}.inject(:+)}"
|
||||
puts "* Total plugin vulnerabilities: #{plugins_json.map {|k,v| v['vulnerabilities'].count}.inject(:+)}"
|
||||
puts "* Total theme vulnerabilities: #{themes_json.map {|k,v| v['vulnerabilities'].count}.inject(:+)}"
|
||||
|
||||
@@ -18,7 +18,10 @@ class Browser
|
||||
:request_timeout,
|
||||
:connect_timeout,
|
||||
:cookie,
|
||||
:throttle
|
||||
:throttle,
|
||||
:disable_accept_header,
|
||||
:disable_referer,
|
||||
:disable_tls_checks
|
||||
]
|
||||
|
||||
@@instance = nil
|
||||
@@ -67,17 +70,23 @@ class Browser
|
||||
@@instance = nil
|
||||
end
|
||||
|
||||
# Override for setting the User-Agent
|
||||
# @param [ String ] user_agent
|
||||
def user_agent=(user_agent)
|
||||
Typhoeus::Config.user_agent = user_agent
|
||||
end
|
||||
|
||||
#
|
||||
# sets browser default values
|
||||
#
|
||||
def browser_defaults
|
||||
Typhoeus::Config.user_agent = "WPScan v#{WPSCAN_VERSION} (http://wpscan.org)"
|
||||
@max_threads = 20
|
||||
# 10 minutes, at this time the cache is cleaned before each scan.
|
||||
# If this value is set to 0, the cache will be disabled
|
||||
@cache_ttl = 600
|
||||
@request_timeout = 60 # 60s
|
||||
@connect_timeout = 10 # 10s
|
||||
@user_agent = "WPScan v#{WPSCAN_VERSION} (http://wpscan.org)"
|
||||
@throttle = 0
|
||||
end
|
||||
|
||||
@@ -115,12 +124,6 @@ class Browser
|
||||
#
|
||||
# @return [ Hash ]
|
||||
def merge_request_params(params = {})
|
||||
params = Browser.append_params_header_field(
|
||||
params,
|
||||
'User-Agent',
|
||||
@user_agent
|
||||
)
|
||||
|
||||
if @proxy
|
||||
params.merge!(proxy: @proxy)
|
||||
params.merge!(proxyauth: @proxy_auth) if @proxy_auth
|
||||
@@ -153,12 +156,18 @@ class Browser
|
||||
params.merge!(maxredirs: 3) unless params.key?(:maxredirs)
|
||||
|
||||
# Disable SSL-Certificate checks
|
||||
params.merge!(ssl_verifypeer: false) unless params.key?(:ssl_verifypeer)
|
||||
if @disable_tls_checks
|
||||
# Cert validity check
|
||||
params.merge!(ssl_verifypeer: 0) unless params.key?(:ssl_verifypeer)
|
||||
# Cert hostname check
|
||||
params.merge!(ssl_verifyhost: 0) unless params.key?(:ssl_verifyhost)
|
||||
end
|
||||
|
||||
params.merge!(cookiejar: @cache_dir + '/cookie-jar')
|
||||
params.merge!(cookiefile: @cache_dir + '/cookie-jar')
|
||||
params.merge!(cookie: @cookie) if @cookie
|
||||
params = Browser.remove_params_header_field(params, 'Accept') if @disable_accept_header
|
||||
params = Browser.remove_params_header_field(params, 'Referer') if @disable_referer
|
||||
|
||||
params
|
||||
end
|
||||
@@ -178,4 +187,18 @@ class Browser
|
||||
end
|
||||
params
|
||||
end
|
||||
|
||||
# @param [ Hash ] params
|
||||
# @param [ String ] field
|
||||
# @param [ Mixed ] field_value
|
||||
#
|
||||
# @return [ Array ]
|
||||
def self.remove_params_header_field(params = {}, field)
|
||||
if !params.has_key?(:headers)
|
||||
params = params.merge(:headers => { field => nil })
|
||||
elsif !params[:headers].has_key?(field)
|
||||
params[:headers][field] = nil
|
||||
end
|
||||
params
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
class Browser
|
||||
module Options
|
||||
|
||||
attr_accessor :request_timeout, :connect_timeout
|
||||
attr_accessor :request_timeout, :connect_timeout, :user_agent, :disable_accept_header, :disable_referer, :disable_tls_checks
|
||||
attr_reader :basic_auth, :cache_ttl, :proxy, :proxy_auth, :throttle
|
||||
attr_writer :user_agent
|
||||
|
||||
# Sets the Basic Authentification credentials
|
||||
# Accepted format:
|
||||
|
||||
0
lib/common/collections/wp_items.rb
Executable file → Normal file
0
lib/common/collections/wp_items.rb
Executable file → Normal file
6
lib/common/collections/wp_items/detectable.rb
Executable file → Normal file
6
lib/common/collections/wp_items/detectable.rb
Executable file → Normal file
@@ -95,6 +95,10 @@ class WpItems < Array
|
||||
code = tag.text.to_s
|
||||
next if code.empty?
|
||||
|
||||
if ! code.valid_encoding?
|
||||
code = code.encode('UTF-16be', :invalid => :replace, :replace => '?').encode('UTF-8')
|
||||
end
|
||||
|
||||
code.scan(code_pattern(wp_target)).flatten.uniq.each do |item_name|
|
||||
names << item_name
|
||||
end
|
||||
@@ -116,7 +120,7 @@ class WpItems < Array
|
||||
wp_content_dir = wp_target.wp_content_dir
|
||||
wp_content_url = wp_target.uri.merge(wp_content_dir).to_s
|
||||
|
||||
url = /#{wp_content_url.gsub(%r{\A(?:http|https)}, 'https?').gsub('/', '\\\\\?\/')}/i
|
||||
url = wp_content_url.gsub(%r{\A(?:http|https)://}, '(?:https?:)?//').gsub('/', '\\\\\?\/')
|
||||
content_dir = %r{(?:#{url}|\\?\/\\?\/?#{wp_content_dir})}i
|
||||
|
||||
%r{#{content_dir}\\?/#{type}\\?/}
|
||||
|
||||
0
lib/common/collections/wp_plugins.rb
Executable file → Normal file
0
lib/common/collections/wp_plugins.rb
Executable file → Normal file
@@ -62,10 +62,14 @@ class WpPlugins < WpItems
|
||||
wp_plugins.add('all-in-one-seo-pack', version: $1)
|
||||
end
|
||||
|
||||
if body =~ /<!-- This site is optimized with the Yoast WordPress SEO plugin v([^\s]+) -/i
|
||||
if body =~ /<!-- This site is optimized with the Yoast (?:WordPress )?SEO plugin v([^\s]+) -/i
|
||||
wp_plugins.add('wordpress-seo', version: $1)
|
||||
end
|
||||
|
||||
if body =~ /<!-- Google Universal Analytics for WordPress v([^\s]+) -/i
|
||||
wp_plugins.add('google-universal-analytics', version: $1)
|
||||
end
|
||||
|
||||
wp_plugins
|
||||
end
|
||||
|
||||
|
||||
0
lib/common/collections/wp_themes.rb
Executable file → Normal file
0
lib/common/collections/wp_themes.rb
Executable file → Normal file
0
lib/common/collections/wp_timthumbs.rb
Executable file → Normal file
0
lib/common/collections/wp_timthumbs.rb
Executable file → Normal file
@@ -41,7 +41,7 @@ class WpTimthumbs < WpItems
|
||||
|
||||
%w{
|
||||
timthumb.php lib/timthumb.php inc/timthumb.php includes/timthumb.php
|
||||
scripts/timthumb.php tools/timthumb.php functions/timthumb.php
|
||||
scripts/timthumb.php tools/timthumb.php functions/timthumb.php thumb.php
|
||||
}.each do |path|
|
||||
wp_timthumb.path = "$wp-content$/themes/#{theme_name}/#{path}"
|
||||
|
||||
|
||||
0
lib/common/collections/wp_users.rb
Executable file → Normal file
0
lib/common/collections/wp_users.rb
Executable file → Normal file
0
lib/common/collections/wp_users/detectable.rb
Executable file → Normal file
0
lib/common/collections/wp_users/detectable.rb
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
LIB_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
||||
LIB_DIR = File.expand_path(File.join(__dir__, '..'))
|
||||
ROOT_DIR = File.expand_path(File.join(LIB_DIR, '..')) # expand_path is used to get "wpscan/" instead of "wpscan/lib/../"
|
||||
DATA_DIR = File.join(ROOT_DIR, 'data')
|
||||
CONF_DIR = File.join(ROOT_DIR, 'conf')
|
||||
@@ -30,7 +30,7 @@ LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update')
|
||||
|
||||
MIN_RUBY_VERSION = '2.1.9'
|
||||
|
||||
WPSCAN_VERSION = '2.9.1'
|
||||
WPSCAN_VERSION = '2.9.2'
|
||||
|
||||
$LOAD_PATH.unshift(LIB_DIR)
|
||||
$LOAD_PATH.unshift(WPSCAN_LIB_DIR)
|
||||
@@ -151,7 +151,7 @@ def banner
|
||||
puts '_______________________________________________________________'
|
||||
puts ' __ _______ _____ '
|
||||
puts ' \\ \\ / / __ \\ / ____| '
|
||||
puts ' \\ \\ /\\ / /| |__) | (___ ___ __ _ _ __ '
|
||||
puts ' \\ \\ /\\ / /| |__) | (___ ___ __ _ _ __ ®'
|
||||
puts ' \\ \\/ \\/ / | ___/ \\___ \\ / __|/ _` | \'_ \\ '
|
||||
puts ' \\ /\\ / | | ____) | (__| (_| | | | |'
|
||||
puts ' \\/ \\/ |_| |_____/ \\___|\\__,_|_| |_|'
|
||||
|
||||
@@ -101,7 +101,7 @@ class DbUpdater
|
||||
puts " [i] Database File Checksum : #{db_checksum}" if verbose
|
||||
|
||||
unless dl_checksum == db_checksum
|
||||
fail "#{filename}: checksums do not match (local: #{dl_checksum} remote: #{db_checksum})"
|
||||
raise ChecksumError.new(File.read(local_file_path(filename))), "#{filename}: checksums do not match (local: #{dl_checksum} remote: #{db_checksum})"
|
||||
end
|
||||
rescue => e
|
||||
puts ' [i] Restoring Backup due to error' if verbose
|
||||
|
||||
@@ -31,3 +31,11 @@ class DownloadError < HttpError
|
||||
"Unable to get #{failure_details}"
|
||||
end
|
||||
end
|
||||
|
||||
class ChecksumError < StandardError
|
||||
attr_reader :file
|
||||
|
||||
def initialize(file)
|
||||
@file = file
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,47 +27,6 @@ def puts(o = '')
|
||||
super(o)
|
||||
end
|
||||
|
||||
module Terminal
|
||||
class Table
|
||||
def render
|
||||
separator = Separator.new(self)
|
||||
buffer = [separator]
|
||||
unless @title.nil?
|
||||
buffer << Row.new(self, [title_cell_options])
|
||||
buffer << separator
|
||||
end
|
||||
unless @headings.cells.empty?
|
||||
buffer << @headings
|
||||
buffer << separator
|
||||
end
|
||||
buffer += @rows
|
||||
buffer << separator
|
||||
buffer.map { |r| style.margin_left + r.render }.join("\n")
|
||||
end
|
||||
alias :to_s :render
|
||||
|
||||
class Style
|
||||
@@defaults = {
|
||||
:border_x => '-', :border_y => '|', :border_i => '+',
|
||||
:padding_left => 1, :padding_right => 1,
|
||||
:margin_left => '',
|
||||
:width => nil, :alignment => nil
|
||||
}
|
||||
|
||||
attr_accessor :margin_left
|
||||
attr_accessor :border_x
|
||||
attr_accessor :border_y
|
||||
attr_accessor :border_i
|
||||
|
||||
attr_accessor :padding_left
|
||||
attr_accessor :padding_right
|
||||
|
||||
attr_accessor :width
|
||||
attr_accessor :alignment
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Numeric
|
||||
def bytes_to_human
|
||||
units = %w{B KB MB GB TB}
|
||||
|
||||
0
lib/common/models/vulnerability.rb
Executable file → Normal file
0
lib/common/models/vulnerability.rb
Executable file → Normal file
0
lib/common/models/wp_item.rb
Executable file → Normal file
0
lib/common/models/wp_item.rb
Executable file → Normal file
0
lib/common/models/wp_item/existable.rb
Executable file → Normal file
0
lib/common/models/wp_item/existable.rb
Executable file → Normal file
3
lib/common/models/wp_item/findable.rb
Executable file → Normal file
3
lib/common/models/wp_item/findable.rb
Executable file → Normal file
@@ -9,8 +9,7 @@ class WpItem
|
||||
#
|
||||
# @return [ void ]
|
||||
def found_from=(method)
|
||||
found = method[%r{find_from_(.*)}, 1]
|
||||
@found_from = found.gsub('_', ' ') if found
|
||||
@found_from = method.to_s.gsub(/find_from_/, '').gsub(/_/, ' ')
|
||||
end
|
||||
|
||||
module Findable
|
||||
|
||||
0
lib/common/models/wp_item/versionable.rb
Executable file → Normal file
0
lib/common/models/wp_item/versionable.rb
Executable file → Normal file
0
lib/common/models/wp_item/vulnerable.rb
Executable file → Normal file
0
lib/common/models/wp_item/vulnerable.rb
Executable file → Normal file
0
lib/common/models/wp_plugin.rb
Executable file → Normal file
0
lib/common/models/wp_plugin.rb
Executable file → Normal file
0
lib/common/models/wp_theme.rb
Executable file → Normal file
0
lib/common/models/wp_theme.rb
Executable file → Normal file
2
lib/common/models/wp_theme/findable.rb
Executable file → Normal file
2
lib/common/models/wp_theme/findable.rb
Executable file → Normal file
@@ -11,7 +11,7 @@ class WpTheme < WpItem
|
||||
def find(target_uri)
|
||||
methods.grep(/^find_from_/).each do |method|
|
||||
if wp_theme = self.send(method, target_uri)
|
||||
wp_theme.found_from = method
|
||||
wp_theme.found_from = method.to_s
|
||||
|
||||
return wp_theme
|
||||
end
|
||||
|
||||
0
lib/common/models/wp_theme/versionable.rb
Executable file → Normal file
0
lib/common/models/wp_theme/versionable.rb
Executable file → Normal file
0
lib/common/models/wp_timthumb.rb
Executable file → Normal file
0
lib/common/models/wp_timthumb.rb
Executable file → Normal file
0
lib/common/models/wp_timthumb/versionable.rb
Executable file → Normal file
0
lib/common/models/wp_timthumb/versionable.rb
Executable file → Normal file
0
lib/common/models/wp_user.rb
Executable file → Normal file
0
lib/common/models/wp_user.rb
Executable file → Normal file
0
lib/common/models/wp_user/existable.rb
Executable file → Normal file
0
lib/common/models/wp_user/existable.rb
Executable file → Normal file
7
lib/common/models/wp_version.rb
Executable file → Normal file
7
lib/common/models/wp_version.rb
Executable file → Normal file
@@ -41,8 +41,11 @@ class WpVersion < WpItem
|
||||
json = json(db_file)
|
||||
|
||||
metadata = {}
|
||||
metadata[:release_date] = json[version]['release_date']
|
||||
metadata[:changelog_url] = json[version]['changelog_url']
|
||||
temp = json[version]
|
||||
if !temp.nil?
|
||||
metadata[:release_date] = temp['release_date']
|
||||
metadata[:changelog_url] = temp['changelog_url']
|
||||
end
|
||||
metadata
|
||||
end
|
||||
end
|
||||
|
||||
20
lib/common/models/wp_version/findable.rb
Executable file → Normal file
20
lib/common/models/wp_version/findable.rb
Executable file → Normal file
@@ -12,6 +12,7 @@ class WpVersion < WpItem
|
||||
#
|
||||
# @return [ WpVersion ]
|
||||
def find(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
|
||||
versions = {}
|
||||
methods.grep(/^find_from_/).each do |method|
|
||||
|
||||
if method === :find_from_advanced_fingerprinting
|
||||
@@ -21,9 +22,21 @@ class WpVersion < WpItem
|
||||
end
|
||||
|
||||
if version
|
||||
return new(target_uri, number: version, found_from: method)
|
||||
if versions.key?(version)
|
||||
versions[version] << method.to_s
|
||||
else
|
||||
versions[version] = [ method.to_s ]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if versions.length > 0
|
||||
determined_version = versions.max_by { |k, v| v.length }
|
||||
if determined_version
|
||||
return new(target_uri, number: determined_version[0], found_from: determined_version[1].join(', '))
|
||||
end
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -199,7 +212,12 @@ class WpVersion < WpItem
|
||||
|
||||
next if attr_value.nil? || attr_value.empty?
|
||||
|
||||
begin
|
||||
uri = Addressable::URI.parse(attr_value)
|
||||
rescue Addressable::URI::InvalidURIError
|
||||
next
|
||||
end
|
||||
|
||||
next unless uri.query && uri.query.match(pattern)
|
||||
|
||||
version = Regexp.last_match[1].to_s
|
||||
|
||||
@@ -12,7 +12,7 @@ class WpVersion < WpItem
|
||||
puts " | Released: #{metadata[:release_date]}"
|
||||
puts " | Changelog: #{metadata[:changelog_url]}"
|
||||
else
|
||||
puts info("WordPress version #{self.number} identified from #{self.found_from} #{"(Released on #{metadata[:release_date]})" if metadata[:release_date]}")
|
||||
puts info("WordPress version #{self.number} #{"(Released on #{metadata[:release_date]}) identified from #{self.found_from}" if metadata[:release_date]}")
|
||||
end
|
||||
|
||||
vulnerabilities = self.vulnerabilities
|
||||
|
||||
@@ -21,6 +21,29 @@ class WebSite
|
||||
@uri.to_s
|
||||
end
|
||||
|
||||
# Checks if the remote website has ssl errors
|
||||
def ssl_error?
|
||||
return false unless @uri.scheme == 'https'
|
||||
c = get_root_path_return_code
|
||||
# http://www.rubydoc.info/github/typhoeus/ethon/Ethon/Easy:return_code
|
||||
return (
|
||||
c == :ssl_connect_error ||
|
||||
c == :peer_failed_verification ||
|
||||
c == :ssl_certproblem ||
|
||||
c == :ssl_cipher ||
|
||||
c == :ssl_cacert ||
|
||||
c == :ssl_cacert_badfile ||
|
||||
c == :ssl_issuer_error ||
|
||||
c == :ssl_crl_badfile ||
|
||||
c == :ssl_engine_setfailed ||
|
||||
c == :ssl_engine_notfound
|
||||
)
|
||||
end
|
||||
|
||||
def get_root_path_return_code
|
||||
Browser.get(@uri.to_s).return_code
|
||||
end
|
||||
|
||||
# Checks if the remote website is up.
|
||||
def online?
|
||||
Browser.get(@uri.to_s).code != 0
|
||||
@@ -68,15 +91,18 @@ class WebSite
|
||||
end
|
||||
|
||||
# Compute the MD5 of the page
|
||||
# Comments are deleted from the page to avoid cache generation details
|
||||
# Comments and scripts are deleted from the page to avoid cache generation details
|
||||
#
|
||||
# @param [ String, Typhoeus::Response ] page The url of the response of the page
|
||||
#
|
||||
# @return [ String ] The MD5 hash of the page
|
||||
def self.page_hash(page)
|
||||
page = Browser.get(page, { followlocation: true, cache_ttl: 0 }) unless page.is_a?(Typhoeus::Response)
|
||||
|
||||
Digest::MD5.hexdigest(page.body.gsub(/<!--.*?-->/m, ''))
|
||||
# remove comments
|
||||
page = page.body.gsub(/<!--.*?-->/m, '')
|
||||
# remove javascript stuff
|
||||
page = page.gsub(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/m, '')
|
||||
Digest::MD5.hexdigest(page)
|
||||
end
|
||||
|
||||
def homepage_hash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../common/common_helper')
|
||||
require File.expand_path(File.join(__dir__, '..', 'common', 'common_helper'))
|
||||
|
||||
require_files_from_directory(WPSCAN_LIB_DIR, '**/*.rb')
|
||||
|
||||
@@ -84,12 +84,17 @@ def help
|
||||
puts ' You do not need to provide the regexp delimiters, but you must write the quotes (simple or double).'
|
||||
puts '--config-file | -c <config file> Use the specified config file, see the example.conf.json.'
|
||||
puts '--user-agent | -a <User-Agent> Use the specified User-Agent.'
|
||||
puts '--cookie <String> String to read cookies from.'
|
||||
puts '--cookie <string> String to read cookies from.'
|
||||
puts '--random-agent | -r Use a random User-Agent.'
|
||||
puts '--follow-redirection If the target url has a redirection, it will be followed without asking if you wanted to do so or not'
|
||||
puts '--batch Never ask for user input, use the default behaviour.'
|
||||
puts '--no-color Do not use colors in the output.'
|
||||
puts '--wp-content-dir <wp content dir> WPScan try to find the content directory (ie wp-content) by scanning the index page, however you can specified it.'
|
||||
puts '--log Creates a log.txt file with WPScan\'s output.'
|
||||
puts '--no-banner Prevents the WPScan banner from being displayed.'
|
||||
puts '--disable-accept-header Prevents WPScan sending the Accept HTTP header.'
|
||||
puts '--disable-referer Prevents setting the Referer header.'
|
||||
puts '--disable-tls-checks Disables SSL/TLS certificate verification.'
|
||||
puts '--wp-content-dir <wp content dir> WPScan try to find the content directory (ie wp-content) by scanning the index page, however you can specify it.'
|
||||
puts ' Subdirectories are allowed.'
|
||||
puts '--wp-plugins-dir <wp plugins dir> Same thing than --wp-content-dir but for the plugins directory.'
|
||||
puts ' If not supplied, WPScan will use wp-content-dir/plugins. Subdirectories are allowed'
|
||||
@@ -100,10 +105,11 @@ def help
|
||||
puts '--wordlist | -w <wordlist> Supply a wordlist for the password brute forcer.'
|
||||
puts '--username | -U <username> Only brute force the supplied username.'
|
||||
puts '--usernames <path-to-file> Only brute force the usernames from the file.'
|
||||
puts '--threads | -t <number of threads> The number of threads to use when multi-threading requests.'
|
||||
puts '--cache-dir <cache-directory> Set the cache directory.'
|
||||
puts '--cache-ttl <cache-ttl> Typhoeus cache TTL.'
|
||||
puts '--request-timeout <request-timeout> Request Timeout.'
|
||||
puts '--connect-timeout <connect-timeout> Connect Timeout.'
|
||||
puts '--threads | -t <number of threads> The number of threads to use when multi-threading requests.'
|
||||
puts '--max-threads <max-threads> Maximum Threads.'
|
||||
puts '--throttle <milliseconds> Milliseconds to wait before doing another web request. If used, the --threads should be set to 1.'
|
||||
puts '--help | -h This help screen.'
|
||||
|
||||
@@ -43,7 +43,11 @@ class WpscanOptions
|
||||
:connect_timeout,
|
||||
:max_threads,
|
||||
:no_banner,
|
||||
:throttle
|
||||
:throttle,
|
||||
:disable_accept_header,
|
||||
:disable_referer,
|
||||
:cache_dir,
|
||||
:disable_tls_checks
|
||||
]
|
||||
|
||||
attr_accessor *ACCESSOR_OPTIONS
|
||||
@@ -208,7 +212,9 @@ class WpscanOptions
|
||||
|
||||
enumerate_options_from_string(cli_value)
|
||||
else
|
||||
raise "Unknow option : #{cli_option} with value #{cli_value}"
|
||||
text = "Unknown option : #{cli_option}"
|
||||
text << " with value #{cli_value}" if (cli_value && !cli_value.empty?)
|
||||
raise text
|
||||
end
|
||||
end
|
||||
|
||||
@@ -282,7 +288,11 @@ class WpscanOptions
|
||||
['--cookie', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--log', GetoptLong::NO_ARGUMENT],
|
||||
['--no-banner', GetoptLong::NO_ARGUMENT],
|
||||
['--throttle', GetoptLong::REQUIRED_ARGUMENT]
|
||||
['--throttle', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--disable-accept-header', GetoptLong::NO_ARGUMENT],
|
||||
['--disable-referer', GetoptLong::NO_ARGUMENT],
|
||||
['--cache-dir', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--disable-tls-checks', GetoptLong::NO_ARGUMENT],
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -124,11 +124,10 @@ describe Browser do
|
||||
describe '#merge_request_params' do
|
||||
let(:params) { {} }
|
||||
let(:cookie_jar) { CACHE_DIR + '/browser/cookie-jar' }
|
||||
let(:user_agent) { 'SomeUA' }
|
||||
let(:default_expectation) {
|
||||
{
|
||||
cache_ttl: 250,
|
||||
headers: { 'User-Agent' => 'SomeUA' },
|
||||
ssl_verifypeer: false, ssl_verifyhost: 0,
|
||||
cookiejar: cookie_jar, cookiefile: cookie_jar,
|
||||
timeout: 60, connecttimeout: 10,
|
||||
maxredirs: 3,
|
||||
@@ -137,16 +136,25 @@ describe Browser do
|
||||
}
|
||||
|
||||
after :each do
|
||||
browser.user_agent = 'SomeUA'
|
||||
browser.user_agent = user_agent
|
||||
browser.cache_ttl = 250
|
||||
|
||||
expect(browser.merge_request_params(params)).to eq @expected
|
||||
expect(Typhoeus::Config.user_agent).to eq user_agent
|
||||
end
|
||||
|
||||
it 'sets the User-Agent header field and cache_ttl' do
|
||||
@expected = default_expectation
|
||||
end
|
||||
|
||||
context 'when @user_agent' do
|
||||
let(:user_agent) { 'test' }
|
||||
|
||||
it 'sets the User-Agent' do
|
||||
@expected = default_expectation
|
||||
end
|
||||
end
|
||||
|
||||
context 'when @proxy' do
|
||||
let(:proxy) { '127.0.0.1:9050' }
|
||||
let(:proxy_expectation) { default_expectation.merge(proxy: proxy) }
|
||||
@@ -177,7 +185,7 @@ describe Browser do
|
||||
it 'appends the basic_auth' do
|
||||
browser.basic_auth = 'user:pass'
|
||||
@expected = default_expectation.merge(
|
||||
headers: default_expectation[:headers].merge('Authorization' => 'Basic ' + Base64.encode64('user:pass').chomp)
|
||||
headers: { 'Authorization' => 'Basic ' + Base64.encode64('user:pass').chomp }
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -206,6 +214,13 @@ describe Browser do
|
||||
@expected = default_expectation.merge(cookie: cookie)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when @disable_tls_checks' do
|
||||
it 'disables tls checks' do
|
||||
browser.disable_tls_checks = true
|
||||
@expected = default_expectation.merge(ssl_verifypeer: 0, ssl_verifyhost: 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#forge_request' do
|
||||
|
||||
@@ -18,7 +18,7 @@ describe WpItems do
|
||||
vulnerable_targets_items: [ WpItem.new(uri, name: 'mr-smith'),
|
||||
WpItem.new(uri, name: 'neo')],
|
||||
|
||||
passive_detection: (1..13).reduce(WpItems.new) { |o, i| o << WpItem.new(uri, name: "detect-me-#{i}") }
|
||||
passive_detection: (1..15).reduce(WpItems.new) { |o, i| o << WpItem.new(uri, name: "detect-me-#{i}") }
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -100,6 +100,13 @@ describe 'WpPlugins::Detectable' do
|
||||
expected.add('all-in-one-seo-pack', version: '2.0.3.1')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when google-universal-analytics detected' do
|
||||
it 'returns google-universal-analytics' do
|
||||
@body = '<!-- Google Universal Analytics for WordPress v2.4.2 -->'
|
||||
expected.add('google-universal-analytics', version: '2.4.2')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ describe 'WpTimthumbs::Detectable' do
|
||||
expected = []
|
||||
%w(
|
||||
timthumb.php lib/timthumb.php inc/timthumb.php includes/timthumb.php
|
||||
scripts/timthumb.php tools/timthumb.php functions/timthumb.php
|
||||
scripts/timthumb.php tools/timthumb.php functions/timthumb.php thumb.php
|
||||
).each do |file|
|
||||
path = "$wp-content$/themes/#{theme_name}/#{file}"
|
||||
expected << WpTimthumb.new(uri, path: path)
|
||||
|
||||
@@ -159,6 +159,22 @@ describe 'WpVersion::Findable' do
|
||||
end
|
||||
end
|
||||
|
||||
describe '::find_from_stylesheets_numbers' do
|
||||
after do
|
||||
fixture = fixtures_dir + 'stylesheet_numbers' + @fixture
|
||||
stub_request_to_fixture(url: uri, fixture: fixture)
|
||||
|
||||
expect(WpVersion.send(:find_from_stylesheets_numbers, uri)).to eq @expected
|
||||
end
|
||||
|
||||
context 'invalid url' do
|
||||
it 'returns nil' do
|
||||
@fixture = '/invalid_url.html'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '::find' do
|
||||
# Stub all WpVersion::find_from_* to return nil
|
||||
def stub_all_to_nil
|
||||
|
||||
@@ -160,6 +160,11 @@ describe 'VersionCompare' do
|
||||
@version1 = '.47'
|
||||
@version2 = '.50.3'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '2.5.9'
|
||||
@version2 = '2.5.10'
|
||||
end
|
||||
end
|
||||
|
||||
context 'version checked is older' do
|
||||
|
||||
@@ -176,6 +176,17 @@ describe 'WebSite' do
|
||||
@expected = "yolo\n\n\nworld!"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are scripts' do
|
||||
let(:page) {
|
||||
body = "yolo\n\n<script type=\"text/javascript\">alert('Hi');</script>\nworld!"
|
||||
Typhoeus::Response.new(body: body)
|
||||
}
|
||||
|
||||
it 'removes them' do
|
||||
@expected = "yolo\n\n\nworld!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#homepage_hash' do
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
|
||||
require File.expand_path(File.join(__dir__, 'wpscan_helper'))
|
||||
|
||||
describe WpTarget do
|
||||
subject(:wp_target) { WpTarget.new(target_url, options) }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
|
||||
require File.expand_path(File.join(__dir__, 'wpscan_helper'))
|
||||
|
||||
describe 'WpscanOptions' do
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
<script type='text/javascript' src='//wp-content/items/detect-me-5/main.js'></script>
|
||||
|
||||
<link rel='stylesheet' id='ai1ec_style-css' href='//example.com/wp-content/items/detect-me-15/test.css' type='text/css' media='all' />
|
||||
|
||||
<style type="text/css">
|
||||
#fancybox-loading.fancybox-ie div {
|
||||
background: transparent;
|
||||
@@ -32,6 +34,7 @@
|
||||
@import url('/wp-content/items/detect-me-8/css/datatables.css?ver=1.9.4');
|
||||
@import url(/wp-content/items/detect-me-9/css/datatables.css?ver=1.9.4);
|
||||
@import url(//wp-content/items/detect-me-10/css/datatables.css?ver=1.9.4);
|
||||
@import url(//example.com/wp-content/items/detect-me-14/css/datatables.css?ver=1.9.4);
|
||||
/* ]]> */
|
||||
</style>
|
||||
|
||||
|
||||
0
spec/samples/common/models/wp_item/error_log
Executable file → Normal file
0
spec/samples/common/models/wp_item/error_log
Executable file → Normal file
0
spec/samples/common/models/wp_item/versionable/simple-login-lockdown-0.4.txt
Executable file → Normal file
0
spec/samples/common/models/wp_item/versionable/simple-login-lockdown-0.4.txt
Executable file → Normal file
0
spec/samples/common/models/wp_item/versionable/trunk-version.txt
Executable file → Normal file
0
spec/samples/common/models/wp_item/versionable/trunk-version.txt
Executable file → Normal file
0
spec/samples/common/models/wp_theme/versionable/bueno-1.5.1.css
Executable file → Normal file
0
spec/samples/common/models/wp_theme/versionable/bueno-1.5.1.css
Executable file → Normal file
0
spec/samples/common/models/wp_theme/versionable/twentyeleven-1.3.css
Executable file → Normal file
0
spec/samples/common/models/wp_theme/versionable/twentyeleven-1.3.css
Executable file → Normal file
0
spec/samples/common/models/wp_theme/versionable/twentyeleven-unknow.css
Executable file → Normal file
0
spec/samples/common/models/wp_theme/versionable/twentyeleven-unknow.css
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/3.3.2.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/3.3.2.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/3.4-beta4.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/3.4-beta4.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/invalid_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/invalid_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/no_generator.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/meta_generator/no_generator.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/readme/3.3.2.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/readme/3.3.2.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/readme/empty_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/readme/empty_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/readme/invalid_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/readme/invalid_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/3.3.2.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/3.3.2.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/3.4-beta4.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/3.4-beta4.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/invalid_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/invalid_version.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/no_generator.html
Executable file → Normal file
0
spec/samples/common/models/wp_version/findable/rss_generator/no_generator.html
Executable file → Normal file
@@ -0,0 +1,8 @@
|
||||
<script src="//use.typekit.net/h3 {
|
||||
font-family: 'Century Gothic', CenturyGothic, AppleGothic, sans-serif;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
font-weight: 500;
|
||||
line-height: 15px;.js"></script><script>try{Typekit.load();}catch(e){}</script>
|
||||
|
||||
0
spec/samples/wpscan/web_site/rss_url/wordpress-3.5.htm
Executable file → Normal file
0
spec/samples/wpscan/web_site/rss_url/wordpress-3.5.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp-login.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp-login.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_config_backup/wp-config.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_config_backup/wp-config.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/facebook-detection.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/facebook-detection.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-custom-subdirectories.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-custom-subdirectories.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-custom-with-spaces.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-custom-with-spaces.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-custom.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-custom.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-in-src.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1-in-src.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_content_dir/wordpress-3.4.1.htm
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_full_path_disclosure/rss-functions-disclosure.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_full_path_disclosure/rss-functions-disclosure.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_login_protection/wp-login-clean.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_login_protection/wp-login-clean.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_login_protection/wp-login-login_lock.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_login_protection/wp-login-login_lock.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_login_protection/wp-login-login_lockdown.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_login_protection/wp-login-login_lockdown.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_readme/readme-3.2.1.html
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_readme/readme-3.2.1.html
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_readme/readme-3.3.2-fr.html
Executable file → Normal file
0
spec/samples/wpscan/wp_target/wp_readme/readme-3.3.2-fr.html
Executable file → Normal file
0
spec/samples/wpscan/wp_target/xmlrpc.php
Executable file → Normal file
0
spec/samples/wpscan/wp_target/xmlrpc.php
Executable file → Normal file
@@ -7,12 +7,6 @@ shared_examples 'WpItem::Findable#Found_From=' do
|
||||
subject.found_from = @method
|
||||
expect(subject.found_from).to eq @expected
|
||||
end
|
||||
context 'when the pattern is not found' do
|
||||
it 'returns nil' do
|
||||
@method = 'I_do_not_match'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
it 'replaces _ by space' do
|
||||
@method = 'find_from_some_detection_method'
|
||||
|
||||
@@ -7,7 +7,7 @@ require 'simplecov' if RUBY_VERSION >= '1.9'
|
||||
|
||||
RSpec::Expectations.configuration.warn_about_potential_false_positives = false
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../lib/common/common_helper')
|
||||
require File.expand_path(File.join(__dir__, '..', 'lib', 'common', 'common_helper'))
|
||||
|
||||
SPEC_DIR = ROOT_DIR + '/spec'
|
||||
SPEC_LIB_DIR = SPEC_DIR + '/lib'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# Script based on http://seclists.org/fulldisclosure/2014/Feb/3
|
||||
|
||||
require File.join(File.dirname(__FILE__), 'lib/wpscan/wpscan_helper')
|
||||
require File.join(__dir__, 'lib', 'wpscan', 'wpscan_helper')
|
||||
|
||||
@opts = {
|
||||
ids: 1..10,
|
||||
|
||||
28
wpscan.rb
28
wpscan.rb
@@ -5,7 +5,7 @@ $: << '.'
|
||||
|
||||
$exit_code = 0
|
||||
|
||||
require File.dirname(__FILE__) + '/lib/wpscan/wpscan_helper'
|
||||
require File.join(__dir__, 'lib', 'wpscan', 'wpscan_helper')
|
||||
|
||||
def main
|
||||
# delete old logfile, check if it is a symlink first.
|
||||
@@ -62,7 +62,7 @@ def main
|
||||
exit(1)
|
||||
else
|
||||
if missing_db_file?
|
||||
puts critical('You can not run a scan without any databases.')
|
||||
puts critical('You can not run a scan without any databases. Extract the data.zip file.')
|
||||
exit(1)
|
||||
end
|
||||
end
|
||||
@@ -86,9 +86,13 @@ def main
|
||||
raise 'We do not support scanning *.wordpress.com hosted blogs'
|
||||
end
|
||||
|
||||
if wp_target.ssl_error?
|
||||
raise "The target site returned an SSL/TLS error. You can try again using the --disable-tls-checks option.\nError: #{wp_target.get_root_path_return_code}\nSee here for a detailed explanation of the error: http://www.rubydoc.info/github/typhoeus/ethon/Ethon/Easy:return_code"
|
||||
end
|
||||
|
||||
# Remote website up?
|
||||
unless wp_target.online?
|
||||
raise "The WordPress URL supplied '#{wp_target.uri}' seems to be down."
|
||||
raise "The WordPress URL supplied '#{wp_target.uri}' seems to be down. Maybe the site is blocking wpscan so you can try the --random-agent parameter."
|
||||
end
|
||||
|
||||
if wpscan_options.proxy
|
||||
@@ -372,7 +376,7 @@ def main
|
||||
puts info('Enumerating usernames ...')
|
||||
|
||||
if wp_target.has_plugin?('stop-user-enumeration')
|
||||
puts warning("Stop User Enumeration plugin detected, results might be empty. However a bypass exists for v1.2.8 and below, see stop_user_enumeration_bypass.rb in #{File.expand_path(File.dirname(__FILE__))}")
|
||||
puts warning("Stop User Enumeration plugin detected, results might be empty. However a bypass exists for v1.2.8 and below, see stop_user_enumeration_bypass.rb in #{__dir__}")
|
||||
end
|
||||
|
||||
wp_users = WpUsers.aggressive_detection(wp_target,
|
||||
@@ -452,8 +456,22 @@ def main
|
||||
puts info("Memory used: #{used_memory.bytes_to_human}") unless windows?
|
||||
puts info("Elapsed time: #{Time.at(elapsed).utc.strftime('%H:%M:%S')}")
|
||||
|
||||
rescue Interrupt
|
||||
# do nothing on interrupt
|
||||
rescue Interrupt
|
||||
exit(1)
|
||||
# Error on Updating
|
||||
rescue ChecksumError => e
|
||||
puts critical(e.message)
|
||||
|
||||
if e.file
|
||||
puts critical('Downloaded File Content:')
|
||||
puts e.file[0..500]
|
||||
puts '.........'
|
||||
puts
|
||||
end
|
||||
|
||||
puts critical('Please submit this info as an Github issue')
|
||||
exit(1)
|
||||
rescue => e
|
||||
puts
|
||||
puts critical(e.message)
|
||||
|
||||
Reference in New Issue
Block a user