Compare commits
122 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 | ||
|
|
f832e27b49 | ||
|
|
6ce29f73c5 | ||
|
|
920338fb62 | ||
|
|
49d0a9e6d9 | ||
|
|
fe401e622b | ||
|
|
6e32cb0db2 | ||
|
|
73171eb39d | ||
|
|
2e05f4171e | ||
|
|
75b8c303e2 | ||
|
|
bd7a493f1c | ||
|
|
9dada7c8f4 | ||
|
|
fe7aede458 | ||
|
|
cdf2b38780 | ||
|
|
a09dbab6a8 | ||
|
|
49a6d275d2 | ||
|
|
8192a4a215 | ||
|
|
1d6593fd4d | ||
|
|
bf99e31e70 | ||
|
|
5386496bdc | ||
|
|
6451510449 | ||
|
|
cd68aa719c | ||
|
|
b328dc4ff9 | ||
|
|
1e1c79aa56 | ||
|
|
08650ce156 | ||
|
|
a1929719f3 | ||
|
|
d34da72cd3 | ||
|
|
816b18b604 | ||
|
|
a78a13bf3f | ||
|
|
33f8aaf1dc | ||
|
|
26ab95d822 | ||
|
|
cea01d8aa0 | ||
|
|
0e61f1e284 | ||
|
|
ddef061b90 | ||
|
|
addeab8947 | ||
|
|
55dc665404 | ||
|
|
8f8538e9e9 | ||
|
|
348ca55bee | ||
|
|
1bb5bc7f33 | ||
|
|
3be5e1fcf5 | ||
|
|
9df8cc9243 | ||
|
|
e28c84aa34 | ||
|
|
7db6b54761 | ||
|
|
e3a06f5694 | ||
|
|
7c5d15e098 | ||
|
|
d683c0f151 | ||
|
|
1e67fa26ff | ||
|
|
0ae6ef59ec | ||
|
|
e27ef40e0f | ||
|
|
380760d028 | ||
|
|
18cfdafc19 | ||
|
|
0934a2e329 | ||
|
|
d1a320324e |
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
|
||||||
@@ -1 +1 @@
|
|||||||
2.2.3
|
2.3.1
|
||||||
|
|||||||
18
.travis.yml
18
.travis.yml
@@ -2,28 +2,22 @@ language: ruby
|
|||||||
sudo: false
|
sudo: false
|
||||||
cache: bundler
|
cache: bundler
|
||||||
rvm:
|
rvm:
|
||||||
- 1.9.2
|
- 2.1.9
|
||||||
- 1.9.3
|
|
||||||
- 2.0.0
|
|
||||||
- 2.1.0
|
|
||||||
- 2.1.1
|
|
||||||
- 2.1.2
|
|
||||||
- 2.1.3
|
|
||||||
- 2.1.4
|
|
||||||
- 2.1.5
|
|
||||||
- 2.2.0
|
- 2.2.0
|
||||||
- 2.2.1
|
- 2.2.1
|
||||||
- 2.2.2
|
- 2.2.2
|
||||||
- 2.2.3
|
- 2.2.3
|
||||||
|
- 2.2.4
|
||||||
|
- 2.3.0
|
||||||
|
- 2.3.1
|
||||||
before_install:
|
before_install:
|
||||||
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
||||||
|
before_script:
|
||||||
|
- "unzip -o $TRAVIS_BUILD_DIR/data.zip -d $TRAVIS_BUILD_DIR"
|
||||||
script: bundle exec rspec
|
script: bundle exec rspec
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
- team@wpscan.org
|
- team@wpscan.org
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- rvm: 1.9.2
|
|
||||||
# do not build gh-pages branch
|
# do not build gh-pages branch
|
||||||
branches:
|
branches:
|
||||||
except:
|
except:
|
||||||
|
|||||||
47
CHANGELOG.md
47
CHANGELOG.md
@@ -1,6 +1,48 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
## Master
|
## Master
|
||||||
[Work in progress](https://github.com/wpscanteam/wpscan/compare/2.9...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
|
||||||
|
|
||||||
|
* Update to Ruby 2.3.1, drop older ruby support
|
||||||
|
* New data file location
|
||||||
|
* Added experimental Windows support
|
||||||
|
* Display WordPress metadata on the detected version
|
||||||
|
* Several small fixes
|
||||||
|
|
||||||
|
WPScan Database Statistics:
|
||||||
|
* Total vulnerable versions: 156
|
||||||
|
* Total vulnerable plugins: 1324
|
||||||
|
* Total vulnerable themes: 376
|
||||||
|
* Total version vulnerabilities: 1998
|
||||||
|
* Total plugin vulnerabilities: 2057
|
||||||
|
* Total theme vulnerabilities: 449
|
||||||
|
|
||||||
## Version 2.9
|
## Version 2.9
|
||||||
Released: 2015-10-15
|
Released: 2015-10-15
|
||||||
@@ -137,7 +179,7 @@ New
|
|||||||
* Add Sucuri sponsor to banner
|
* Add Sucuri sponsor to banner
|
||||||
* Add protocol to sucuri url in banner
|
* Add protocol to sucuri url in banner
|
||||||
* Add response code to proxy error output
|
* Add response code to proxy error output
|
||||||
* Add a statement about mendatory newlines at the end of list
|
* Add a statement about mandatory newlines at the end of list
|
||||||
* Give warning if default username 'admin' is still used
|
* Give warning if default username 'admin' is still used
|
||||||
* License amendment to make it more clear about value added usage
|
* License amendment to make it more clear about value added usage
|
||||||
|
|
||||||
@@ -493,4 +535,3 @@ Fixed issues
|
|||||||
|
|
||||||
## Version 2.1
|
## Version 2.1
|
||||||
Released 2013-3-4
|
Released 2013-3-4
|
||||||
|
|
||||||
|
|||||||
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"]
|
||||||
8
Gemfile
8
Gemfile
@@ -1,12 +1,10 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'typhoeus', '~>0.8.0'
|
gem 'typhoeus', '>=1.0.0'
|
||||||
gem 'nokogiri'
|
gem 'nokogiri', '>=1.6.7.2'
|
||||||
gem 'addressable'
|
gem 'addressable'
|
||||||
gem 'yajl-ruby' # Better JSON parser regarding memory usage
|
gem 'yajl-ruby' # Better JSON parser regarding memory usage
|
||||||
# TODO: update the below when terminal-table 1.5.3+ is released.
|
gem 'terminal-table', '>=1.6.0'
|
||||||
# (and delete the Terminal module in lib/common/hacks.rb)
|
|
||||||
gem 'terminal-table', '~>1.4.5'
|
|
||||||
gem 'ruby-progressbar', '>=1.6.0'
|
gem 'ruby-progressbar', '>=1.6.0'
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
|||||||
6
LICENSE
6
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
WPScan Public Source License
|
WPScan Public Source License
|
||||||
|
|
||||||
The WPScan software (henceforth referred to simply as "WPScan") is dual-licensed - Copyright 2011-2015 WPScan Team.
|
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.
|
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.
|
||||||
|
|
||||||
@@ -68,3 +68,7 @@ To the extent permitted under Law, WPScan is provided under an AS-IS basis. The
|
|||||||
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.
|
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.
|
||||||
|
|||||||
220
README.md
220
README.md
@@ -4,16 +4,17 @@
|
|||||||
[](https://travis-ci.org/wpscanteam/wpscan)
|
[](https://travis-ci.org/wpscanteam/wpscan)
|
||||||
[](https://codeclimate.com/github/wpscanteam/wpscan)
|
[](https://codeclimate.com/github/wpscanteam/wpscan)
|
||||||
[](https://gemnasium.com/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-2015 WPScan Team.
|
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.
|
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.
|
||||||
|
|
||||||
@@ -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.
|
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.
|
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;
|
Free-use Terms and Conditions;
|
||||||
|
|
||||||
##### 3. Redistribution
|
### 3. Redistribution
|
||||||
|
|
||||||
Redistribution is permitted under the following conditions:
|
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.
|
- Unmodified Copyright notices are provided with WPScan.
|
||||||
- Does not conflict with the commercialization clause.
|
- 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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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:
|
WPScan comes pre-installed on the following Linux distributions:
|
||||||
|
|
||||||
@@ -90,73 +95,49 @@ WPScan comes pre-installed on the following Linux distributions:
|
|||||||
- [SamuraiWTF](http://samurai.inguardians.com/)
|
- [SamuraiWTF](http://samurai.inguardians.com/)
|
||||||
- [BlackArch](http://blackarch.org/)
|
- [BlackArch](http://blackarch.org/)
|
||||||
|
|
||||||
Prerequisites:
|
Windows is not supported
|
||||||
|
|
||||||
- Ruby >= 1.9.2 - Recommended: 2.2.3
|
## Prerequisites
|
||||||
|
|
||||||
|
- Ruby >= 2.1.9 - Recommended: 2.3.1
|
||||||
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
||||||
- RubyGems - Recommended: latest
|
- RubyGems - Recommended: latest
|
||||||
- Git
|
- Git
|
||||||
|
|
||||||
Windows is not supported.
|
### Installing dependencies on Ubuntu
|
||||||
If installed from Github update the code base with ```git pull```. The databases are updated with ```wpscan.rb --update```.
|
|
||||||
|
|
||||||
####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:
|
### Installing dependencies on Debian
|
||||||
|
|
||||||
sudo apt-get install libcurl4-openssl-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev ruby-dev
|
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
|
|
||||||
|
|
||||||
From Ubuntu 14.04:
|
### Installing dependencies on Fedora
|
||||||
|
|
||||||
sudo apt-get install libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev ruby-dev build-essential libgmp-dev
|
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 Debian:
|
### Installing dependencies on Arch Linux
|
||||||
|
|
||||||
sudo apt-get install git ruby ruby-dev libcurl4-openssl-dev make
|
|
||||||
git clone https://github.com/wpscanteam/wpscan.git
|
|
||||||
cd wpscan
|
|
||||||
sudo gem install bundler
|
|
||||||
bundle install --without test --path vendor/bundle
|
|
||||||
|
|
||||||
####Installing on Fedora:
|
|
||||||
|
|
||||||
sudo yum install gcc ruby-devel libxml2 libxml2-devel libxslt libxslt-devel libcurl-devel patch
|
|
||||||
git clone https://github.com/wpscanteam/wpscan.git
|
|
||||||
cd wpscan
|
|
||||||
sudo gem install bundler && bundle install --without test
|
|
||||||
|
|
||||||
####Installing on Archlinux:
|
|
||||||
|
|
||||||
pacman -Syu ruby
|
pacman -Syu ruby
|
||||||
pacman -Syu libyaml
|
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)
|
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
|
## Installing with RVM (recommended)
|
||||||
cd wpscan
|
|
||||||
sudo gem install bundler && sudo bundle install --without test
|
|
||||||
|
|
||||||
####Installing with RVM:
|
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 ~
|
cd ~
|
||||||
|
curl -sSL https://rvm.io/mpapis.asc | gpg --import -
|
||||||
curl -sSL https://get.rvm.io | bash -s stable
|
curl -sSL https://get.rvm.io | bash -s stable
|
||||||
source ~/.rvm/scripts/rvm
|
source ~/.rvm/scripts/rvm
|
||||||
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
|
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
|
||||||
rvm install 2.2.3
|
rvm install 2.3.1
|
||||||
rvm use 2.2.3 --default
|
rvm use 2.3.1 --default
|
||||||
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
|
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
|
||||||
gem install bundler
|
gem install bundler
|
||||||
git clone https://github.com/wpscanteam/wpscan.git
|
git clone https://github.com/wpscanteam/wpscan.git
|
||||||
@@ -164,7 +145,26 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
|||||||
gem install bundler
|
gem install bundler
|
||||||
bundle install --without test
|
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
|
- Typhoeus segmentation fault
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
|||||||
|
|
||||||
Then, open the directory of the readline gem (you have to locate it)
|
Then, open the directory of the readline gem (you have to locate it)
|
||||||
|
|
||||||
cd ~/.rvm/src/ruby-1.9.2-p180/ext/readline
|
cd ~/.rvm/src/ruby-XXXX/ext/readline
|
||||||
ruby extconf.rb
|
ruby extconf.rb
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
@@ -207,14 +207,11 @@ 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)
|
See [https://github.com/wpscanteam/wpscan/issues/148](https://github.com/wpscanteam/wpscan/issues/148)
|
||||||
|
|
||||||
#### WPSCAN ARGUMENTS
|
# WPSCAN ARGUMENTS
|
||||||
|
|
||||||
--update Update the databases.
|
|
||||||
|
|
||||||
|
--update Update the database to the latest version.
|
||||||
--url | -u <target url> The WordPress URL/domain to scan.
|
--url | -u <target url> The WordPress URL/domain to scan.
|
||||||
|
|
||||||
--force | -f Forces WPScan to not check if the remote site is running WordPress.
|
--force | -f Forces WPScan to not check if the remote site is running WordPress.
|
||||||
|
|
||||||
--enumerate | -e [option(s)] Enumeration.
|
--enumerate | -e [option(s)] Enumeration.
|
||||||
option :
|
option :
|
||||||
u usernames from id 1 to 10
|
u usernames from id 1 to 10
|
||||||
@@ -229,55 +226,44 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
|||||||
Multiple values are allowed : "-e tt,p" will enumerate timthumbs and plugins
|
Multiple values are allowed : "-e tt,p" will enumerate timthumbs and plugins
|
||||||
If no option is supplied, the default is "vt,tt,u,vp"
|
If no option is supplied, the default is "vt,tt,u,vp"
|
||||||
|
|
||||||
--exclude-content-based "<regexp or string>" Used with the enumeration option, will exclude all occurrences based on the regexp or string supplied
|
--exclude-content-based "<regexp or string>"
|
||||||
You do not need to provide the regexp delimiters, but you must write the quotes (simple or double)
|
Used with the enumeration option, will exclude all occurrences based on the regexp or string supplied.
|
||||||
|
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
|
--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.
|
||||||
--user-agent | -a <User-Agent> Use the specified User-Agent
|
--cookie <string> String to read cookies from.
|
||||||
|
--random-agent | -r Use a random User-Agent.
|
||||||
--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
|
--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.
|
||||||
--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. 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
|
|
||||||
|
|
||||||
--proxy <[protocol://]host:port> Supply a proxy (will override the one from conf/browser.conf.json).
|
|
||||||
HTTP, SOCKS4 SOCKS4A and SOCKS5 are supported. If no protocol is given (format host:port), HTTP will be used
|
|
||||||
|
|
||||||
--proxy-auth <username:password> Supply the proxy login credentials.
|
|
||||||
|
|
||||||
--basic-auth <username:password> Set the HTTP Basic authentication.
|
|
||||||
|
|
||||||
--wordlist | -w <wordlist> Supply a wordlist for the password brute forcer.
|
|
||||||
|
|
||||||
--threads | -t <number of threads> The number of threads to use when multi-threading requests.
|
|
||||||
|
|
||||||
--username | -U <username> Only brute force the supplied username.
|
|
||||||
|
|
||||||
--usernames <path-to-file> Only brute force the usernames from the file.
|
|
||||||
|
|
||||||
--cache-ttl <cache-ttl> Typhoeus cache TTL.
|
|
||||||
|
|
||||||
--request-timeout <request-timeout> Request Timeout.
|
|
||||||
|
|
||||||
--connect-timeout <connect-timeout> Connect Timeout.
|
|
||||||
|
|
||||||
--max-threads <max-threads> Maximum Threads.
|
|
||||||
|
|
||||||
--help | -h This help screen.
|
|
||||||
|
|
||||||
--verbose | -v Verbose output.
|
|
||||||
|
|
||||||
--batch Never ask for user input, use the default behavior.
|
|
||||||
|
|
||||||
--no-color Do not use colors in the output.
|
--no-color Do not use colors in the output.
|
||||||
|
--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
|
||||||
|
--proxy <[protocol://]host:port> Supply a proxy. HTTP, SOCKS4 SOCKS4A and SOCKS5 are supported.
|
||||||
|
If no protocol is given (format host:port), HTTP will be used.
|
||||||
|
--proxy-auth <username:password> Supply the proxy login credentials.
|
||||||
|
--basic-auth <username:password> Set the HTTP Basic authentication.
|
||||||
|
--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.
|
||||||
|
--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.
|
||||||
|
|
||||||
--log Save STDOUT to log.txt
|
# WPSCAN EXAMPLES
|
||||||
|
|
||||||
#### WPSCAN EXAMPLES
|
|
||||||
|
|
||||||
Do 'non-intrusive' checks...
|
Do 'non-intrusive' checks...
|
||||||
|
|
||||||
@@ -311,26 +297,22 @@ Debug output...
|
|||||||
|
|
||||||
```ruby wpscan.rb --url www.example.com --debug-output 2>debug.log```
|
```ruby wpscan.rb --url www.example.com --debug-output 2>debug.log```
|
||||||
|
|
||||||
#### PROJECT HOME
|
# PROJECT HOME
|
||||||
|
|
||||||
[http://www.wpscan.org](http://www.wpscan.org)
|
[http://www.wpscan.org](http://www.wpscan.org)
|
||||||
|
|
||||||
#### VULNERABILITY DATABASE
|
# VULNERABILITY DATABASE
|
||||||
|
|
||||||
[https://wpvulndb.com](https://wpvulndb.com)
|
[https://wpvulndb.com](https://wpvulndb.com)
|
||||||
|
|
||||||
#### GIT REPOSITORY
|
# GIT REPOSITORY
|
||||||
|
|
||||||
[https://github.com/wpscanteam/wpscan](https://github.com/wpscanteam/wpscan)
|
[https://github.com/wpscanteam/wpscan](https://github.com/wpscanteam/wpscan)
|
||||||
|
|
||||||
#### ISSUES
|
# ISSUES
|
||||||
|
|
||||||
[https://github.com/wpscanteam/wpscan/issues](https://github.com/wpscanteam/wpscan/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)
|
[http://rdoc.info/github/wpscanteam/wpscan/frames](http://rdoc.info/github/wpscanteam/wpscan/frames)
|
||||||
|
|
||||||
#### SPECIAL THANKS
|
|
||||||
|
|
||||||
[RandomStorm](https://www.randomstorm.com)
|
|
||||||
|
|||||||
19
dev/stats.rb
Executable file
19
dev/stats.rb
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
require File.expand_path(File.join(__dir__, '..', 'lib', 'wpscan', 'wpscan_helper'))
|
||||||
|
|
||||||
|
wordpress_json = json(WORDPRESSES_FILE)
|
||||||
|
plugins_json = json(PLUGINS_FILE)
|
||||||
|
themes_json = json(THEMES_FILE)
|
||||||
|
|
||||||
|
puts 'WPScan Database Statistics:'
|
||||||
|
puts "* Total tracked wordpresses: #{wordpress_json.count}"
|
||||||
|
puts "* Total tracked plugins: #{plugins_json.count}"
|
||||||
|
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: #{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,
|
:request_timeout,
|
||||||
:connect_timeout,
|
:connect_timeout,
|
||||||
:cookie,
|
:cookie,
|
||||||
:throttle
|
:throttle,
|
||||||
|
:disable_accept_header,
|
||||||
|
:disable_referer,
|
||||||
|
:disable_tls_checks
|
||||||
]
|
]
|
||||||
|
|
||||||
@@instance = nil
|
@@instance = nil
|
||||||
@@ -67,17 +70,23 @@ class Browser
|
|||||||
@@instance = nil
|
@@instance = nil
|
||||||
end
|
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
|
# sets browser default values
|
||||||
#
|
#
|
||||||
def browser_defaults
|
def browser_defaults
|
||||||
|
Typhoeus::Config.user_agent = "WPScan v#{WPSCAN_VERSION} (http://wpscan.org)"
|
||||||
@max_threads = 20
|
@max_threads = 20
|
||||||
# 10 minutes, at this time the cache is cleaned before each scan.
|
# 10 minutes, at this time the cache is cleaned before each scan.
|
||||||
# If this value is set to 0, the cache will be disabled
|
# If this value is set to 0, the cache will be disabled
|
||||||
@cache_ttl = 600
|
@cache_ttl = 600
|
||||||
@request_timeout = 60 # 60s
|
@request_timeout = 60 # 60s
|
||||||
@connect_timeout = 10 # 10s
|
@connect_timeout = 10 # 10s
|
||||||
@user_agent = "WPScan v#{WPSCAN_VERSION} (http://wpscan.org)"
|
|
||||||
@throttle = 0
|
@throttle = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -115,12 +124,6 @@ class Browser
|
|||||||
#
|
#
|
||||||
# @return [ Hash ]
|
# @return [ Hash ]
|
||||||
def merge_request_params(params = {})
|
def merge_request_params(params = {})
|
||||||
params = Browser.append_params_header_field(
|
|
||||||
params,
|
|
||||||
'User-Agent',
|
|
||||||
@user_agent
|
|
||||||
)
|
|
||||||
|
|
||||||
if @proxy
|
if @proxy
|
||||||
params.merge!(proxy: @proxy)
|
params.merge!(proxy: @proxy)
|
||||||
params.merge!(proxyauth: @proxy_auth) if @proxy_auth
|
params.merge!(proxyauth: @proxy_auth) if @proxy_auth
|
||||||
@@ -143,8 +146,8 @@ class Browser
|
|||||||
end
|
end
|
||||||
|
|
||||||
params.merge!(referer: referer)
|
params.merge!(referer: referer)
|
||||||
params.merge!(timeout: @request_timeout) if @request_timeout
|
params.merge!(timeout: @request_timeout) if @request_timeout && !params.key?(:timeout)
|
||||||
params.merge!(connecttimeout: @connect_timeout) if @connect_timeout
|
params.merge!(connecttimeout: @connect_timeout) if @connect_timeout && !params.key?(:connecttimeout)
|
||||||
|
|
||||||
# Used to enable the cache system if :cache_ttl > 0
|
# Used to enable the cache system if :cache_ttl > 0
|
||||||
params.merge!(cache_ttl: @cache_ttl) unless params.key?(:cache_ttl)
|
params.merge!(cache_ttl: @cache_ttl) unless params.key?(:cache_ttl)
|
||||||
@@ -153,12 +156,18 @@ class Browser
|
|||||||
params.merge!(maxredirs: 3) unless params.key?(:maxredirs)
|
params.merge!(maxredirs: 3) unless params.key?(:maxredirs)
|
||||||
|
|
||||||
# Disable SSL-Certificate checks
|
# Disable SSL-Certificate checks
|
||||||
params.merge!(ssl_verifypeer: false)
|
if @disable_tls_checks
|
||||||
params.merge!(ssl_verifyhost: 0)
|
# 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!(cookiejar: @cache_dir + '/cookie-jar')
|
||||||
params.merge!(cookiefile: @cache_dir + '/cookie-jar')
|
params.merge!(cookiefile: @cache_dir + '/cookie-jar')
|
||||||
params.merge!(cookie: @cookie) if @cookie
|
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
|
params
|
||||||
end
|
end
|
||||||
@@ -178,4 +187,18 @@ class Browser
|
|||||||
end
|
end
|
||||||
params
|
params
|
||||||
end
|
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
|
end
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
class Browser
|
class Browser
|
||||||
module Options
|
module Options
|
||||||
|
|
||||||
attr_accessor :cache_ttl, :request_timeout, :connect_timeout
|
attr_accessor :request_timeout, :connect_timeout, :user_agent, :disable_accept_header, :disable_referer, :disable_tls_checks
|
||||||
attr_reader :basic_auth, :proxy, :proxy_auth, :throttle
|
attr_reader :basic_auth, :cache_ttl, :proxy, :proxy_auth, :throttle
|
||||||
attr_writer :user_agent
|
|
||||||
|
|
||||||
# Sets the Basic Authentification credentials
|
# Sets the Basic Authentification credentials
|
||||||
# Accepted format:
|
# Accepted format:
|
||||||
@@ -25,6 +24,10 @@ class Browser
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cache_ttl=(ttl)
|
||||||
|
@cache_ttl = ttl.to_i
|
||||||
|
end
|
||||||
|
|
||||||
# @return [ Integer ]
|
# @return [ Integer ]
|
||||||
def max_threads
|
def max_threads
|
||||||
@max_threads || 1
|
@max_threads || 1
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ class CacheFileStore
|
|||||||
@storage_path = File.expand_path(File.join(storage_path, storage_dir))
|
@storage_path = File.expand_path(File.join(storage_path, storage_dir))
|
||||||
@serializer = serializer
|
@serializer = serializer
|
||||||
|
|
||||||
# File.directory? for ruby <= 1.9 otherwise,
|
unless Dir.exist?(@storage_path)
|
||||||
# it makes more sense to do Dir.exist? :/
|
|
||||||
unless File.directory?(@storage_path)
|
|
||||||
FileUtils.mkdir_p(@storage_path)
|
FileUtils.mkdir_p(@storage_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -51,7 +49,7 @@ class CacheFileStore
|
|||||||
end
|
end
|
||||||
|
|
||||||
def write_entry(key, data_to_store, cache_ttl)
|
def write_entry(key, data_to_store, cache_ttl)
|
||||||
if cache_ttl > 0
|
if cache_ttl && cache_ttl > 0
|
||||||
File.open(get_entry_file_path(key), 'w') do |f|
|
File.open(get_entry_file_path(key), 'w') do |f|
|
||||||
begin
|
begin
|
||||||
f.write(@serializer.dump(data_to_store))
|
f.write(@serializer.dump(data_to_store))
|
||||||
|
|||||||
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
|
code = tag.text.to_s
|
||||||
next if code.empty?
|
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|
|
code.scan(code_pattern(wp_target)).flatten.uniq.each do |item_name|
|
||||||
names << item_name
|
names << item_name
|
||||||
end
|
end
|
||||||
@@ -116,7 +120,7 @@ class WpItems < Array
|
|||||||
wp_content_dir = wp_target.wp_content_dir
|
wp_content_dir = wp_target.wp_content_dir
|
||||||
wp_content_url = wp_target.uri.merge(wp_content_dir).to_s
|
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
|
content_dir = %r{(?:#{url}|\\?\/\\?\/?#{wp_content_dir})}i
|
||||||
|
|
||||||
%r{#{content_dir}\\?/#{type}\\?/}
|
%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)
|
wp_plugins.add('all-in-one-seo-pack', version: $1)
|
||||||
end
|
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)
|
wp_plugins.add('wordpress-seo', version: $1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if body =~ /<!-- Google Universal Analytics for WordPress v([^\s]+) -/i
|
||||||
|
wp_plugins.add('google-universal-analytics', version: $1)
|
||||||
|
end
|
||||||
|
|
||||||
wp_plugins
|
wp_plugins
|
||||||
end
|
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{
|
%w{
|
||||||
timthumb.php lib/timthumb.php inc/timthumb.php includes/timthumb.php
|
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|
|
}.each do |path|
|
||||||
wp_timthumb.path = "$wp-content$/themes/#{theme_name}/#{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
|
# 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/../"
|
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')
|
DATA_DIR = File.join(ROOT_DIR, 'data')
|
||||||
CONF_DIR = File.join(ROOT_DIR, 'conf')
|
CONF_DIR = File.join(ROOT_DIR, 'conf')
|
||||||
@@ -28,7 +28,9 @@ LOCAL_FILES_XSD = File.join(DATA_DIR, 'local_vulnerable_files.xsd')
|
|||||||
USER_AGENTS_FILE = File.join(DATA_DIR, 'user-agents.txt')
|
USER_AGENTS_FILE = File.join(DATA_DIR, 'user-agents.txt')
|
||||||
LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update')
|
LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update')
|
||||||
|
|
||||||
WPSCAN_VERSION = '2.9'
|
MIN_RUBY_VERSION = '2.1.9'
|
||||||
|
|
||||||
|
WPSCAN_VERSION = '2.9.2'
|
||||||
|
|
||||||
$LOAD_PATH.unshift(LIB_DIR)
|
$LOAD_PATH.unshift(LIB_DIR)
|
||||||
$LOAD_PATH.unshift(WPSCAN_LIB_DIR)
|
$LOAD_PATH.unshift(WPSCAN_LIB_DIR)
|
||||||
@@ -42,6 +44,11 @@ def kali_linux?
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Determins if installed on Windows OS
|
||||||
|
def windows?
|
||||||
|
Gem.win_platform?
|
||||||
|
end
|
||||||
|
|
||||||
require 'environment'
|
require 'environment'
|
||||||
|
|
||||||
def escape_glob(s)
|
def escape_glob(s)
|
||||||
@@ -144,7 +151,7 @@ def banner
|
|||||||
puts '_______________________________________________________________'
|
puts '_______________________________________________________________'
|
||||||
puts ' __ _______ _____ '
|
puts ' __ _______ _____ '
|
||||||
puts ' \\ \\ / / __ \\ / ____| '
|
puts ' \\ \\ / / __ \\ / ____| '
|
||||||
puts ' \\ \\ /\\ / /| |__) | (___ ___ __ _ _ __ '
|
puts ' \\ \\ /\\ / /| |__) | (___ ___ __ _ _ __ ®'
|
||||||
puts ' \\ \\/ \\/ / | ___/ \\___ \\ / __|/ _` | \'_ \\ '
|
puts ' \\ \\/ \\/ / | ___/ \\___ \\ / __|/ _` | \'_ \\ '
|
||||||
puts ' \\ /\\ / | | ____) | (__| (_| | | | |'
|
puts ' \\ /\\ / | | ____) | (__| (_| | | | |'
|
||||||
puts ' \\/ \\/ |_| |_____/ \\___|\\__,_|_| |_|'
|
puts ' \\/ \\/ |_| |_____/ \\___|\\__,_|_| |_|'
|
||||||
@@ -223,7 +230,11 @@ end
|
|||||||
#
|
#
|
||||||
# @return [ Integer ] The number of lines in the given file
|
# @return [ Integer ] The number of lines in the given file
|
||||||
def count_file_lines(file)
|
def count_file_lines(file)
|
||||||
|
if windows?
|
||||||
|
`findstr /R /N "^" #{file.shellescape} | find /C ":"`.split[0].to_i
|
||||||
|
else
|
||||||
`wc -l #{file.shellescape}`.split[0].to_i
|
`wc -l #{file.shellescape}`.split[0].to_i
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Truncates a string to a specific length and adds ... at the end
|
# Truncates a string to a specific length and adds ... at the end
|
||||||
@@ -257,3 +268,7 @@ end
|
|||||||
def directory_listing_enabled?(url)
|
def directory_listing_enabled?(url)
|
||||||
Browser.get(url.to_s).body[%r{<title>Index of}] ? true : false
|
Browser.get(url.to_s).body[%r{<title>Index of}] ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def url_encode(str)
|
||||||
|
CGI.escape(str).gsub("+", "%20")
|
||||||
|
end
|
||||||
|
|||||||
@@ -22,13 +22,15 @@ class DbUpdater
|
|||||||
{
|
{
|
||||||
ssl_verifyhost: 2,
|
ssl_verifyhost: 2,
|
||||||
ssl_verifypeer: true,
|
ssl_verifypeer: true,
|
||||||
accept_encoding: 'gzip, deflate'
|
accept_encoding: 'gzip, deflate',
|
||||||
|
timeout: 300,
|
||||||
|
connecttimeout: 20
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ] The raw file URL associated with the given filename
|
# @return [ String ] The raw file URL associated with the given filename
|
||||||
def remote_file_url(filename)
|
def remote_file_url(filename)
|
||||||
"https://wpvulndb.com/data/#{filename}"
|
"https://data.wpscan.org/#{filename}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ] The checksum of the associated remote filename
|
# @return [ String ] The checksum of the associated remote filename
|
||||||
@@ -99,7 +101,7 @@ class DbUpdater
|
|||||||
puts " [i] Database File Checksum : #{db_checksum}" if verbose
|
puts " [i] Database File Checksum : #{db_checksum}" if verbose
|
||||||
|
|
||||||
unless dl_checksum == db_checksum
|
unless dl_checksum == db_checksum
|
||||||
fail "#{filename}: checksums do not match"
|
raise ChecksumError.new(File.read(local_file_path(filename))), "#{filename}: checksums do not match (local: #{dl_checksum} remote: #{db_checksum})"
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
puts ' [i] Restoring Backup due to error' if verbose
|
puts ' [i] Restoring Backup due to error' if verbose
|
||||||
|
|||||||
@@ -31,3 +31,11 @@ class DownloadError < HttpError
|
|||||||
"Unable to get #{failure_details}"
|
"Unable to get #{failure_details}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ChecksumError < StandardError
|
||||||
|
attr_reader :file
|
||||||
|
|
||||||
|
def initialize(file)
|
||||||
|
@file = file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,35 +1,5 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
# Since ruby 1.9.2, URI::escape is obsolete
|
|
||||||
# See http://rosettacode.org/wiki/URL_encoding#Ruby and http://www.ruby-forum.com/topic/207489
|
|
||||||
if RUBY_VERSION >= '1.9.2'
|
|
||||||
module URI
|
|
||||||
extend self
|
|
||||||
|
|
||||||
def escape(str)
|
|
||||||
URI::Parser.new.escape(str)
|
|
||||||
end
|
|
||||||
alias :encode :escape
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if RUBY_VERSION < '1.9'
|
|
||||||
class Array
|
|
||||||
# Fix for grep with symbols in ruby <= 1.8.7
|
|
||||||
def _grep_(regexp)
|
|
||||||
matches = []
|
|
||||||
self.each do |value|
|
|
||||||
value = value.to_s
|
|
||||||
matches << value if value.match(regexp)
|
|
||||||
end
|
|
||||||
matches
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :grep, :_grep_
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# This is used in WpItem::Existable
|
# This is used in WpItem::Existable
|
||||||
module Typhoeus
|
module Typhoeus
|
||||||
class Response
|
class Response
|
||||||
@@ -57,52 +27,11 @@ def puts(o = '')
|
|||||||
super(o)
|
super(o)
|
||||||
end
|
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
|
class Numeric
|
||||||
def bytes_to_human
|
def bytes_to_human
|
||||||
units = %w{B KB MB GB TB}
|
units = %w{B KB MB GB TB}
|
||||||
e = (Math.log(self)/Math.log(1024)).floor
|
e = (Math.log(abs)/Math.log(1024)).floor
|
||||||
s = '%.3f' % (to_f / 1024**e)
|
s = '%.3f' % (abs.to_f / 1024**e)
|
||||||
s.sub(/\.?0*$/, ' ' + units[e])
|
s.sub(/\.?0*$/, ' ' + units[e])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
0
lib/common/models/vulnerability.rb
Executable file → Normal file
0
lib/common/models/vulnerability.rb
Executable file → Normal file
4
lib/common/models/wp_item.rb
Executable file → Normal file
4
lib/common/models/wp_item.rb
Executable file → Normal file
@@ -100,9 +100,7 @@ class WpItem
|
|||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def path=(path)
|
def path=(path)
|
||||||
@path = URI.encode(
|
@path = path.gsub(/\$wp-plugins\$/i, wp_plugins_dir).gsub(/\$wp-content\$/i, wp_content_dir)
|
||||||
path.gsub(/\$wp-plugins\$/i, wp_plugins_dir).gsub(/\$wp-content\$/i, wp_content_dir)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [ WpItem ] other
|
# @param [ WpItem ] other
|
||||||
|
|||||||
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 ]
|
# @return [ void ]
|
||||||
def found_from=(method)
|
def found_from=(method)
|
||||||
found = method[%r{find_from_(.*)}, 1]
|
@found_from = method.to_s.gsub(/find_from_/, '').gsub(/_/, ' ')
|
||||||
@found_from = found.gsub('_', ' ') if found
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Findable
|
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
2
lib/common/models/wp_plugin.rb
Executable file → Normal file
2
lib/common/models/wp_plugin.rb
Executable file → Normal file
@@ -7,7 +7,7 @@ class WpPlugin < WpItem
|
|||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def forge_uri(target_base_uri)
|
def forge_uri(target_base_uri)
|
||||||
@uri = target_base_uri.merge(URI.encode(wp_plugins_dir + '/' + name + '/'))
|
@uri = target_base_uri.merge("#{wp_plugins_dir}/#{url_encode(name)}/")
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_file
|
def db_file
|
||||||
|
|||||||
2
lib/common/models/wp_theme.rb
Executable file → Normal file
2
lib/common/models/wp_theme.rb
Executable file → Normal file
@@ -23,7 +23,7 @@ class WpTheme < WpItem
|
|||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def forge_uri(target_base_uri)
|
def forge_uri(target_base_uri)
|
||||||
@uri = target_base_uri.merge(URI.encode(wp_content_dir + '/themes/' + name + '/'))
|
@uri = target_base_uri.merge("#{wp_content_dir}/themes/#{url_encode(name)}/")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ] The url to the theme stylesheet
|
# @return [ String ] The url to the theme stylesheet
|
||||||
|
|||||||
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)
|
def find(target_uri)
|
||||||
methods.grep(/^find_from_/).each do |method|
|
methods.grep(/^find_from_/).each do |method|
|
||||||
if wp_theme = self.send(method, target_uri)
|
if wp_theme = self.send(method, target_uri)
|
||||||
wp_theme.found_from = method
|
wp_theme.found_from = method.to_s
|
||||||
|
|
||||||
return wp_theme
|
return wp_theme
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class WpTheme
|
|||||||
puts " | Referenced style.css: #{referenced_url}" if referenced_url && referenced_url != style_url
|
puts " | Referenced style.css: #{referenced_url}" if referenced_url && referenced_url != style_url
|
||||||
puts " | Theme Name: #{@theme_name}" if @theme_name
|
puts " | Theme Name: #{@theme_name}" if @theme_name
|
||||||
puts " | Theme URI: #{@theme_uri}" if @theme_uri
|
puts " | Theme URI: #{@theme_uri}" if @theme_uri
|
||||||
puts " | Description: #{theme_desc}"
|
puts " | Description: #{theme_desc}" if theme_desc
|
||||||
puts " | Author: #{@theme_author}" if @theme_author
|
puts " | Author: #{@theme_author}" if @theme_author
|
||||||
puts " | Author URI: #{@theme_author_uri}" if @theme_author_uri
|
puts " | Author URI: #{@theme_author_uri}" if @theme_author_uri
|
||||||
puts " | Template: #{@theme_template}" if @theme_template and verbose
|
puts " | Template: #{@theme_template}" if @theme_template and verbose
|
||||||
|
|||||||
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
@@ -3,6 +3,8 @@
|
|||||||
class WpUser < WpItem
|
class WpUser < WpItem
|
||||||
module BruteForcable
|
module BruteForcable
|
||||||
|
|
||||||
|
attr_reader :progress_bar
|
||||||
|
|
||||||
# Brute force the user with the wordlist supplied
|
# Brute force the user with the wordlist supplied
|
||||||
#
|
#
|
||||||
# It can take a long time to queue 2 million requests,
|
# It can take a long time to queue 2 million requests,
|
||||||
@@ -25,7 +27,8 @@ class WpUser < WpItem
|
|||||||
hydra = browser.hydra
|
hydra = browser.hydra
|
||||||
queue_count = 0
|
queue_count = 0
|
||||||
found = false
|
found = false
|
||||||
progress_bar = self.progress_bar(count_file_lines(wordlist)+1, options)
|
|
||||||
|
create_progress_bar(count_file_lines(wordlist)+1, options)
|
||||||
|
|
||||||
File.open(wordlist).each do |password|
|
File.open(wordlist).each do |password|
|
||||||
password.chomp!
|
password.chomp!
|
||||||
@@ -42,7 +45,7 @@ class WpUser < WpItem
|
|||||||
request.on_complete do |response|
|
request.on_complete do |response|
|
||||||
progress_bar.progress += 1 if options[:show_progression] && !found
|
progress_bar.progress += 1 if options[:show_progression] && !found
|
||||||
|
|
||||||
puts "\n Trying Username : #{login} Password : #{password}" if options[:verbose]
|
progress_bar.log(" Trying Username: #{login} Password: #{password}") if options[:verbose]
|
||||||
|
|
||||||
if valid_password?(response, password, redirect_url, options)
|
if valid_password?(response, password, redirect_url, options)
|
||||||
found = true
|
found = true
|
||||||
@@ -57,7 +60,7 @@ class WpUser < WpItem
|
|||||||
if queue_count >= browser.max_threads
|
if queue_count >= browser.max_threads
|
||||||
hydra.run
|
hydra.run
|
||||||
queue_count = 0
|
queue_count = 0
|
||||||
puts "Sent #{browser.max_threads} requests ..." if options[:verbose]
|
progress_bar.log(" Sent #{browser.max_threads} request/s ...") if options[:verbose]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -71,9 +74,9 @@ class WpUser < WpItem
|
|||||||
#
|
#
|
||||||
# @return [ ProgressBar ]
|
# @return [ ProgressBar ]
|
||||||
# :nocov:
|
# :nocov:
|
||||||
def progress_bar(passwords_size, options)
|
def create_progress_bar(passwords_size, options)
|
||||||
if options[:show_progression]
|
if options[:show_progression]
|
||||||
ProgressBar.create(
|
@progress_bar = ProgressBar.create(
|
||||||
format: '%t %a <%B> (%c / %C) %P%% %e',
|
format: '%t %a <%B> (%c / %C) %P%% %e',
|
||||||
title: " Brute Forcing '#{login}'",
|
title: " Brute Forcing '#{login}'",
|
||||||
total: passwords_size
|
total: passwords_size
|
||||||
@@ -107,20 +110,20 @@ class WpUser < WpItem
|
|||||||
progression = "#{info('[SUCCESS]')} Login : #{login} Password : #{password}\n\n"
|
progression = "#{info('[SUCCESS]')} Login : #{login} Password : #{password}\n\n"
|
||||||
valid = true
|
valid = true
|
||||||
elsif response.body =~ /login_error/i
|
elsif response.body =~ /login_error/i
|
||||||
verbose = "\n Incorrect login and/or password."
|
verbose = "Incorrect login and/or password."
|
||||||
elsif response.timed_out?
|
elsif response.timed_out?
|
||||||
progression = critical('ERROR: Request timed out.')
|
progression = critical('ERROR: Request timed out.')
|
||||||
elsif response.code == 0
|
elsif response.code == 0
|
||||||
progression = critical("ERROR: No response from remote server. WAF/IPS? (#{response.return_message})")
|
progression = critical("ERROR: No response from remote server. WAF/IPS? (#{response.return_message})")
|
||||||
elsif response.code.to_s =~ /^50/
|
elsif response.code.to_s =~ /^50/
|
||||||
progression = critical('ERROR: Server error, try reducing the number of threads.')
|
progression = critical('ERROR: Server error, try reducing the number of threads or use the --throttle option.')
|
||||||
else
|
else
|
||||||
progression = critical("ERROR: We received an unknown response for #{password}...")
|
progression = critical("ERROR: We received an unknown response for #{password}...")
|
||||||
verbose = critical(" Code: #{response.code}\n Body: #{response.body}\n")
|
verbose = critical(" Code: #{response.code}\n Body: #{response.body}\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "\n " + progression if progression && options[:show_progression]
|
progress_bar.log(" #{progression}") if progression && options[:show_progression]
|
||||||
puts verbose if verbose && options[:verbose]
|
progress_bar.log(" #{verbose}") if verbose && options[:verbose]
|
||||||
|
|
||||||
valid || false
|
valid || false
|
||||||
end
|
end
|
||||||
|
|||||||
0
lib/common/models/wp_user/existable.rb
Executable file → Normal file
0
lib/common/models/wp_user/existable.rb
Executable file → Normal file
15
lib/common/models/wp_version.rb
Executable file → Normal file
15
lib/common/models/wp_version.rb
Executable file → Normal file
@@ -8,7 +8,7 @@ class WpVersion < WpItem
|
|||||||
include WpVersion::Output
|
include WpVersion::Output
|
||||||
|
|
||||||
# The version number
|
# The version number
|
||||||
attr_accessor :number
|
attr_accessor :number, :metadata
|
||||||
alias_method :version, :number # Needed to have the right behaviour in Vulnerable#vulnerable_to?
|
alias_method :version, :number # Needed to have the right behaviour in Vulnerable#vulnerable_to?
|
||||||
|
|
||||||
# @return [ Array ]
|
# @return [ Array ]
|
||||||
@@ -35,4 +35,17 @@ class WpVersion < WpItem
|
|||||||
a << node.text.to_s
|
a << node.text.to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [ Hash ] Metadata for specific WP version from WORDPRESSES_FILE
|
||||||
|
def metadata(version)
|
||||||
|
json = json(db_file)
|
||||||
|
|
||||||
|
metadata = {}
|
||||||
|
temp = json[version]
|
||||||
|
if !temp.nil?
|
||||||
|
metadata[:release_date] = temp['release_date']
|
||||||
|
metadata[:changelog_url] = temp['changelog_url']
|
||||||
|
end
|
||||||
|
metadata
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
77
lib/common/models/wp_version/findable.rb
Executable file → Normal file
77
lib/common/models/wp_version/findable.rb
Executable file → Normal file
@@ -12,6 +12,7 @@ class WpVersion < WpItem
|
|||||||
#
|
#
|
||||||
# @return [ WpVersion ]
|
# @return [ WpVersion ]
|
||||||
def find(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
|
def find(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
|
||||||
|
versions = {}
|
||||||
methods.grep(/^find_from_/).each do |method|
|
methods.grep(/^find_from_/).each do |method|
|
||||||
|
|
||||||
if method === :find_from_advanced_fingerprinting
|
if method === :find_from_advanced_fingerprinting
|
||||||
@@ -21,9 +22,21 @@ class WpVersion < WpItem
|
|||||||
end
|
end
|
||||||
|
|
||||||
if version
|
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
|
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
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -114,34 +127,6 @@ class WpVersion < WpItem
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_from_stylesheets_numbers(target_uri)
|
|
||||||
wp_versions = WpVersion.all
|
|
||||||
found = {}
|
|
||||||
pattern = /\bver=([0-9\.]+)/i
|
|
||||||
|
|
||||||
Nokogiri::HTML(Browser.get(target_uri.to_s).body).css('link,script').each do |tag|
|
|
||||||
%w(href src).each do |attribute|
|
|
||||||
attr_value = tag.attribute(attribute).to_s
|
|
||||||
|
|
||||||
next if attr_value.nil? || attr_value.empty?
|
|
||||||
|
|
||||||
uri = Addressable::URI.parse(attr_value)
|
|
||||||
next unless uri.query && uri.query.match(pattern)
|
|
||||||
|
|
||||||
version = Regexp.last_match[1].to_s
|
|
||||||
|
|
||||||
found[version] ||= 0
|
|
||||||
found[version] += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
found.delete_if { |v, _| !wp_versions.include?(v) }
|
|
||||||
|
|
||||||
best_guess = found.sort_by(&:last).last
|
|
||||||
# best_guess[0]: version number, [1] numbers of occurences
|
|
||||||
best_guess && best_guess[1] > 1 ? best_guess[0] : nil
|
|
||||||
end
|
|
||||||
|
|
||||||
# Uses data/wp_versions.xml to try to identify a
|
# Uses data/wp_versions.xml to try to identify a
|
||||||
# wordpress version.
|
# wordpress version.
|
||||||
#
|
#
|
||||||
@@ -158,8 +143,6 @@ class WpVersion < WpItem
|
|||||||
def find_from_advanced_fingerprinting(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
|
def find_from_advanced_fingerprinting(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
|
||||||
xml = xml(versions_xml)
|
xml = xml(versions_xml)
|
||||||
|
|
||||||
# This wp_item will take care of encoding the path
|
|
||||||
# and replace variables like $wp-content$ & $wp-plugins$
|
|
||||||
wp_item = WpItem.new(target_uri,
|
wp_item = WpItem.new(target_uri,
|
||||||
wp_content_dir: wp_content_dir,
|
wp_content_dir: wp_content_dir,
|
||||||
wp_plugins_dir: wp_plugins_dir)
|
wp_plugins_dir: wp_plugins_dir)
|
||||||
@@ -218,5 +201,37 @@ class WpVersion < WpItem
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_from_stylesheets_numbers(target_uri)
|
||||||
|
wp_versions = WpVersion.all
|
||||||
|
found = {}
|
||||||
|
pattern = /\bver=([0-9\.]+)/i
|
||||||
|
|
||||||
|
Nokogiri::HTML(Browser.get(target_uri.to_s).body).css('link,script').each do |tag|
|
||||||
|
%w(href src).each do |attribute|
|
||||||
|
attr_value = tag.attribute(attribute).to_s
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
found[version] ||= 0
|
||||||
|
found[version] += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
found.delete_if { |v, _| !wp_versions.include?(v) }
|
||||||
|
|
||||||
|
best_guess = found.sort_by(&:last).last
|
||||||
|
# best_guess[0]: version number, [1] numbers of occurences
|
||||||
|
best_guess && best_guess[1] > 1 ? best_guess[0] : nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,8 +4,16 @@ class WpVersion < WpItem
|
|||||||
module Output
|
module Output
|
||||||
|
|
||||||
def output(verbose = false)
|
def output(verbose = false)
|
||||||
|
metadata = self.metadata(self.number)
|
||||||
|
|
||||||
puts
|
puts
|
||||||
|
if verbose
|
||||||
puts info("WordPress version #{self.number} identified from #{self.found_from}")
|
puts info("WordPress version #{self.number} identified from #{self.found_from}")
|
||||||
|
puts " | Released: #{metadata[:release_date]}"
|
||||||
|
puts " | Changelog: #{metadata[:changelog_url]}"
|
||||||
|
else
|
||||||
|
puts info("WordPress version #{self.number} #{"(Released on #{metadata[:release_date]}) identified from #{self.found_from}" if metadata[:release_date]}")
|
||||||
|
end
|
||||||
|
|
||||||
vulnerabilities = self.vulnerabilities
|
vulnerabilities = self.vulnerabilities
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
|
||||||
version = RUBY_VERSION.dup
|
version = RUBY_VERSION.dup
|
||||||
if Gem::Version.create(version) < Gem::Version.create(1.9)
|
|
||||||
puts "Ruby >= 1.9 required to run wpscan (You have #{version})"
|
if Gem::Version.create(version) < Gem::Version.create(MIN_RUBY_VERSION)
|
||||||
|
puts "Ruby >= #{MIN_RUBY_VERSION} required to run wpscan (You have #{version})"
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ begin
|
|||||||
require 'shellwords'
|
require 'shellwords'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
require 'cgi'
|
||||||
# Third party libs
|
# Third party libs
|
||||||
require 'typhoeus'
|
require 'typhoeus'
|
||||||
require 'yajl/json_gem'
|
require 'yajl/json_gem'
|
||||||
|
|||||||
@@ -21,6 +21,29 @@ class WebSite
|
|||||||
@uri.to_s
|
@uri.to_s
|
||||||
end
|
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.
|
# Checks if the remote website is up.
|
||||||
def online?
|
def online?
|
||||||
Browser.get(@uri.to_s).code != 0
|
Browser.get(@uri.to_s).code != 0
|
||||||
@@ -68,15 +91,18 @@ class WebSite
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Compute the MD5 of the page
|
# 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
|
# @param [ String, Typhoeus::Response ] page The url of the response of the page
|
||||||
#
|
#
|
||||||
# @return [ String ] The MD5 hash of the page
|
# @return [ String ] The MD5 hash of the page
|
||||||
def self.page_hash(page)
|
def self.page_hash(page)
|
||||||
page = Browser.get(page, { followlocation: true, cache_ttl: 0 }) unless page.is_a?(Typhoeus::Response)
|
page = Browser.get(page, { followlocation: true, cache_ttl: 0 }) unless page.is_a?(Typhoeus::Response)
|
||||||
|
# remove comments
|
||||||
Digest::MD5.hexdigest(page.body.gsub(/<!--.*?-->/m, ''))
|
page = page.body.gsub(/<!--.*?-->/m, '')
|
||||||
|
# remove javascript stuff
|
||||||
|
page = page.gsub(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/m, '')
|
||||||
|
Digest::MD5.hexdigest(page)
|
||||||
end
|
end
|
||||||
|
|
||||||
def homepage_hash
|
def homepage_hash
|
||||||
|
|||||||
@@ -135,6 +135,11 @@ class WpTarget < WebSite
|
|||||||
@uri.merge("#{wp_content_dir}/uploads/").to_s
|
@uri.merge("#{wp_content_dir}/uploads/").to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [ String ]
|
||||||
|
def includes_dir_url
|
||||||
|
@uri.merge("wp-includes/").to_s
|
||||||
|
end
|
||||||
|
|
||||||
# Script for replacing strings in wordpress databases
|
# Script for replacing strings in wordpress databases
|
||||||
# reveals database credentials after hitting submit
|
# reveals database credentials after hitting submit
|
||||||
# http://interconnectit.com/124/search-and-replace-for-wordpress-databases/
|
# http://interconnectit.com/124/search-and-replace-for-wordpress-databases/
|
||||||
@@ -153,4 +158,8 @@ class WpTarget < WebSite
|
|||||||
def upload_directory_listing_enabled?
|
def upload_directory_listing_enabled?
|
||||||
directory_listing_enabled?(upload_dir_url)
|
directory_listing_enabled?(upload_dir_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def include_directory_listing_enabled?
|
||||||
|
directory_listing_enabled?(includes_dir_url)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class WpTarget < WebSite
|
|||||||
queue_count = 0
|
queue_count = 0
|
||||||
|
|
||||||
backups.each do |file|
|
backups.each do |file|
|
||||||
file_url = @uri.merge(URI.escape(file)).to_s
|
file_url = @uri.merge(url_encode(file)).to_s
|
||||||
request = browser.forge_request(file_url)
|
request = browser.forge_request(file_url)
|
||||||
|
|
||||||
request.on_complete do |response|
|
request.on_complete do |response|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# encoding: UTF-8
|
# 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')
|
require_files_from_directory(WPSCAN_LIB_DIR, '**/*.rb')
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ def help
|
|||||||
puts
|
puts
|
||||||
puts 'Some values are settable in a config file, see the example.conf.json'
|
puts 'Some values are settable in a config file, see the example.conf.json'
|
||||||
puts
|
puts
|
||||||
puts '--update Update to the database to the latest version.'
|
puts '--update Update the database to the latest version.'
|
||||||
puts '--url | -u <target url> The WordPress URL/domain to scan.'
|
puts '--url | -u <target url> The WordPress URL/domain to scan.'
|
||||||
puts '--force | -f Forces WPScan to not check if the remote site is running WordPress.'
|
puts '--force | -f Forces WPScan to not check if the remote site is running WordPress.'
|
||||||
puts '--enumerate | -e [option(s)] Enumeration.'
|
puts '--enumerate | -e [option(s)] Enumeration.'
|
||||||
@@ -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 ' 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 '--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 '--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 '--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 '--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 '--batch Never ask for user input, use the default behaviour.'
|
||||||
puts '--no-color Do not use colors in the output.'
|
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 ' Subdirectories are allowed.'
|
||||||
puts '--wp-plugins-dir <wp plugins dir> Same thing than --wp-content-dir but for the plugins directory.'
|
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'
|
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 '--wordlist | -w <wordlist> Supply a wordlist for the password brute forcer.'
|
||||||
puts '--username | -U <username> Only brute force the supplied username.'
|
puts '--username | -U <username> Only brute force the supplied username.'
|
||||||
puts '--usernames <path-to-file> Only brute force the usernames from the file.'
|
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 '--cache-ttl <cache-ttl> Typhoeus cache TTL.'
|
||||||
puts '--request-timeout <request-timeout> Request Timeout.'
|
puts '--request-timeout <request-timeout> Request Timeout.'
|
||||||
puts '--connect-timeout <connect-timeout> Connect 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 '--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 '--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.'
|
puts '--help | -h This help screen.'
|
||||||
|
|||||||
@@ -43,7 +43,11 @@ class WpscanOptions
|
|||||||
:connect_timeout,
|
:connect_timeout,
|
||||||
:max_threads,
|
:max_threads,
|
||||||
:no_banner,
|
:no_banner,
|
||||||
:throttle
|
:throttle,
|
||||||
|
:disable_accept_header,
|
||||||
|
:disable_referer,
|
||||||
|
:cache_dir,
|
||||||
|
:disable_tls_checks
|
||||||
]
|
]
|
||||||
|
|
||||||
attr_accessor *ACCESSOR_OPTIONS
|
attr_accessor *ACCESSOR_OPTIONS
|
||||||
@@ -208,7 +212,9 @@ class WpscanOptions
|
|||||||
|
|
||||||
enumerate_options_from_string(cli_value)
|
enumerate_options_from_string(cli_value)
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -282,7 +288,11 @@ class WpscanOptions
|
|||||||
['--cookie', GetoptLong::REQUIRED_ARGUMENT],
|
['--cookie', GetoptLong::REQUIRED_ARGUMENT],
|
||||||
['--log', GetoptLong::NO_ARGUMENT],
|
['--log', GetoptLong::NO_ARGUMENT],
|
||||||
['--no-banner', 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
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -124,11 +124,10 @@ describe Browser do
|
|||||||
describe '#merge_request_params' do
|
describe '#merge_request_params' do
|
||||||
let(:params) { {} }
|
let(:params) { {} }
|
||||||
let(:cookie_jar) { CACHE_DIR + '/browser/cookie-jar' }
|
let(:cookie_jar) { CACHE_DIR + '/browser/cookie-jar' }
|
||||||
|
let(:user_agent) { 'SomeUA' }
|
||||||
let(:default_expectation) {
|
let(:default_expectation) {
|
||||||
{
|
{
|
||||||
cache_ttl: 250,
|
cache_ttl: 250,
|
||||||
headers: { 'User-Agent' => 'SomeUA' },
|
|
||||||
ssl_verifypeer: false, ssl_verifyhost: 0,
|
|
||||||
cookiejar: cookie_jar, cookiefile: cookie_jar,
|
cookiejar: cookie_jar, cookiefile: cookie_jar,
|
||||||
timeout: 60, connecttimeout: 10,
|
timeout: 60, connecttimeout: 10,
|
||||||
maxredirs: 3,
|
maxredirs: 3,
|
||||||
@@ -137,16 +136,25 @@ describe Browser do
|
|||||||
}
|
}
|
||||||
|
|
||||||
after :each do
|
after :each do
|
||||||
browser.user_agent = 'SomeUA'
|
browser.user_agent = user_agent
|
||||||
browser.cache_ttl = 250
|
browser.cache_ttl = 250
|
||||||
|
|
||||||
expect(browser.merge_request_params(params)).to eq @expected
|
expect(browser.merge_request_params(params)).to eq @expected
|
||||||
|
expect(Typhoeus::Config.user_agent).to eq user_agent
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the User-Agent header field and cache_ttl' do
|
it 'sets the User-Agent header field and cache_ttl' do
|
||||||
@expected = default_expectation
|
@expected = default_expectation
|
||||||
end
|
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
|
context 'when @proxy' do
|
||||||
let(:proxy) { '127.0.0.1:9050' }
|
let(:proxy) { '127.0.0.1:9050' }
|
||||||
let(:proxy_expectation) { default_expectation.merge(proxy: proxy) }
|
let(:proxy_expectation) { default_expectation.merge(proxy: proxy) }
|
||||||
@@ -177,7 +185,7 @@ describe Browser do
|
|||||||
it 'appends the basic_auth' do
|
it 'appends the basic_auth' do
|
||||||
browser.basic_auth = 'user:pass'
|
browser.basic_auth = 'user:pass'
|
||||||
@expected = default_expectation.merge(
|
@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
|
||||||
end
|
end
|
||||||
@@ -206,6 +214,13 @@ describe Browser do
|
|||||||
@expected = default_expectation.merge(cookie: cookie)
|
@expected = default_expectation.merge(cookie: cookie)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
describe '#forge_request' do
|
describe '#forge_request' do
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ describe WpItems do
|
|||||||
vulnerable_targets_items: [ WpItem.new(uri, name: 'mr-smith'),
|
vulnerable_targets_items: [ WpItem.new(uri, name: 'mr-smith'),
|
||||||
WpItem.new(uri, name: 'neo')],
|
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
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -100,6 +100,13 @@ describe 'WpPlugins::Detectable' do
|
|||||||
expected.add('all-in-one-seo-pack', version: '2.0.3.1')
|
expected.add('all-in-one-seo-pack', version: '2.0.3.1')
|
||||||
end
|
end
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ describe 'WpTimthumbs::Detectable' do
|
|||||||
|
|
||||||
def expected_targets_from_theme(theme_name)
|
def expected_targets_from_theme(theme_name)
|
||||||
expected = []
|
expected = []
|
||||||
%w{
|
%w(
|
||||||
timthumb.php lib/timthumb.php inc/timthumb.php includes/timthumb.php
|
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|
|
).each do |file|
|
||||||
path = "$wp-content$/themes/#{theme_name}/#{file}"
|
path = "$wp-content$/themes/#{theme_name}/#{file}"
|
||||||
expected << WpTimthumb.new(uri, path: path)
|
expected << WpTimthumb.new(uri, path: path)
|
||||||
end
|
end
|
||||||
@@ -46,7 +46,7 @@ describe 'WpTimthumbs::Detectable' do
|
|||||||
after do
|
after do
|
||||||
targets = subject.send(:targets_items_from_file, file, wp_target)
|
targets = subject.send(:targets_items_from_file, file, wp_target)
|
||||||
|
|
||||||
expect(targets.map { |t| t.url }).to eq @expected.map { |t| t.url }
|
expect(targets.map(&:url)).to eq @expected.map(&:url)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when an empty file' do
|
context 'when an empty file' do
|
||||||
@@ -71,7 +71,7 @@ describe 'WpTimthumbs::Detectable' do
|
|||||||
theme = 'hello-world'
|
theme = 'hello-world'
|
||||||
targets = subject.send(:theme_timthumbs, theme, wp_target)
|
targets = subject.send(:theme_timthumbs, theme, wp_target)
|
||||||
|
|
||||||
expect(targets.map { |t| t.url }).to eq expected_targets_from_theme(theme).map { |t| t.url }
|
expect(targets.map(&:url)).to eq expected_targets_from_theme(theme).map(&:url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ describe 'WpTimthumbs::Detectable' do
|
|||||||
after do
|
after do
|
||||||
targets = subject.send(:targets_items, wp_target, options)
|
targets = subject.send(:targets_items, wp_target, options)
|
||||||
|
|
||||||
expect(targets.map { |t| t.url }).to eq @expected.sort.map { |t| t.url }
|
expect(targets.map(&:url)).to match_array(@expected.map(&:url))
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when no :theme_name' do
|
context 'when no :theme_name' do
|
||||||
@@ -101,7 +101,7 @@ describe 'WpTimthumbs::Detectable' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context 'when :theme_name' do
|
context 'when :theme_name' do
|
||||||
let(:theme) { 'theme-name'}
|
let(:theme) { 'theme-name' }
|
||||||
|
|
||||||
context 'when no :file' do
|
context 'when no :file' do
|
||||||
let(:options) { { theme_name: theme } }
|
let(:options) { { theme_name: theme } }
|
||||||
|
|||||||
@@ -105,11 +105,6 @@ describe WpItem do
|
|||||||
@expected = 'plugins/readme.txt'
|
@expected = 'plugins/readme.txt'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'also encodes chars' do
|
|
||||||
@path = 'some dir with spaces'
|
|
||||||
@expected = 'some%20dir%20with%20spaces'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#uri' do
|
describe '#uri' do
|
||||||
|
|||||||
@@ -159,6 +159,22 @@ describe 'WpVersion::Findable' do
|
|||||||
end
|
end
|
||||||
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
|
describe '::find' do
|
||||||
# Stub all WpVersion::find_from_* to return nil
|
# Stub all WpVersion::find_from_* to return nil
|
||||||
def stub_all_to_nil
|
def stub_all_to_nil
|
||||||
|
|||||||
@@ -160,6 +160,11 @@ describe 'VersionCompare' do
|
|||||||
@version1 = '.47'
|
@version1 = '.47'
|
||||||
@version2 = '.50.3'
|
@version2 = '.50.3'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'returns true' do
|
||||||
|
@version1 = '2.5.9'
|
||||||
|
@version2 = '2.5.10'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'version checked is older' do
|
context 'version checked is older' do
|
||||||
|
|||||||
@@ -176,6 +176,17 @@ describe 'WebSite' do
|
|||||||
@expected = "yolo\n\n\nworld!"
|
@expected = "yolo\n\n\nworld!"
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
describe '#homepage_hash' do
|
describe '#homepage_hash' do
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
|
require File.expand_path(File.join(__dir__, 'wpscan_helper'))
|
||||||
|
|
||||||
describe WpTarget do
|
describe WpTarget do
|
||||||
subject(:wp_target) { WpTarget.new(target_url, options) }
|
subject(:wp_target) { WpTarget.new(target_url, options) }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
|
require File.expand_path(File.join(__dir__, 'wpscan_helper'))
|
||||||
|
|
||||||
describe 'WpscanOptions' do
|
describe 'WpscanOptions' do
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
<script type='text/javascript' src='//wp-content/items/detect-me-5/main.js'></script>
|
<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">
|
<style type="text/css">
|
||||||
#fancybox-loading.fancybox-ie div {
|
#fancybox-loading.fancybox-ie div {
|
||||||
background: transparent;
|
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-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-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(//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>
|
</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
|
subject.found_from = @method
|
||||||
expect(subject.found_from).to eq @expected
|
expect(subject.found_from).to eq @expected
|
||||||
end
|
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
|
it 'replaces _ by space' do
|
||||||
@method = 'find_from_some_detection_method'
|
@method = 'find_from_some_detection_method'
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ shared_examples 'WpTarget::WpConfigBackup' do
|
|||||||
# set all @config_backup_files to point to a 404
|
# set all @config_backup_files to point to a 404
|
||||||
before :each do
|
before :each do
|
||||||
config_backup_files.each do |backup_file|
|
config_backup_files.each do |backup_file|
|
||||||
file_url = wp_target.uri.merge(URI.escape(backup_file)).to_s
|
file_url = wp_target.uri.merge(url_encode(backup_file)).to_s
|
||||||
|
|
||||||
stub_request(:get, file_url).to_return(status: 404)
|
stub_request(:get, file_url).to_return(status: 404)
|
||||||
end
|
end
|
||||||
@@ -24,7 +24,7 @@ shared_examples 'WpTarget::WpConfigBackup' do
|
|||||||
expected = []
|
expected = []
|
||||||
|
|
||||||
config_backup_files.sample(1).each do |backup_file|
|
config_backup_files.sample(1).each do |backup_file|
|
||||||
file_url = wp_target.uri.merge(URI.escape(backup_file)).to_s
|
file_url = wp_target.uri.merge(url_encode(backup_file)).to_s
|
||||||
expected << file_url
|
expected << file_url
|
||||||
|
|
||||||
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
||||||
@@ -40,7 +40,7 @@ shared_examples 'WpTarget::WpConfigBackup' do
|
|||||||
expected = []
|
expected = []
|
||||||
|
|
||||||
config_backup_files.sample(2).each do |backup_file|
|
config_backup_files.sample(2).each do |backup_file|
|
||||||
file_url = wp_target.uri.merge(URI.escape(backup_file)).to_s
|
file_url = wp_target.uri.merge(url_encode(backup_file)).to_s
|
||||||
expected << file_url
|
expected << file_url
|
||||||
|
|
||||||
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ require 'simplecov' if RUBY_VERSION >= '1.9'
|
|||||||
|
|
||||||
RSpec::Expectations.configuration.warn_about_potential_false_positives = false
|
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_DIR = ROOT_DIR + '/spec'
|
||||||
SPEC_LIB_DIR = SPEC_DIR + '/lib'
|
SPEC_LIB_DIR = SPEC_DIR + '/lib'
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Script based on http://seclists.org/fulldisclosure/2014/Feb/3
|
# 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 = {
|
@opts = {
|
||||||
ids: 1..10,
|
ids: 1..10,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user