Compare commits

..

353 Commits
2.4 ... 2.5

Author SHA1 Message Date
Peter
23420f62df Some files changed for version release 2.5 2014-09-26 11:15:59 +02:00
ethicalhack3r
33149caede Update url 2014-09-26 10:20:38 +02:00
ethicalhack3r
67bec7136b Merge branch 'vdb_intergration'
Conflicts:
	lib/common/models/vulnerability.rb
	spec/lib/common/models/vulnerability_spec.rb
	spec/lib/common/models/wp_item_spec.rb
	spec/lib/common/models/wp_plugin_spec.rb
	spec/lib/common/models/wp_theme_spec.rb
	spec/lib/common/models/wp_version_spec.rb
2014-09-26 10:15:36 +02:00
erwanlr
57a12114dc Updates the data.zip 2014-09-25 17:32:25 +01:00
erwanlr
e32abea46b Adds latest DB files 2014-09-25 13:21:07 +02:00
erwanlr
b12b271a61 Update ruby-progressbar version dependency - Ref #495 2014-09-24 16:20:03 +02:00
Peter
f337cccc68 Update CHANGELOG.md (prepared for release) 2014-09-24 15:22:28 +02:00
Christian Mehlmauer
7f9e178f75 changed some colors 2014-09-22 23:34:42 +02:00
ethicalhack3r
b19696090f Fix for #694 2014-09-21 22:02:30 +02:00
ethicalhack3r
d7488bd402 Fix bug in output 2014-09-21 21:05:49 +02:00
ethicalhack3r
604299a1ac Update VDB url 2014-09-20 10:09:35 +02:00
ethicalhack3r
6800d51347 Undo changes, seem to work with new json ref arrays 2014-09-20 09:32:13 +02:00
ethicalhack3r
7cecd249a8 Update json parsing to reflect new reference arrays 2014-09-20 09:28:48 +02:00
erwanlr
a214ea9341 Adds pathname require statement - Fix #693 2014-09-19 12:33:12 +02:00
ethicalhack3r
884a19b13d Link to new vdb in references output 2014-09-18 10:24:55 +02:00
ethicalhack3r
771f4ae766 Update docs to reflect new updating logic 2014-09-18 09:49:17 +02:00
Peter
9273398c0e Shorter if statement 2014-09-18 00:07:13 +02:00
Peter
a5ed6ad134 Fix if statement 2014-09-17 23:47:54 +02:00
Peter
1bbf575e91 Small code clean 2014-09-17 22:36:39 +02:00
Peter
49582fd841 Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-09-17 18:51:52 +02:00
Peter
bdaf12c1fa Exit program after --update 2014-09-17 18:50:29 +02:00
Peter
ef27c98056 Little output change and coloring 2014-09-17 18:39:58 +02:00
erwanlr
722f3ce384 Adds config file to check - Ref #689 2014-09-17 18:03:25 +02:00
erwanlr
9d084a7b2f Merges the db-update branch 2014-09-17 16:12:12 +02:00
erwanlr
c31a06e255 Removes the source code updaters 2014-09-17 16:01:41 +02:00
erwanlr
ea36c79c26 Adds a missing verbose output 2014-09-13 14:00:59 +02:00
erwanlr
cbe33caeef Removes the ListGenerator plugin from WPStools 2014-09-13 13:57:45 +02:00
erwanlr
8b44354fec Fixes travis failure 2014-09-12 20:47:47 +02:00
erwanlr
619302cd11 Adds the empty data dir 2014-09-12 19:20:44 +02:00
erwanlr
3e94ca11df DB Update: fixes a bug due to .chomp, Adds verbose output 2014-09-12 19:18:56 +02:00
erwanlr
f818778e0a Removes all files from data/ 2014-09-12 18:46:30 +02:00
Peter
280a91f139 Update CHANGELOG 2014-09-12 16:10:16 +02:00
erwanlr
82367a81c9 Deletes the json spec (files to test not longer in the repo) 2014-09-12 12:50:46 +02:00
erwanlr
93b1234d0f Removes useless code 2014-09-12 12:47:55 +02:00
erwanlr
571bc5cf90 Removes the exit used for testing 2014-09-12 12:43:51 +02:00
erwanlr
91de353307 Adds the db update system 2014-09-12 12:43:06 +02:00
Christian Mehlmauer
7ec394a8f2 update data files 2014-09-11 21:03:17 +02:00
Christian Mehlmauer
451c6c07ca new generate method, fix #657 2014-09-11 21:03:16 +02:00
erwanlr
a6b0548426 Potenial fix for 'marshal data too short' error - Ref #685 2014-09-11 20:04:24 +02:00
erwanlr
f89463c4d8 Adds specs for relative URI in Location headers - Ref #686 2014-09-11 19:40:47 +02:00
erwanlr
3be63d85f2 Merge pull request #687 from Soullivaneuh/magic-slash
Re-build redirection url if relative URI
2014-09-11 17:53:06 +01:00
Sullivan SENECHAL
d271b63aa4 Re-build redirection url if begin with slash '/' 2014-09-11 15:35:00 +02:00
erwanlr
fb46fd7101 Removes the vuln.xsd 2014-09-10 17:31:44 +02:00
erwanlr
64513bb9d1 Adds db files 2014-09-10 17:27:06 +02:00
erwanlr
ef56f82de9 Deleting db file 2014-09-10 17:20:15 +02:00
erwanlr
f775379f42 Simulating db update before release 2014-09-10 17:19:35 +02:00
erwanlr
1b377dd674 Testing db stuff 2014-09-10 17:08:12 +02:00
erwanlr
99837127a6 Testing the ignore of db files 2014-09-10 16:57:02 +02:00
erwanlr
f2d205e576 Adds DB update system 2014-09-10 16:31:04 +02:00
ethicalhack3r
bf5bde0e36 Slight changes 2014-09-10 16:27:08 +02:00
ethicalhack3r
18314adce2 Update license #435 2014-09-10 16:23:26 +02:00
erwanlr
d1a7a0ee1f Db Update draft 2014-09-10 12:52:52 +02:00
Christian Mehlmauer
eb73025338 directory listing 2014-09-05 18:27:06 +02:00
Christian Mehlmauer
66cd3e08a0 Detect directory listing in upload folder 2014-09-05 18:25:46 +02:00
Peter
aa8e525681 Prepare CHANGELOG, added stats 2014-09-04 21:47:04 +02:00
erwanlr
7a36f89124 Adds WP 4.0 fingerprints 2014-09-04 20:13:02 +02:00
erwanlr
3e56acab64 Merge pull request #679 from jeffmcjunkin/master
Update README - fix typo in Ubuntu 14.04 instructions
2014-09-02 20:13:38 +01:00
jeffmcjunkin
012670b349 Update README - fix typo in Ubuntu 14.04 instructions
"sudo apt-get install" line had "build-essentials" instead of "build-essential"
2014-09-02 12:05:16 -07:00
erwanlr
44cb13644a Typo, sort of ... 2014-09-02 20:43:37 +02:00
erwanlr
bd8e6db092 Don't try to play with the comments in passive detection, just ignore them 2014-09-02 20:42:17 +02:00
erwanlr
96ae8ade5d Fixes the remove_conditional_comments function 2014-09-02 18:34:01 +02:00
erwanlr
04b1cee71e Factorises a crappy spec - Kudos to @hlissner for this one ;) 2014-09-02 17:12:56 +02:00
Peter
bd07cf859f Prepare CHANGELOG for the new WPScan release 2014-09-02 10:22:54 +02:00
Christian Mehlmauer
e937906647 Be more verbose when no version can be detected 2014-09-01 20:00:59 +02:00
erwanlr
03618f38b5 Improves the Plugins & Themes passive detection, fixes #674 2014-09-01 18:28:09 +02:00
Christian Mehlmauer
94fdddb056 Merge branch 'master' of github.com:wpscanteam/wpscan 2014-08-30 12:18:55 +02:00
Christian Mehlmauer
12dfc60f75 Added detection for Yoast Wordpress SEO plugin 2014-08-30 12:18:31 +02:00
erwanlr
a383d12061 Ensures to give a string to Typhoeus 2014-08-29 20:41:17 +02:00
Christian Mehlmauer
3131c6cb5d fix #673 2014-08-29 07:27:29 +02:00
erwanlr
5f53297f58 Also ensure to not process empty Location headers 2014-08-15 23:00:42 +02:00
erwanlr
cebd808674 Ensures a nil location is not processed when enumerating usernames 2014-08-15 22:54:17 +02:00
erwanlr
30a07f037e Fixes #661 - Don't hash directories named like a file 2014-08-14 17:42:08 +02:00
Peter
4ef1387781 Small change in output (coloring) 2014-08-10 13:19:58 +02:00
ethicalhack3r
1578ce2ebd Fix for infinite loop in wpstools #653 2014-08-07 23:05:46 +02:00
Christian Mehlmauer
391fd6c960 Fix Travis 2014-08-07 22:18:22 +02:00
Christian Mehlmauer
ef7ac1d77b Fix #626 2014-08-07 22:01:23 +02:00
Christian Mehlmauer
ca2610d74f Add exception so ruby wpscan.rb http://domain.com is detected 2014-08-07 21:38:37 +02:00
erwanlr
8d8aa52b9b Adds WP 3.9.2, 3.8.4 & 3.7.4 fingerprints - Ref #652 2014-08-06 21:31:00 +02:00
Ryan Dewhurst
84ec0c3964 Merge pull request #647 from wpvulndb/master
Pull Request from WPVULNDB
2014-08-01 14:29:58 +02:00
wpvulndb
f55736599e Commit from WPVULNDB 2014-08-01 14:23:02 +02:00
wpvulndb
b890235a82 Commit from WPVULNDB 2014-08-01 14:23:00 +02:00
wpvulndb
2cc3bc5759 Commit from WPVULNDB 2014-08-01 14:22:54 +02:00
ethicalhack3r
ca100ef7e9 Merge branch 'json_data'
Conflicts:
	data/plugin_vulns.xml
	data/theme_vulns.xml
2014-08-01 13:34:34 +02:00
ethicalhack3r
721cad75a2 Add file 2014-08-01 13:27:40 +02:00
erwanlr
c3110a4ab7 Merge pull request #643 from fgeek/2012-6652
Address CVE-2012-6652. Closes #623
2014-07-31 20:30:28 +01:00
Henri Salo
452aabf89b Address CVE-2012-6652. Closes #623 2014-07-31 22:17:23 +03:00
Peter
adcd6734ef Added Paid Membership Pro Vuln. Fix #627 2014-07-31 20:11:37 +02:00
Peter
a68c1f1cf7 Added Novana Vuln. Fix #630 2014-07-31 20:05:19 +02:00
Peter
712eaf9f1e Corrected a typo 2014-07-31 19:52:09 +02:00
Peter
7e119fa2ac Added Uploadify Vuln. Fix #634 2014-07-31 19:30:54 +02:00
ethicalhack3r
ac90ad0129 Dont use fail 2014-07-31 15:39:48 +02:00
ethicalhack3r
6b61e273a0 Use fail 2014-07-31 15:38:02 +02:00
ethicalhack3r
aab8e85f9d Implement FireFart's feedback 2014-07-31 15:31:07 +02:00
ethicalhack3r
3959892c20 Fix wpstools check-vuln-ref-urls 2014-07-31 15:26:13 +02:00
ethicalhack3r
420ad6cd37 Fix rspecs for new json 2014-07-31 14:08:49 +02:00
Peter
664bff544e git push origin masterMerge branch 'fgeek-vulndb4' 2014-07-31 13:28:23 +02:00
Peter
6716de6635 Fix merge conflict 2014-07-31 13:27:30 +02:00
Peter
4f50fbdfe4 Added new CVE's. Fix #572 2014-07-31 13:16:51 +02:00
Henri Salo
009abb3fd5 References. Added old starbox-voting FPD vulnerability. 2014-07-31 14:08:20 +03:00
Peter
191b4402e1 Added new CVE's. Update #572 2014-07-31 12:39:12 +02:00
Peter
13bc347897 Added new CVE's. Update #572 2014-07-31 12:13:27 +02:00
ethicalhack3r
187e2f1330 Correct wp_vulns file 2014-07-31 12:07:33 +02:00
ethicalhack3r
8d2ec115f5 Changed vuln data references to url 2014-07-31 11:56:14 +02:00
Peter
921596f6f8 Added WP-e-Commerce Vulns. Fix #640 2014-07-31 11:43:42 +02:00
Peter
a00987efc8 Added Email-Newsletter Vuln. Fix #632 2014-07-31 11:29:33 +02:00
Peter
b1a35d9df8 Added Uploader Vuln. Update #633 2014-07-31 11:21:22 +02:00
ethicalhack3r
08dfa4cab2 Implemented Erwan's feedback 2014-07-31 11:14:22 +02:00
erwanlr
63ca695b51 Merge pull request #629 from fgeek/vulndb2
Fixed error in plugin name.
2014-07-31 08:30:02 +01:00
erwanlr
55310247c2 Merge pull request #636 from fgeek/vulndb3
Added references.
2014-07-31 08:29:33 +01:00
Henri Salo
456334af75 Added references. 2014-07-31 09:16:27 +03:00
Henri Salo
38ce047d9e Fixed error in plugin name. 2014-07-31 08:35:21 +03:00
ethicalhack3r
14be7dead5 Work on json database file parsing, still needs some work. 2014-07-30 18:34:42 +02:00
erwanlr
ab2e368c6f Fixes #625 - Only parse styles when needed 2014-07-30 15:36:00 +01:00
Peter
0e7ca594ed Added CVE-2014-4938. Update #572 2014-07-30 16:30:12 +02:00
Peter
f742287496 Added CVE-2014-4937 and CVE-2014-4938. Update #572 2014-07-30 16:18:31 +02:00
Peter
cb37919e76 Added Simple Slider Vuln. Fix #614 2014-07-30 16:02:09 +02:00
Peter
933fc26b66 Merge pull request #624 from fgeek/GeoPlaces
geoplaces4 also uses name GeoPlaces4beta
2014-07-30 15:51:23 +02:00
Henri Salo
8ea94175ac geoplaces4 also uses name GeoPlaces4beta 2014-07-30 16:36:41 +03:00
erwanlr
013fb12c00 Improves the version comparison 2014-07-30 12:13:23 +01:00
erwanlr
1e6b5a1e4d Improves the version comparison 2014-07-30 12:11:04 +01:00
erwanlr
aed20db328 Merge pull request #621 from fgeek/vulndb
haiku-minimalist-audio-player osvdb reference
2014-07-30 12:02:49 +01:00
Henri Salo
332684f4e2 haiku-minimalist-audio-player osvdb reference 2014-07-30 13:47:01 +03:00
erwanlr
12d275c26b Updates bulletproof-securty vulns 2014-07-30 10:56:30 +01:00
ethicalhack3r
9b1312c7d9 Incorrect DB 2014-07-29 23:15:56 +02:00
Christian Mehlmauer
874b069357 Added metasploit module 2014-07-29 20:40:45 +02:00
erwanlr
03a917c326 Merge pull request #616 from fgeek/CVE-2012-6651
CVE-2012-6651/vitamin
2014-07-29 08:23:04 +01:00
erwanlr
6a5560a0b1 Merge pull request #617 from fgeek/media-library-categories
media-library-categories OSVDB ID correction
2014-07-29 08:22:36 +01:00
Henri Salo
6b0bbdc605 media-library-categories OSVDB ID correction 2014-07-29 08:11:43 +03:00
Henri Salo
4c0608d47d CVE-2012-6651/vitamin 2014-07-29 08:06:56 +03:00
Christian Mehlmauer
2e1aede8b4 Added metasploit module 2014-07-28 22:44:46 +02:00
Peter
2c3e968710 Added CVE-2014-4942. Update #572 2014-07-28 20:54:00 +02:00
Peter
ecf45803e0 Added Magazine Basic Theme vuln. Fix #597 2014-07-28 20:27:42 +02:00
Peter
2e4ede4251 Change WPtouch. Fix #587 2014-07-28 10:46:51 +02:00
Peter
4f52649f28 Change portable-phpmyadmin. Fix #583 2014-07-27 21:37:00 +02:00
Peter
11e58ff88d Added OSVDB 71966. Fix #607 2014-07-27 20:55:38 +02:00
erwanlr
a7c097a5a9 Merge pull request #612 from fgeek/pluginvulns2
CVE-2013-0721/wp-php-widget. Closes #599
2014-07-27 17:34:06 +01:00
erwanlr
8c53686697 Merge pull request #611 from fgeek/pluginvulns
mp3-jplayer vulnerability, references
2014-07-27 17:31:59 +01:00
Henri Salo
6754f1467a CVE-2013-0721/wp-php-widget. Closes #599 2014-07-27 19:25:11 +03:00
Henri Salo
fb98b3cc9a mp3-jplayer vulnerability, references 2014-07-27 19:18:25 +03:00
erwanlr
729f6fd308 Merge pull request #610 from fgeek/vulndb2
Adds detection for wp-imagezoom download.php file upload php code execution vulnerability
2014-07-27 13:56:56 +01:00
erwanlr
e2b0711271 Merge pull request #609 from fgeek/vulndb
Added references. Also closes #608.
2014-07-27 13:50:52 +01:00
Henri Salo
eb8cffb1a8 Adds detection for wp-imagezoom download.php file upload php code execution vulnerability 2014-07-27 15:48:45 +03:00
Henri Salo
d7e534ca74 Added references. Also closes #608. 2014-07-27 15:34:22 +03:00
erwanlr
347e261748 Merge pull request #605 from fgeek/user-photo
CVE-2013-1916/user-photo
2014-07-27 10:49:21 +01:00
Henri Salo
7deb9c4fbf CVE-2013-1916/user-photo 2014-07-27 12:42:27 +03:00
erwanlr
c1ab5ad929 Merge pull request #604 from fgeek/vulndb
Added references
2014-07-26 23:40:05 +01:00
Henri Salo
2686c37aa1 Added references 2014-07-27 01:29:00 +03:00
erwanlr
45edb9973d Merge pull request #602 from fgeek/dbdata2
Added references
2014-07-26 21:04:03 +01:00
Henri Salo
2bd4ce08c4 Added references 2014-07-26 22:30:36 +03:00
erwanlr
460d1ac86c Merge pull request #601 from fgeek/dbdata
Added references for plugin vulns
2014-07-26 20:28:29 +01:00
erwanlr
9df8da0b6f Merge pull request #596 from fgeek/theme-famous
famous OSVDB item
2014-07-26 20:22:36 +01:00
erwanlr
baaf85f567 Merge pull request #595 from fgeek/readme-change
Fixed typo, added note about pyfiscan as it is made for that reason.
2014-07-26 20:22:20 +01:00
erwanlr
6ffe817e86 Merge pull request #593 from fgeek/2013-7102
CVE-2013-7102/optimizepress fixed in version
2014-07-26 20:21:49 +01:00
erwanlr
edbdbdac56 Merge pull request #592 from fgeek/classipress
CVE-2011-5257/classipress
2014-07-26 20:21:21 +01:00
erwanlr
11c3c6d20e Merge pull request #591 from fgeek/buddypress
CVE-2012-2109/buddypress
2014-07-26 20:21:10 +01:00
erwanlr
81019b9fc8 Merge pull request #589 from fgeek/changes
Added references
2014-07-26 20:20:55 +01:00
erwanlr
4514123279 Merge pull request #582 from fgeek/CVE-2011-4562
CVE-2011-3981/allwebmenus-wordpress-menu-plugin, CVE-2011-4562/redirection
2014-07-26 20:20:38 +01:00
Henri Salo
0fc4a448aa New references 2014-07-26 22:19:24 +03:00
Henri Salo
bde51cc946 famous OSVDB item 2014-07-26 21:27:20 +03:00
Henri Salo
4f7e29163f Fixed typo, added note about pyfiscan as it is made for that reason. 2014-07-26 21:23:53 +03:00
Henri Salo
7837d1f6e8 CVE2013-7102/optimizepress fixed in version 2014-07-26 21:14:31 +03:00
Henri Salo
99bb300559 CVE-2011-5257/classipress 2014-07-26 21:09:12 +03:00
Henri Salo
f1108ef7d1 CVE-2012-2109/buddypress 2014-07-26 20:56:38 +03:00
Henri Salo
bd6cfec71c Added references. 2014-07-26 20:43:18 +03:00
Henri Salo
ef3ed86096 CVE-2011-4562/redirection 2014-07-26 18:26:28 +03:00
Henri Salo
097898b120 CVE-2011-3981/allwebmenus-wordpress-menu-plugin 2014-07-26 17:05:06 +03:00
Ryan Dewhurst
6fbf2643a1 Merge pull request #577 from fgeek/wysija-newsletters
CVE-2014-4725
2014-07-24 23:29:58 +02:00
Ryan Dewhurst
a1989c105e Merge pull request #576 from fgeek/readme
Added make to Debian installation guide, which is needed in minimal installation.
2014-07-24 23:29:00 +02:00
Henri Salo
97426e6d7d CVE-2014-4725 2014-07-24 13:12:09 +03:00
Henri Salo
b2e1b65ae5 Added make to Debian installation, which is needed in minimal installation. 2014-07-24 12:57:13 +03:00
Peter
06c8d34451 Added CVE-2014-4944. Update #572 2014-07-22 12:36:00 +02:00
erwanlr
ecba81ea5b Fixes #575 - Typo in a package name 2014-07-20 19:42:04 +02:00
Christian Mehlmauer
26e0066c82 Only output if different from style_url 2014-07-16 18:38:39 +02:00
Christian Mehlmauer
6ebb9b6f66 Fixed false positive theme detection 2014-07-16 18:25:35 +02:00
Christian Mehlmauer
102e30c29a Added metasploit module for WPTouch 2014-07-15 23:36:41 +02:00
ethicalhack3r
a8a716e0bd Change metasploit url to updated one 2014-07-15 14:35:56 +02:00
ethicalhack3r
9e23aaa5c0 Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-07-15 13:21:55 +02:00
ethicalhack3r
9b059c3985 Add wptouch vuln 2014-07-15 13:21:30 +02:00
Peter
2d3c7e65d2 Added CVE's. Update #567 2014-07-15 00:03:10 +02:00
Peter
9e7d3462ab Added CVE's. Update #567 2014-07-14 07:28:32 +02:00
Peter
aececf980b Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-07-11 18:22:42 +02:00
Peter
e5f3b4bf1d Added some missing Theme names 2014-07-11 18:20:30 +02:00
ethicalhack3r
9b629bb1c4 Backticks to 4 spaces 2014-07-11 17:07:33 +02:00
ethicalhack3r
9e39a57231 Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-07-11 17:03:24 +02:00
ethicalhack3r
47e9608aa2 Update links in MD 2014-07-11 17:02:29 +02:00
erwanlr
2f012caa3e Removes the remaining bacticks 2014-07-11 17:01:21 +02:00
ethicalhack3r
e835fc3ac0 MD test 2014-07-11 16:59:50 +02:00
ethicalhack3r
5240e9ce98 MD test 2014-07-11 16:57:59 +02:00
ethicalhack3r
b8ab2c839f MD test 2014-07-11 16:56:59 +02:00
ethicalhack3r
1ee81b90bf Change bacticks to 4 spaces in MD 2014-07-11 16:52:54 +02:00
ethicalhack3r
1354f2debb Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-07-11 16:50:31 +02:00
ethicalhack3r
7373ea24d8 Markdown test 2014-07-11 16:50:17 +02:00
erwanlr
7fc03461ba MD Test 2014-07-11 16:49:47 +02:00
ethicalhack3r
a5e45e2d79 Markdown test 2014-07-11 16:43:00 +02:00
ethicalhack3r
42cf2ac19b Markdown test 2014-07-11 16:42:10 +02:00
ethicalhack3r
6098d064a7 Markdown test 2014-07-11 16:41:16 +02:00
ethicalhack3r
cd79f576b7 Change markdown back 2014-07-11 16:39:18 +02:00
ethicalhack3r
4039a4a820 Quick markdown test 2014-07-11 16:38:17 +02:00
ethicalhack3r
919085d829 Use absolute URL for repo page 2014-07-11 16:26:02 +02:00
ethicalhack3r
88f27b39c4 Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-07-11 16:25:24 +02:00
ethicalhack3r
b1f38a51fe Use local WPScan logo 2014-07-11 16:25:06 +02:00
Peter
ef0253ee9e Added CVE's. Update #554 2014-07-11 16:20:46 +02:00
ethicalhack3r
3cf33af0e2 Add build-essentials requirement to Ubuntu > 14.04 2014-07-11 15:24:14 +02:00
Ryan Dewhurst
3eaa060aac Merge pull request #565 from fgeek/readme
Updated installation instr. for GNU/Linux Debian.
2014-07-11 12:01:32 +02:00
Henri Salo
cf4efee340 Updated installation instr. for GNU/Linux Debian. 2014-07-11 10:04:08 +03:00
Peter
0b04a96e15 Added CVE's. Update #554 2014-07-10 19:50:34 +02:00
Peter
c1d928c503 Added CVE's. Fix #564 2014-07-10 18:20:22 +02:00
Christian Mehlmauer
479b21a722 Replace all occurences 2014-07-10 00:30:33 +02:00
Christian Mehlmauer
ceeaeaf487 better username extraction 2014-07-10 00:24:20 +02:00
Peter
d5179b742b Added CVE's. Update #554 2014-07-09 22:09:55 +02:00
Peter
b38055c497 Added CVE-2014-4560, CVE-2014-4563. Update #554 2014-07-09 09:45:40 +02:00
Peter
ff1e9e63d6 Added CVE-2014-4603. Fix #550 2014-07-09 09:27:17 +02:00
Peter
a1a4293851 Added CVE-2014-4588. Fix #521 2014-07-09 09:17:51 +02:00
Peter
f39cc8ee53 Update vuln db 2014-07-07 21:02:06 +02:00
Peter
9fc5b90f25 Update vuln db 2014-07-06 23:19:55 +02:00
erwanlr
e7c9c884e9 Adds the NextGen Arbitrary File Upload vuln 2014-07-06 22:16:49 +02:00
Christian Mehlmauer
0469128917 They released another fix 2014-07-06 10:58:16 +02:00
erwanlr
656e38eae7 Updates the timthumbs list 2014-07-05 21:24:09 +02:00
Christian Mehlmauer
95721350da Added metasploit exploit 2014-07-03 21:47:41 +02:00
erwanlr
98d9e87356 Changes VersionCompare#is_newer_or_same? by lesser_or_equal? 2014-07-03 12:33:27 +02:00
erwanlr
a69cb4f4c2 Fixes #515 - theme-my-login LFI added 2014-07-03 10:05:33 +02:00
erwanlr
f42ea74e26 Adds the Parallax timthumb file location. Ref #506 2014-07-02 13:03:05 +02:00
erwanlr
d9b86f9922 Fix Timthumb RCE detection for version 2.0 (which was excluded) 2014-07-02 12:17:14 +02:00
erwanlr
605e9cfe6d Changes the vulnerable version of timthumb to 1.33 instead of 1.34 2014-07-01 22:10:01 +02:00
erwanlr
dd53c7b200 Fix #506 - Timthumbs WebShot RCE detection 2014-07-01 21:44:39 +02:00
ethicalhack3r
f9b10dc9db Added wysija-newsletters plugin file upload found by Sucuri 2014-07-01 18:04:09 +02:00
erwanlr
daef491d3e Changes the email in the Readme 2014-06-30 20:59:26 +02:00
erwanlr
95fde17d97 Updates the recommended ruby version 2014-06-30 20:57:06 +02:00
erwanlr
2c6cbb7799 Fix #509 - Stored XSS & CSRF in simple-share-buttons-adder 2014-06-30 20:51:33 +02:00
erwanlr
3498d4317a Fix #513 - login-rebuilder CSRF 2014-06-30 20:45:30 +02:00
erwanlr
611ef49d03 Merge pull request #511 from fgeek/pluginvulns
CVE-2014-4030 assigned
2014-06-28 10:08:53 +01:00
Henri Salo
fd2212db7b CVE-2014-4030 assigned 2014-06-27 18:37:25 +03:00
Christian Mehlmauer
4d8b8ba64c Changed text
in single sites it seems to be user registration, and
blog registration on multusite installations
2014-06-27 13:17:55 +02:00
Christian Mehlmauer
32fe70a354 Output registration URL 2014-06-27 00:15:55 +02:00
Christian Mehlmauer
e2652df546 Added fixed_in 2014-06-26 23:50:49 +02:00
ethicalhack3r
d1427d5f99 Add url to featured-comments plugin 2014-06-26 22:04:53 +02:00
Peter
ef814f3602 Added CVE-2012-6649. Fix #508 2014-06-26 15:21:24 +02:00
Peter
00acc8289e Added CVE-2012-6649. Fix #508 2014-06-26 15:20:05 +02:00
Peter
341f980974 Added CVE-2012-6649. Fix #509 2014-06-26 14:44:53 +02:00
Peter
1b7ea5bed3 Update vuln db 2014-06-26 08:35:02 +02:00
Peter
ee1c92ffa0 Small change vuln db 2014-06-25 15:08:59 +02:00
Peter
0114a50f61 Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-06-25 11:51:56 +02:00
Peter
c7c9e105ef Update vuln db 2014-06-25 11:50:20 +02:00
ethicalhack3r
3e31e71116 Added old disqus sqli bug. Poss fake... 2014-06-25 11:28:17 +02:00
ethicalhack3r
e74b1d2210 Add new disqus RCE vuln 2014-06-25 11:25:41 +02:00
Ryan Dewhurst
1ca2f28187 Merge pull request #507 from fgeek/pluginvulns
CVEs for old issues
2014-06-25 09:39:55 +02:00
Henri Salo
9fc75b651e CVE for OSVDB item 85134 2014-06-25 10:02:48 +03:00
Henri Salo
934a6acdd2 CVE for OSVDB item 107297 2014-06-25 09:54:56 +03:00
Peter
88adc5676f Update vuln db 2014-06-24 22:11:53 +02:00
Peter
f27483ea7b Merge pull request #505 from fgeek/readmechanges
Changed copyright year. Small change to prerequirements.
2014-06-24 15:00:46 +02:00
Henri Salo
6a11c620cf Changed copyright year. Small change to prerequirements. 2014-06-24 12:15:57 +03:00
Peter
7281f15051 Add wp-football vulnerabilities in db 2014-06-24 10:58:01 +02:00
Peter
b1196fb09b Small change to correct XML tag 2014-06-19 20:38:24 +02:00
Peter
27fb875c0d Small change to correct XML tag 2014-06-19 20:36:22 +02:00
Peter
3cdeac5dfb Fix #503. Update CREDITS 2014-06-19 12:49:31 +02:00
Peter
e1c47ce5c3 Fix #490. Add a disclaimer file. 2014-06-19 09:51:23 +02:00
Peter
d9523cb1bc Update vuln db 2014-06-17 22:17:08 +02:00
Peter
bd2403388e Added CVE-2014-3921. Fix #497 2014-06-17 21:38:41 +02:00
Christian Mehlmauer
7511208b8b Update README 2014-06-17 16:56:36 +02:00
Christian Mehlmauer
4586d44c1f Update README.md 2014-06-17 16:55:43 +02:00
Peter
717e5b07d1 Added CVE-2014-3961. Fix #498 2014-06-17 13:19:56 +02:00
ethicalhack3r
2c6082f454 Tell Travis to ignore Ruby 1.9.2 errors 2014-06-17 12:12:05 +02:00
Christian Mehlmauer
586239292b Try to fix Travis 2014-06-17 10:59:02 +02:00
Christian Mehlmauer
7bd1c87bf6 Update README 2014-06-17 07:12:26 +02:00
Christian Mehlmauer
6eded4cdc2 Update README.md 2014-06-17 07:12:18 +02:00
Christian Mehlmauer
5e693f2274 Update README.md 2014-06-17 07:12:01 +02:00
Christian Mehlmauer
b0e3aeed6c Update README 2014-06-17 07:08:41 +02:00
Peter
dd9ef38636 Removed useless line in Vuln db 2014-06-16 09:52:43 +02:00
Peter
32df782470 Added CVE-2013-3937. Fix #499 2014-06-16 07:46:07 +02:00
Peter
1d9162930c Added CVE-2013-3257. Fix #500 2014-06-15 09:31:46 +02:00
Peter
152d02bcbe Added CVE-2013-3258. Fix #501 2014-06-15 09:23:35 +02:00
ethicalhack3r
2cc4dc724b Made title of some vulns smaller 2014-06-11 23:22:17 +02:00
Peter
1ee14f4c69 Update vuln db 2014-06-10 08:47:25 +02:00
Christian Mehlmauer
7748019a76 Update pre-commit-hook.rb 2014-06-07 00:28:37 +02:00
Peter
8241a1d8a3 Update README. Fixes: #496, #482 and #477 2014-06-06 09:36:33 +02:00
Peter
83e3373561 Update vuln db 2014-06-04 09:08:41 +02:00
erwanlr
c8c126d444 Rspec 3.0 support 2014-06-02 22:06:49 +02:00
erwanlr
c12b1d0670 Pre-transpec 2014-06-02 22:02:44 +02:00
Peter
5caf4f45a9 Fix #494. All in one SEO pack vulnerability 2014-06-02 20:25:58 +02:00
Christian Mehlmauer
8f51ff2910 Merge branch 'master' of github.com:wpscanteam/wpscan 2014-05-31 15:59:26 +02:00
Christian Mehlmauer
6b8436f825 Replace some '/' by File.join 2014-05-31 15:59:05 +02:00
erwanlr
c4b146b36b Fixes #489 - Adds bib2html CVE 2014-05-29 14:53:42 +02:00
erwanlr
098b14884d Fixes #491 - DZS Video Gallery Content Spoofing & XSS 2014-05-29 14:46:54 +02:00
Peter
47d8818028 Update vuln db 2014-05-28 11:18:58 +02:00
erwanlr
e3bc50a163 Fixes #487 2014-05-27 14:55:42 +02:00
Christian Mehlmauer
34ba6a86c9 set ruby version and gemset for rvm users 2014-05-27 09:45:16 +02:00
Peter
2369ef53ac Update vuln db 2014-05-25 22:02:52 +02:00
erwanlr
8d3907ff65 Fixes the location of the robots.txt check 2014-05-22 17:45:10 +02:00
erwanlr
2760eaca85 Adds ruby 2.1.2 to Travis 2014-05-22 17:41:01 +02:00
erwanlr
af0319cc66 Adds a --cookie option. Ref #485 2014-05-22 17:34:09 +02:00
Peter
e050539747 Update vuln db 2014-05-22 09:20:08 +02:00
erwanlr
451756c764 Merge pull request #484 from fgeek/master
Address CVE-2014-3210
2014-05-21 19:22:50 +02:00
Henri Salo
afa40df7ad Address CVE-2014-3210 2014-05-21 20:03:26 +03:00
Henri Salo
fb2b606d26 Address CVE-2014-3210 2014-05-21 20:02:55 +03:00
Peter
e0ebd47730 Update vuln db 2014-05-18 00:31:25 +02:00
Peter
e97f4e8020 Fix for Jetpack plugin false positive. Fix: #481 2014-05-15 08:05:12 +02:00
erwanlr
79f07b7350 Properly removes the colour sequence from log. Fixes #480 2014-05-14 18:33:23 +02:00
Peter
c1c8829536 Update vuln db 2014-05-13 22:42:28 +02:00
Peter
ef20371562 Timthumb in MoneyTheme
See also: http://packetstormsecurity.com/files/123819/
2014-05-12 20:34:31 +02:00
ethicalhack3r
c08f275cf7 Updated Gemfile 2014-05-12 16:57:34 +02:00
ethicalhack3r
6f995fe350 Updated ruby-progressbar to 1.5.0 2014-05-12 16:23:08 +02:00
Peter
68aec92d3a Update vuln db 2014-05-11 00:04:37 +02:00
erwanlr
dda328210c Bumps the version 2014-05-10 16:10:57 +02:00
erwanlr
c3f4f232e3 Updates the plugin & theme lists 2014-05-10 16:09:54 +02:00
erwanlr
302f1da066 Ensures a clean abort of Hydra, Ref #461 2014-05-10 10:23:24 +02:00
erwanlr
a6e65d33dd Updates ruby-progressbar constraint 2014-05-10 10:02:14 +02:00
Christian Mehlmauer
7b0cb29466 XML check rspecs
Example output:
  1) XML content each plugin vuln needs a type node
     Failure/Error: @result.should have(0).items, "Items:\n#{@result.join("\n")}"
       Items:
       ReFlex Gallery 1.4 - reflex-gallery.php Direct Request Path Disclosure
       Gallery Plugin 3.8.3 - gallery-plugin.php filename_1 Parameter Arbitrary File Access
       EZPZ One Click Backup <= 12.03.10 - OS Command Injection
       BulletProof Security - Security Log Script Insertion Vulnerability
       Portable phpMyAdmin - /pma/phpinfo.php Direct Request System Information Disclosure
       HMS Testimonials 2.0.10 - CSRF
       HMS Testimonials 2.0.10 - XSS
       platinum_seo_pack.php - s Parameter Reflected XSS
       Email Newsletter 8.0 - 'option' Parameter Information Disclosure Vulnerability
2014-05-09 17:58:04 +02:00
ethicalhack3r
a3eedb14f4 Added missing type nodes 2014-05-09 15:38:30 +02:00
ethicalhack3r
74d73a1d17 Added missing type node 2014-05-09 15:29:18 +02:00
ethicalhack3r
92e7e8516c Added missing type node 2014-05-09 15:25:26 +02:00
ethicalhack3r
61ac0b7d20 Added missing type node 2014-05-09 15:22:30 +02:00
ethicalhack3r
8b4ea7fd7c Added missing type 2014-05-09 15:15:47 +02:00
ethicalhack3r
90846cf770 Added missing type to vuln 2014-05-09 15:05:01 +02:00
ethicalhack3r
a9e33ea282 Added missing type 2014-05-09 14:58:57 +02:00
ethicalhack3r
eea006e787 Added missing type node 2014-05-09 14:53:27 +02:00
Peter
9e58098e5c Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-05-09 08:32:08 +02:00
Peter
ff49f574d4 Merge branch 'droope-patch-1' 2014-05-09 08:30:18 +02:00
Peter
599d816a88 Solve Git Merge conflict 2014-05-09 08:13:33 +02:00
Pedro Worcel
4b0dd04114 Update plugin_vulns.xml
add <vulnerability> tag
2014-05-09 10:49:55 +12:00
erwanlr
36a0fbf181 Adds 3.9.1 fingerprints 2014-05-08 21:20:36 +02:00
erwanlr
3cfd8f40da Removes the Travis failure allowed for ruby-2.1.0 2014-05-08 15:06:27 +02:00
Christian Mehlmauer
23173c4bf4 Merge pull request #476 from droope/patch-2
Update plugin_vulns.xml
2014-05-08 09:21:10 +02:00
Pedro Worcel
722c31ccd9 Update plugin_vulns.xml
Hi there,

adding http://packetstormsecurity.com/files/126521/wpphotogallery-xsrf.txt to the list, security researcher was a bad boy and didn't specify version or anything.

Ta,
Pedro
2014-05-08 17:40:15 +12:00
Pedro Worcel
7623a01272 Update plugin_vulns.xml
Added code exec + others in iMember360is. I assume the name of the plugin is "infusion4wp" due to the fact that you can download a zip file from here http://docs.imember360.com/welcome/ which has that as the zip root folder.
2014-05-08 17:23:22 +12:00
Peter
1b90fdce73 Update vuln db 2014-05-06 09:14:29 +02:00
Peter
ce57db9526 Fixed vulnerabilities in statistics 2014-05-05 18:42:36 +02:00
Peter
8b9e47cd11 Update vuln db 2014-05-05 00:24:37 +02:00
Peter
a87a261b80 Markup the command help 2014-05-02 15:31:09 +02:00
Peter
989d561679 Small updates for the --no-color argument switch 2014-05-02 15:04:59 +02:00
Peter
b349990b19 Added a --no-color argument switch 2014-05-02 14:43:16 +02:00
Peter
2104b49cee Output: Give 'Fixed in' an informational tag' 2014-05-02 13:42:10 +02:00
Peter
77606efb77 Merge branch 'master' of https://github.com/wpscanteam/wpscan 2014-05-01 12:09:04 +02:00
Peter
6164ad2ab1 Fix #472. WPScan stops after redirection if not WordPress website 2014-05-01 12:08:03 +02:00
erwanlr
a60d58dcb0 Merge pull request #473 from fgeek/master
CVE-2014-3114
2014-05-01 11:47:02 +02:00
Henri Salo
4e45d17ad2 CVE-2014-3114 2014-05-01 12:13:43 +03:00
erwanlr
c8e614d064 Allows ruby-2.1.0 to fail until a solution is found 2014-04-30 23:22:09 +02:00
Peter
544beeb078 Update vuln db 2014-04-30 22:25:00 +02:00
erwanlr
a00f0d8367 Fixes #464 - Readmes updated to reflect recent changes about the config file & batch mode 2014-04-30 16:59:17 +02:00
Peter
ea57290792 Added ArchAssault distro - WPScan comes pre-installed with this distro 2014-04-27 16:56:01 +02:00
Peter
603a4afaf3 Merge pull request #470 from wpscanteam/layout-423
New improved Layout (see #423)
2014-04-27 16:02:54 +02:00
Peter
19e2772729 Update wpscan.rb 2014-04-27 15:49:15 +02:00
Peter
82ebb82a5f Small change in code 2014-04-27 15:40:12 +02:00
Peter
516ae6b68c Fix git merge problem 2014-04-27 15:32:10 +02:00
Peter
59225a4b9c Update vuln db 2014-04-25 15:43:55 +02:00
Peter
1da9d36ecc Update vuln db 2014-04-22 21:11:15 +02:00
Peter
0787e5c738 Update vuln db - #467 2014-04-22 13:04:51 +02:00
FireFart
e52e82fb78 formatting 2014-03-22 18:12:47 +01:00
FireFart
78cb3f8ee2 Merge remote-tracking branch 'origin/master' into layout-423 2014-03-22 18:01:22 +01:00
Peter
17dcc7ec80 Undo even more, wrong branch 2014-03-16 23:16:40 +01:00
Peter
565eed99ef Undo last commit, wrong branch 2014-03-16 22:58:42 +01:00
Peter
1f13c47a46 Update vuln db 2014-03-16 22:30:37 +01:00
Peter
ec5d12c940 Changed layout and coloring 2014-03-08 22:47:43 +01:00
Peter
5fbfa1453c Layout changes with new colors 2014-03-07 23:16:50 +01:00
158 changed files with 1987 additions and 78938 deletions

1
.ruby-gemset Normal file
View File

@@ -0,0 +1 @@
wpscan

1
.ruby-version Normal file
View File

@@ -0,0 +1 @@
2.1.2

View File

@@ -5,7 +5,11 @@ rvm:
- 2.0.0
- 2.1.0
- 2.1.1
script: bundle exec rspec --format documentation
- 2.1.2
script: bundle exec rspec
notifications:
email:
- wpscanteam@gmail.com
matrix:
allow_failures:
- rvm: 1.9.2

View File

@@ -1,6 +1,86 @@
# Changelog
## Master
[Work in progress](https://github.com/wpscanteam/wpscan/compare/2.4...master)
[Work in progress](https://github.com/wpscanteam/wpscan/compare/2.5...master)
## Version 2.5
Released: 2014-09-26 (@ BruCON 2014)
New
* Exit program after --update
* Detect directory listing in upload folder
* Be more verbose when no version can be detected
* Added detection for Yoast Wordpress SEO plugin
* Also ensure to not process empty Location headers
* Ensures a nil location is not processed when enumerating usernames
* Fix #626 - Detect 'Must_Use_Plugins'
* better username extraction
* Add a --cookie option. Ref #485
* Add a --no-color option
* Output: Give 'Fixed in' an informational tag
* Added ArchAssault distro - WPScan comes pre-installed with this distro
* Layout changes with new colors
Removed
* Removes the source code updaters
* Removes the ListGenerator plugin from WPStools
* Removes all files from data/
General core
* Update docs to reflect new updating logic
* Little output change and coloring
* Adds a missing verbose output
* Re-build redirection url if begin with slash '/'
* Fixes the remove_conditional_comments function
* Ensures to give a string to Typhoeus
* Fix wpstools check-vuln-ref-urls
* Fix rspecs for new json
* Only output if different from style_url
* Add exception so 'ruby wpscan.rb http://domain.com' is detected
* Added make to Debian installation, which is needed in minimal installation.
* Add build-essentials requirement to Ubuntu > 14.04
* Updated installation instr. for GNU/Linux Debian.
* Changes VersionCompare#is_newer_or_same? by lesser_or_equal?
* Fixes the location of the robots.txt check
* Updates the recommended ruby version
* Rspec 3.0 support
* Adds ruby 2.1.2 to Travis
* Updated ruby-progressbar to 1.5.0
WordPress Fingerprints
* Adds WP 4.0 fingerprints
* Adds WP 3.9.2, 3.8.4 & 3.7.4 fingerprints - Ref #652
* Adds 3.9.1 fingerprints
Fixed issues
* Fix #689 - Adds config file to check
* Fix #694 - Output Arrays
* Fix #693 - Adds pathname require statement
* Fix #657 - generate method
* Fix #685 - Potenial fix for 'marshal data too short' error
* Fix #686 - Adds specs for relative URI in Location headers
* Fix #435 - Update license
* Fix #674 - Improves the Plugins & Themes passive detection
* Fix #673 - Problem with the output
* Fix #661 - Don't hash directories named like a file
* Fix #653 - Fix for infinite loop in wpstools
* Fix #625 - Only parse styles when needed
* Fix #481 - Fix for Jetpack plugin false positive
* Fix #480 - Properly removes the colour sequence from log
* Fix #472 - WPScan stops after redirection if not WordPress website
* Fix #464 - Readmes updated to reflect recent changes about the config file & batch mode
Vulnerabilities
* geoplaces4 also uses name GeoPlaces4beta
* Added metasploit module's
* Added some timthumb detections
WPScan Database Statistics:
* Total vulnerable versions: 87
* Total vulnerable plugins: 854
* Total vulnerable themes: 303
* Total version vulnerabilities: 752
* Total plugin vulnerabilities: 1351
* Total theme vulnerabilities: 345
## Version 2.4
Released: 2014-04-17
@@ -12,7 +92,6 @@ New
* Switch over to nist - Fix #301
* New choice added when a redirection is detected - Fix #438
Removed
* Removed 'Total WordPress Sites in the World' counter from stats
* Old wpscan repo links removed - Fix #440

View File

@@ -11,10 +11,11 @@ Ryan Dewhurst - @ethicalhack3r (Project Lead)
*Other Contributors*
Henri Salo AKA fgeek - Reported lots of vulnerabilities
Alip AKA Undead - alip.aswalid at gmail.com
michee08 - Reported and gave potential solutions to bugs.
michee08 - Reported and gave potential solutions to bugs
Callum Pember - Implemented proxy support - callumpember at gmail.com
g0tmi1k - Additional timthumb checks + bug reports.
g0tmi1k - Additional timthumb checks + bug reports
Melvin Lammerts - Reported a couple of fake vulnerabilities - melvin at 12k.nl
Paolo Perego - @thesp0nge - Basic authentication
Gianluca Brindisi - @gbrindisi - Project Developer
Gianluca Brindisi - @gbrindisi - Project Developer

2
DISCLAIMER.txt Normal file
View File

@@ -0,0 +1,2 @@
WPScan is not responsible for misuse or for any damage that you may cause!
You agree that you use this software at your own risk.

19
Gemfile
View File

@@ -1,13 +1,14 @@
source "https://rubygems.org"
source 'https://rubygems.org'
gem "typhoeus", "~>0.6.8"
gem "nokogiri"
gem "json"
gem "terminal-table"
gem "ruby-progressbar", ">=1.2.0"
gem 'typhoeus', '~>0.6.8'
gem 'nokogiri'
gem 'json'
gem 'terminal-table'
gem 'ruby-progressbar', '>=1.6.0'
group :test do
gem "webmock", ">=1.17.2"
gem "simplecov"
gem "rspec", :require => "spec"
gem 'webmock', '>=1.17.2'
gem 'simplecov'
gem 'rspec', '~>3.0'
gem 'rspec-its'
end

29
LICENSE
View File

@@ -1,15 +1,20 @@
WPScan - WordPress Security Scanner
Copyright (C) 2012-2013
The WPScan software and its data (henceforth both referred to simply as "WPScan") is dual-licensed - copyright 2011-2014 The WPScan Team.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cases that include commercialization of WPScan require a commercial, non-free license. Otherwise, the system can be used under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Cases of commercialization are:
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
- Using WPScan to provide commercial managed/Software-as-a-Service services.
- Distributing WPScan as a commercial product or as part of one.
Cases which do not require a commercial license, and thus fall under the terms of GNU General Public License, include (but are not limited to):
- Penetration testers (or penetration testing organizations) using WPScan as part of their assessment toolkit. So long as that does not conflict with the commercialization clause.
- Using WPScan to test your own systems.
- Any non-commercial use of WPScan.
If you need to acquire a commercial license or are unsure about whether you need to acquire a commercial license, please get in touch, we will be happy to clarify things for you and work with you to accommodate your requirements.
wpscanteam at gmail.com
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

127
README
View File

@@ -9,23 +9,26 @@ __________________________________________________
==LICENSE==
WPScan - WordPress Security Scanner
Copyright (C) 2011-2013 The WPScan Team
The WPScan software and its data (henceforth both referred to simply as "WPScan") is dual-licensed - copyright 2011-2014 The WPScan Team.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cases that include commercialization of WPScan require a commercial, non-free license. Otherwise, the system can be used under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Cases of commercialization are:
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
- Using WPScan to provide commercial managed/Software-as-a-Service services.
- Distributing WPScan as a commercial product or as part of one.
ryandewhurst at gmail
Cases which do not require a commercial license, and thus fall under the terms of GNU General Public License, include (but are not limited to):
- Penetration testers (or penetration testing organizations) using WPScan as part of their assessment toolkit. So long as that does not conflict with the commercialization clause.
- Using WPScan to test your own systems.
- Any non-commercial use of WPScan.
If you need to acquire a commercial license or are unsure about whether you need to acquire a commercial license, please get in touch, we will be happy to clarify things for you and work with you to accommodate your requirements.
wpscanteam at gmail.com
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
==INSTALL==
@@ -35,22 +38,38 @@ ryandewhurst at gmail
* Kali Linux
* Pentoo
* SamuraiWTF
* ArchAssault
Prerequisites:
* Windows not supported
* Ruby >= 1.9.2 - Recommended: 1.9.3
* Ruby >= 1.9.2 - Recommended: 2.1.2
* Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
* RubyGems - Recommended: latest
* Git
-> Installing on Debian/Ubuntu:
-> Installing on Ubuntu:
Before Ubuntu 14.04:
sudo apt-get install libcurl4-gnutls-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev ruby-dev
From Ubuntu 14.04:
sudo apt-get install libcurl4-gnutls-dev libxml2 libxml2-dev libxslt1-dev ruby-dev build-essential
sudo apt-get install libcurl4-gnutls-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev ruby-dev
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
sudo gem install bundler && bundle install --without test
-> Installing on Debian:
sudo apt-get install git ruby ruby-dev libcurl4-gnutls-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
@@ -78,6 +97,20 @@ ryandewhurst at gmail
cd wpscan
sudo gem install bundler && sudo bundle install --without test
-> Installing with RVM:
cd ~
curl -sSL https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
rvm install 2.1.2
rvm use 2.1.2 --default
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
gem install bundler
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
bundle install --without test
==KNOWN ISSUES==
- Typhoeus segmentation fault:
@@ -116,7 +149,7 @@ ryandewhurst at gmail
==WPSCAN ARGUMENTS==
--update Update to the latest revision
--update Update the databases.
--url | -u <target url> The WordPress URL/domain to scan.
@@ -131,15 +164,15 @@ ryandewhurst at gmail
ap all plugins (can take a long time)
tt timthumbs
t themes
vp only vulnerable themes
vt only vulnerable themes
at all themes (can take a long time)
Multiple values are allowed : '-e tt,p' will enumerate timthumbs and plugins
If no option is supplied, the default is 'vt,tt,u,vp'
Multiple values are allowed : "-e tt,p" will enumerate timthumbs and plugins
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
You do not need to provide the regexp delimiters, but you must write the quotes (simple or double)
--exclude-content-based "<regexp or string>" 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
--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
@@ -151,31 +184,35 @@ ryandewhurst at gmail
--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 <[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 (will override the one from conf/browser.conf.json).
--proxy-auth <username:password> Supply the proxy login credentials.
--basic-auth <username:password> Set the HTTP Basic authentication
--basic-auth <username:password> Set the HTTP Basic authentication.
--wordlist | -w <wordlist> Supply a wordlist for the password bruter and do the brute.
--threads | -t <number of threads> The number of threads to use when multi-threading requests. (will override the value from conf/browser.conf.json)
--threads | -t <number of threads> The number of threads to use when multi-threading requests.
--username | -U <username> Only brute force the supplied username.
--cache-ttl <cache-ttl> Typhoeus cache TTL
--cache-ttl <cache-ttl> Typhoeus cache TTL.
--request-timeout <request-timeout> Request Timeout
--request-timeout <request-timeout> Request Timeout.
--connect-timeout <connect-timeout> Connect Timeout
--connect-timeout <connect-timeout> Connect Timeout.
--max-threads <max-threads> Maximum Threads
--max-threads <max-threads> Maximum Threads.
--help | -h This help screen.
--verbose | -v Verbose output.
--batch Never ask for user input, use the default behaviour.
--no-color Do not use colors in the output.
==WPSCAN EXAMPLES==
Do 'non-intrusive' checks...
@@ -202,7 +239,7 @@ Use custom content directory...
ruby wpscan.rb -u www.example.com --wp-content-dir custom-content
Update WPScan...
Update WPScan's databases...
ruby wpscan.rb --update
@@ -212,21 +249,27 @@ Debug output...
==WPSTOOLS ARGUMENTS==
--help | -h This help screen.
--Verbose | -v Verbose output.
--update | -u Update to the latest revision.
--generate_plugin_list [number of pages] Generate a new data/plugins.txt file. (supply number of *pages* to parse, default : 150)
--gpl Alias for --generate_plugin_list
--check-local-vulnerable-files | --clvf <local directory> Perform a recursive scan in the <local directory> to find vulnerable files or shells
-v, --verbose Verbose output
--check-vuln-ref-urls, --cvru Check all the vulnerabilities reference urls for 404
--check-local-vulnerable-files, --clvf LOCAL_DIRECTORY Perform a recursive scan in the LOCAL_DIRECTORY to find vulnerable files or shells
--generate-plugin-list, --gpl [NUMBER_OF_ITEMS] Generate a new data/plugins.txt file. (supply number of *items* to parse, default : 1500)
--generate-full-plugin-list, --gfpl Generate a new full data/plugins.txt file
--generate-theme-list, --gtl [NUMBER_OF_ITEMS] Generate a new data/themes.txt file. (supply number of *items* to parse, default : 200)
--generate-full-theme-list, --gftl Generate a new full data/themes.txt file
--generate-all, --ga Generate a new full plugins, full themes, popular plugins and popular themes list
-s, --stats Show WpScan Database statistics
--spellcheck, --sc Check all files for common spelling mistakes.
==WPSTOOLS EXAMPLES==
- Generate a new 'most popular' plugin list, up to 150 pages ...
ruby wpstools.rb --generate_plugin_list 150
- Generate a new 'most popular' plugin list, up to 1500 items ...
ruby wpstools.rb --generate-plugin-list 1500
- Locally scan a wordpress installation for vulnerable files or shells :
Locally scan a wordpress installation for vulnerable files or shells:
ruby wpstools.rb --check-local-vulnerable-files /var/www/wordpress/
Or check https://github.com/fgeek/pyfiscan project.
===PROJECT HOME===
www.wpscan.org

192
README.md
View File

@@ -1,26 +1,29 @@
![alt text](http://dvwa.co.uk/images/wpscan_logo_407x80.png "WPScan - WordPress Security Scanner")
![alt text](https://raw.githubusercontent.com/wpscanteam/wpscan/gh-pages/wpscan_logo_407x80.png "WPScan - WordPress Security Scanner")
[![Build Status](https://travis-ci.org/wpscanteam/wpscan.png?branch=master)](https://travis-ci.org/wpscanteam/wpscan)
#### LICENSE
WPScan - WordPress Security Scanner
Copyright (C), 2011-2013 The WPScan Team
The WPScan software and its data (henceforth both referred to simply as "WPScan") is dual-licensed - copyright 2011-2014 The WPScan Team.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cases that include commercialization of WPScan require a commercial, non-free license. Otherwise, the system can be used under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Cases of commercialization are:
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
- Using WPScan to provide commercial managed/Software-as-a-Service services.
- Distributing WPScan as a commercial product or as part of one.
ryandewhurst at gmail
Cases which do not require a commercial license, and thus fall under the terms of GNU General Public License, include (but are not limited to):
- Penetration testers (or penetration testing organizations) using WPScan as part of their assessment toolkit. So long as that does not conflict with the commercialization clause.
- Using WPScan to test your own systems.
- Any non-commercial use of WPScan.
If you need to acquire a commercial license or are unsure about whether you need to acquire a commercial license, please get in touch, we will be happy to clarify things for you and work with you to accommodate your requirements.
wpscanteam at gmail.com
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
#### INSTALL
@@ -30,60 +33,76 @@ WPScan comes pre-installed on the following Linux distributions:
- [Kali Linux](http://www.kali.org/)
- [Pentoo](http://www.pentoo.ch/)
- [SamuraiWTF](http://samurai.inguardians.com/)
- [ArchAssault](https://archassault.org/)
Prerequisites:
- Windows not supported
- Ruby >= 1.9.2 - Recommended: 1.9.3
- Ruby >= 1.9.2 - Recommended: 2.1.2
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
- RubyGems - Recommended: latest
- Git
*Installing on Debian/Ubuntu:*
Windows is not supported.
```sudo apt-get install libcurl4-gnutls-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev ruby-dev```
####Installing on Ubuntu:
```git clone https://github.com/wpscanteam/wpscan.git```
Before Ubuntu 14.04:
```cd wpscan```
sudo apt-get install libcurl4-gnutls-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev ruby-dev
```sudo gem install bundler && bundle install --without test```
From Ubuntu 14.04:
*Installing on Fedora:*
sudo apt-get install libcurl4-gnutls-dev libxml2 libxml2-dev libxslt1-dev ruby-dev build-essential
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
sudo gem install bundler && bundle install --without test
```sudo yum install gcc ruby-devel libxml2 libxml2-devel libxslt libxslt-devel libcurl-devel```
####Installing on Debian:
```git clone https://github.com/wpscanteam/wpscan.git```
sudo apt-get install git ruby ruby-dev libcurl4-gnutls-dev make
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
sudo gem install bundler
bundle install --without test --path vendor/bundle
```cd wpscan```
####Installing on Fedora:
```sudo gem install bundler && bundle install --without test```
sudo yum install gcc ruby-devel libxml2 libxml2-devel libxslt libxslt-devel libcurl-devel
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
sudo gem install bundler && bundle install --without test
*Installing on Archlinux:*
####Installing on Archlinux:
```pacman -Syu ruby```
pacman -Syu ruby
pacman -Syu libyaml
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
sudo gem install bundler && bundle install --without test
gem install typhoeus
gem install nokogiri
```pacman -Syu libyaml```
####Installing on Mac OSX:
```git clone https://github.com/wpscanteam/wpscan.git```
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)
```cd wpscan```
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
sudo gem install bundler && sudo bundle install --without test
```sudo gem install bundler && bundle install --without test```
####Installing with RVM:
```gem install typhoeus```
```gem install nokogiri```
*Installing 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
```git clone https://github.com/wpscanteam/wpscan.git```
```cd wpscan```
```sudo gem install bundler && sudo bundle install --without test```
cd ~
curl -sSL https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
rvm install 2.1.2
rvm use 2.1.2 --default
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
gem install bundler
git clone https://github.com/wpscanteam/wpscan.git
cd wpscan
bundle install --without test
#### KNOWN ISSUES
@@ -96,7 +115,7 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
Update cURL to version => 7.21.7 (may have to install from source).
Installation from sources :
```
Grab the sources from http://curl.haxx.se/download.html
Decompress the archive
Open the folder with the extracted files
@@ -104,21 +123,21 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
Run make
Run sudo make install
Run sudo ldconfig
```
- cannot load such file -- readline:
```sudo aptitude install libreadline5-dev libncurses5-dev```
sudo aptitude install libreadline5-dev libncurses5-dev
Then, open the directory of the readline gem (you have to locate it)
```
cd ~/.rvm/src/ruby-1.9.2-p180/ext/readline
ruby extconf.rb
make
make install
```
See http://vvv.tobiassjosten.net/ruby-on-rails/fixing-readline-for-the-ruby-on-rails-console/ for more details
See [http://vvv.tobiassjosten.net/ruby-on-rails/fixing-readline-for-the-ruby-on-rails-console/](http://vvv.tobiassjosten.net/ruby-on-rails/fixing-readline-for-the-ruby-on-rails-console/) for more details
- no such file to load -- rubygems
@@ -126,11 +145,11 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
And select your ruby version
See https://github.com/wpscanteam/wpscan/issues/148
See [https://github.com/wpscanteam/wpscan/issues/148](https://github.com/wpscanteam/wpscan/issues/148)
#### WPSCAN ARGUMENTS
--update Update to the latest revision
--update Update the databases.
--url | -u <target url> The WordPress URL/domain to scan.
@@ -147,13 +166,13 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
t themes
vt only vulnerable themes
at all themes (can take a long time)
Multiple values are allowed : '-e tt,p' will enumerate timthumbs and plugins
If no option is supplied, the default is 'vt,tt,u,vp'
Multiple values are allowed : "-e tt,p" will enumerate timthumbs and plugins
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
You do not need to provide the regexp delimiters, but you must write the quotes (simple or double)
--exclude-content-based "<regexp or string>" 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
--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
@@ -165,31 +184,35 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
--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 <[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 (will override the one from conf/browser.conf.json).
--proxy-auth <username:password> Supply the proxy login credentials.
--basic-auth <username:password> Set the HTTP Basic authentication
--basic-auth <username:password> Set the HTTP Basic authentication.
--wordlist | -w <wordlist> Supply a wordlist for the password bruter and do the brute.
--threads | -t <number of threads> The number of threads to use when multi-threading requests. (will override the value from conf/browser.conf.json)
--threads | -t <number of threads> The number of threads to use when multi-threading requests.
--username | -U <username> Only brute force the supplied username.
--cache-ttl <cache-ttl> Typhoeus cache TTL
--cache-ttl <cache-ttl> Typhoeus cache TTL.
--request-timeout <request-timeout> Request Timeout
--request-timeout <request-timeout> Request Timeout.
--connect-timeout <connect-timeout> Connect Timeout
--connect-timeout <connect-timeout> Connect Timeout.
--max-threads <max-threads> Maximum Threads
--max-threads <max-threads> Maximum Threads.
--help | -h This help screen.
--verbose | -v Verbose output.
--batch Never ask for user input, use the default behaviour.
--no-color Do not use colors in the output.
#### WPSCAN EXAMPLES
Do 'non-intrusive' checks...
@@ -216,7 +239,7 @@ Use custom content directory...
```ruby wpscan.rb -u www.example.com --wp-content-dir custom-content```
Update WPScan...
Update WPScan's databases...
```ruby wpscan.rb --update```
@@ -226,38 +249,45 @@ Debug output...
#### WPSTOOLS ARGUMENTS
--help | -h This help screen.
--Verbose | -v Verbose output.
--update | -u Update to the latest revision.
--generate_plugin_list [number of pages] Generate a new data/plugins.txt file. (supply number of *pages* to parse, default : 150)
--gpl Alias for --generate_plugin_list
--check-local-vulnerable-files | --clvf <local directory> Perform a recursive scan in the <local directory> to find vulnerable files or shells
-v, --verbose Verbose output
--check-vuln-ref-urls, --cvru Check all the vulnerabilities reference urls for 404
--check-local-vulnerable-files, --clvf LOCAL_DIRECTORY Perform a recursive scan in the LOCAL_DIRECTORY to find vulnerable files or shells
--generate-plugin-list, --gpl [NUMBER_OF_ITEMS] Generate a new data/plugins.txt file. (supply number of *items* to parse, default : 1500)
--generate-full-plugin-list, --gfpl Generate a new full data/plugins.txt file
--generate-theme-list, --gtl [NUMBER_OF_ITEMS] Generate a new data/themes.txt file. (supply number of *items* to parse, default : 200)
--generate-full-theme-list, --gftl Generate a new full data/themes.txt file
--generate-all, --ga Generate a new full plugins, full themes, popular plugins and popular themes list
-s, --stats Show WpScan Database statistics.
--spellcheck, --sc Check all files for common spelling mistakes.
#### WPSTOOLS EXAMPLES
Generate a new 'most popular' plugin list, up to 150 pages...
Generate a new 'most popular' plugin list, up to 1500 items...
```ruby wpstools.rb --generate_plugin_list 150```
```ruby wpstools.rb --generate-plugin-list 1500```
Locally scan a wordpress installation for vulnerable files or shells:
Locally scan a wordpress installation for vulnerable files or shells :
```ruby wpstools.rb --check-local-vulnerable-files /var/www/wordpress/```
Or check [pyfiscan](https://github.com/fgeek/pyfiscan) project.
#### PROJECT HOME
www.wpscan.org
[http://www.wpscan.org](http://www.wpscan.org)
#### GIT REPOSITORY
https://github.com/wpscanteam/wpscan
[https://github.com/wpscanteam/wpscan](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
http://rdoc.info/github/wpscanteam/wpscan/frames
[http://rdoc.info/github/wpscanteam/wpscan/frames](http://rdoc.info/github/wpscanteam/wpscan/frames)
#### SPONSOR

BIN
data.zip Normal file

Binary file not shown.

2
data/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Only he following extensions are scanned : js, php, swf, html, htm
If you want to add one, modify the variable file_extension_to_scan, line 191 in wpstools.rb
-->
<hashes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="local_vulnerable_files.xsd">
<hash sha1="17c372678aafb3bc1a7b37320b5cc1d8af433527">
<title>XSS in swfupload.swf</title>
<file>swfupload.swf</file>
<reference>http://brindi.si/g/blog/vulnerable-swf-bundled-in-wordpress-plugins.html</reference>
</hash>
<hash sha1="775dc1089829ef07838406def28a4d8bfef69d66">
<title>Arbitrary File Upload Vulnerability</title>
<file>php.php</file>
<reference>http://packetstormsecurity.com/files/119241/wpvalums-shell.txt</reference>
</hash>
<!-- This one a is the same as above, but the postSize verification has been removed -->
<hash sha1="5e8f0d5a917d2937318a9bafd0529135bd473e70">
<title>Arbitrary File Upload Vulnerability</title>
<file>php.php</file>
<reference>http://packetstormsecurity.com/files/119218/wpreflexgallery-shell.txt</reference>
</hash>
<hash sha1="3f9ad05b05b65ee2b6efa1373f708293dd2005c7">
<title>Arbitrary File Upload Vulnerability</title>
<file>uploadify.php</file>
<reference>http://packetstormsecurity.com/files/119219/wpuploader104-shell.txt</reference>
</hash>
<hash sha1="ac638cc38f011b74a8d9a4e7d3d60358e472166c">
<title>Inline phpinfo()</title>
<file>phpinfo.php</file>
<reference>http://php.net/manual/en/function.phpinfo.php</reference>
</hash>
<hash sha1="012ee25cceff745e681fbb3697a06f3712f55554">
<title>phpinfo()</title>
<file>phpinfo.php</file>
<reference>http://php.net/manual/en/function.phpinfo.php</reference>
</hash>
</hashes>

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve" />
<xs:minLength value="1" />
<xs:pattern value="[^\s].+[^\s]|[^\s]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="uritype">
<xs:restriction base="xs:anyURI">
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="sha1type">
<xs:restriction base="stringtype">
<xs:pattern value="[0-9a-f]{40}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="hashtype">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="title" type="stringtype"/>
<xs:element name="file" type="stringtype"/>
<xs:element name="reference" type="uritype"/>
</xs:sequence>
<xs:attribute type="sha1type" name="sha1" use="required"/>
</xs:complexType>
<xs:element name="hashes">
<xs:complexType>
<xs:sequence>
<xs:element name="hash" type="hashtype" maxOccurs="unbounded" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -1,3 +0,0 @@
http://.*\.rr\.nu
http://www\.thesea\.org/media\.php

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,298 +0,0 @@
aadya
abaris
adamos
adaptive-flat
adelle
admired
adventure
advertica-lite
albinomouse
aldehyde
alexandria
analytical-lite
anarcho-notepad
apprise
arcade-basic
arunachala
aspen
asteria-lite
asteroid
atahualpa
attitude
base-wp
beach
bearded
big-city
bizantine
bizark
bizflare
bizkit
biznez-lite
bizsphere
bizstudio-lite
bizway
blackbird
blankslate
blogbox
blogolife
blox
bluegray
boldr-lite
boot-store
bootstrap-ultimate
bouquet
bresponzive
brightnews
bueno
business-lite
busiprof
buzz
capture
catch-box
catch-everest
catch-evolution
catch-kathmandu
celestial-lite
chaostheory
childishly-simple
church
cirrus
clean-retina
cleo
coller
colorway
contango
coraline
corpo
custom-community
customizr
cyberchimps
dark-tt
dazzling
decode
designfolio
desk-mess-mirrored
destro
discover
dms
drop
duena
dusk-to-dawn
duster
dw-minion
dw-timeline
dw-wallpress
eclipse
elegantwhite
elmax
engrave-lite
epic
esell
esplanade
esquire
evolve
expert
expound
family
fifteen
fine
firmasite
flat
focus
forever
formation
fresh-lite
frontier
fruitful
gamepress
gold
govpress
graphene
graphy
gridbulletin
gridiculous
gridster-lite
hatch
hazen
health-center-lite
hemingway
highwind
hueman
i-transform
iconic-one
ifeature
imprint
independent-publisher
infinite
infoway
inkness
inkzine
intuition
invert-lite
irex-lite
iribbon
isis
itek
justwrite
kavya
klasik
leatherdiary
lingonberry
linia-magazine
luminescence-lite
lupercalia
magazine-style
magazino
mantra
market
match
matheson
max-magazine
maxflat-core
meadowhill
mesocolumn
mh-magazine-lite
midnightcity
minimatica
minimize
mn-flow
modern-estate
monaco
montezuma
multiloquent
mywiki
neuro
newgamer
newpro
next-saturday
nictitate
omega
one-page
onetone
openstrap
opulus-sombre
origami
origin
oxygen
p2
padhang
pagelines
parabola
parallax
parament
phonix
pilcrow
pilot-fish
pinbin
pinboard
pink-touch-2
platform
point
portfolio-press
pr-news
preference-lite
preus
primo-lite
promax
quark
radiant
radiate
raindrops
rambo
raptor
raven
redesign
responsive
restaurante
restaurateur
restimpo
retention
reviewgine-affiliate
ridizain
sampression-lite
semper-fi-lite
sensitive
sequel
serene
shopping
simple-catch
simply-vision
singl
sixteen
skt-full-width
sliding-door
smpl-skeleton
snaps
snapshot
sneak-lite
socialize-lite
spacious
spartan
spasalon
sporty
spun
stairway
stargazer
start-point
steira
storefront-paper
story
suevafree
suffusion
sugar-and-spice
sundance
sunny-blue-sky
sunrain
sunspot
superhero
supernova
surfarama
swift-basic
tanzanite
teal
tempera
temptation
terrifico
the-newswire
thematic
theron-lite
tiga
timeturner
tiny-forge
tonal
tonic
travelify
twentyeleven
twentyfourteen
twentyten
twentythirteen
twentytwelve
typal-makewp005
unite
untitled
uu-2014
vantage
venom
viper
virtue
vision
visitpress
visual
vryn-restaurant
ward
weaver-ii
wilson
wp-creativix
wp-opulus
wp-simple
wpchimp-countdown
writr
x2
yoko
zbench
zeedynamic
zeeflow
zeeminty
zeenoble
zeestyle
zeetasty

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +0,0 @@
# Windows
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.27 (KHTML, like Gecko) Chrome/12.0.712.0 Safari/534.27
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.24 Safari/535.1
Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0E)
Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.1) Gecko/20100101 Firefox/10.0.1
Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20120427 Firefox/15.0a1
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0)
Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
# MAC
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.15 Safari/534.13
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418.8 (KHTML, like Gecko) Safari/419.3
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2; rv:10.0.1) Gecko/20100101 Firefox/10.0.1
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10
# Linux
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.20 Safari/535.1
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100915 Gentoo Firefox/3.6.9
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.16) Gecko/20120421 Gecko Firefox/11.0
Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0
Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00
Mozilla/5.0 (X11; U; Linux x86_64; us; rv:1.9.1.19) Gecko/20110430 shadowfox/7.0 (like Firefox/7.0

View File

@@ -1,109 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve" />
<xs:minLength value="1" />
<xs:pattern value="[^\s].+[^\s]|[^\s]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger" />
</xs:simpleType>
<xs:simpleType name="uritype">
<xs:restriction base="xs:anyURI">
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="cvetype">
<xs:restriction base="xs:token">
<xs:pattern value="[0-9]{4}-[0-9]{4,}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typetype">
<xs:restriction base="stringtype">
<xs:enumeration value="SQLI"/>
<xs:enumeration value="MULTI"/>
<xs:enumeration value="REDIRECT"/>
<xs:enumeration value="RCE"/>
<xs:enumeration value="RFI"/>
<xs:enumeration value="LFI"/>
<xs:enumeration value="UPLOAD"/>
<xs:enumeration value="UNKNOWN"/>
<xs:enumeration value="XSS"/>
<xs:enumeration value="CSRF"/>
<xs:enumeration value="SSRF"/>
<xs:enumeration value="AUTHBYPASS"/>
<xs:enumeration value="BYPASS"/>
<xs:enumeration value="FPD"/>
<xs:enumeration value="XXE"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="itemtype">
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="vulnerability" type="vulntype" />
</xs:sequence>
<xs:attribute type="stringtype" name="name" use="required"/>
</xs:complexType>
<xs:complexType name="wordpresstype">
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="vulnerability" type="vulntype"/>
</xs:sequence>
<xs:attribute type="stringtype" name="version" use="required"/>
</xs:complexType>
<xs:complexType name="vulntype">
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:choice>
<xs:element name="title" type="stringtype"/>
<xs:element name="type" type="typetype"/>
<xs:element name="fixed_in" type="stringtype"/>
<xs:element name="references" type="referencetype"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="referencetype">
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:choice>
<xs:element name="url" type="uritype" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="cve" type="cvetype" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="secunia" type="inttype" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="osvdb" type="inttype" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="metasploit" type="stringtype" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="exploitdb" type="inttype" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:element name="vulnerabilities">
<xs:complexType>
<xs:choice>
<xs:element name="plugin" type="itemtype" maxOccurs="unbounded" minOccurs="0"/>
<xs:element name="theme" type="itemtype" maxOccurs="unbounded" minOccurs="0"/>
<xs:element name="wordpress" type="wordpresstype" maxOccurs="unbounded" minOccurs="0"/>
</xs:choice>
</xs:complexType>
<xs:unique name="uniquePlugin">
<xs:selector xpath="plugin"/>
<xs:field xpath="@name"/>
</xs:unique>
<xs:unique name="uniqueTheme">
<xs:selector xpath="theme"/>
<xs:field xpath="@name"/>
</xs:unique>
<xs:unique name="uniqueWordpress">
<xs:selector xpath="wordpress"/>
<xs:field xpath="@version"/>
</xs:unique>
</xs:element>
</xs:schema>

View File

@@ -1,218 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file contains identification data to identify WordPress versions.
http://wordpress.org/download/release-archive/
Position is important, DO NOT change anything unless you know what you are doing :p
-->
<wp-versions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="wp_versions.xsd">
<file src="readme.html">
<hash md5="84b54c54aa48ae72e633685c17e67457">
<version>3.9</version>
</hash>
<hash md5="c6de8fc70a18be7e5c36198cd0f99a64">
<version>3.8.3</version>
</hash>
<hash md5="e01a2663475f6a7a8363a7c75a73fe23">
<version>3.8.2</version>
</hash>
<hash md5="0d0eb101038124a108f608d419387b92">
<version>3.8.1</version>
</hash>
<hash md5="38ee273095b8f25b9ffd5ce5018fc4f0">
<version>3.8</version>
</hash>
<hash md5="813e06052daa0692036e60d76d7141d3">
<version>3.7.3</version>
</hash>
<hash md5="b3a05c7a344c2f53cb6b680fd65a91e8">
<version>3.7.2</version>
</hash>
<hash md5="e82f4fe7d3c1166afb4c00856b875f16">
<version>3.6.1</version>
</hash>
<hash md5="477f1e652f31dae76a38e3559c91deb9">
<version>3.6</version>
</hash>
<hash md5="caf7946275c3e885419b1d36b22cb5f3">
<version>3.5.2</version>
</hash>
<hash md5="05d50a04ef19bd4b0a280362469bf22f">
<version>3.5.1</version>
</hash>
<hash md5="066cfc0f9b29ae6d491aa342ebfb1b71">
<version>3.5</version>
</hash>
<hash md5="36b2b72a0f22138a921a38db890d18c1">
<version>3.3.3</version>
</hash>
<hash md5="628419c327ca5ed8685ae3af6f753eb8">
<version>3.3.2</version>
</hash>
<hash md5="c1ed266e26a829b772362d5135966bc3">
<version>3.3.1</version>
</hash>
<hash md5="9ea06ab0184049bf4ea2410bf51ce402">
<version>3.0</version>
</hash>
</file>
<file src="wp-includes/css/buttons-rtl.css">
<hash md5="d24d1d1eb3a4b9a4998e4df1761f8b9e">
<version>3.9</version>
</hash>
<hash md5="71c13ab1693b45fb3d7712e540c4dfe0">
<version>3.8</version>
</hash>
</file>
<file src="wp-includes/js/tinymce/wp-tinymce.js.gz">
<!-- Note: 3.7.1 has no unique file (the hash below is the same than the 3.7.2) -->
<hash md5="44d281b0d84cc494e2b095a6d2202f4d">
<version>3.7.1</version>
</hash>
<hash md5="b0bcf8091516db358ee9c833afd73175">
<version>3.7</version>
</hash>
<hash md5="cf4bbd562430a9bcbe735062be851be1">
<version>3.6.1</version>
</hash>
<hash md5="42ce18e88f1c21d4e991fcd431bcb606">
<version>3.6</version>
</hash>
<hash md5="a58dd12608659503cf087e879e720354">
<version>3.5.2</version>
</hash>
<hash md5="55c80a4794624ce9b94aa3631ad46c0b">
<version>3.5.1</version>
</hash>
<hash md5="8e529a971610d7ebe7851339c5cb3d67">
<version>3.5</version>
</hash>
<hash md5="ff19e44be975f89b647274d85b70f821">
<version>3.4.2</version>
</hash>
</file>
<file src="wp-admin/js/customize-controls.js">
<hash md5="aa0d38bd6f590ad8c3126074145b1bf1">
<version>3.4.1</version>
</hash>
</file>
<file src="wp-includes/js/customize-preview.js">
<hash md5="da36bc2dfcb13350c799b62de68dfa4b">
<version>3.4</version>
</hash>
</file>
<file src="wp-includes/js/plupload/plupload.js">
<hash md5="85199c05db63fcb5880de4af8be7b571">
<version>3.3.2</version>
</hash>
</file>
<file src="wp-admin/js/common.js">
<hash md5="4516252d47a73630280869994d510180">
<version>3.3</version>
</hash>
</file>
<file src="wp-admin/js/wp-fullscreen.js">
<hash md5="5675f7793f171b6424bf72f9d7bf4d9a">
<version>3.2.1</version>
</hash>
<hash md5="7b423e0b7c9221092737ad5271d09863">
<version>3.2</version>
</hash>
</file>
<file src="wp-includes/css/admin-bar.css">
<hash md5="181250fab3a7e2549a7e7fa21c2e6079">
<version>3.1</version>
</hash>
</file>
<file src="$wp-content$/themes/twentyten/style.css">
<hash md5="6211e2ac1463bf99e98f28ab63e47c54">
<version>3.0</version>
</hash>
</file>
<file src="$wp-plugins$/akismet/readme.txt">
<hash md5="4d5e52da417aa0101054bd41e6243389">
<version>2.8.6</version>
</hash>
<hash md5="58e086dea9d24ed074fe84ba87386c69">
<version>2.8.5</version>
</hash>
<hash md5="48c52025b5f28731e9a0c864c189c2e7">
<version>2.8.2</version>
</hash>
</file>
<file src="wp-includes/js/wp-ajax-response.js">
<hash md5="0289d1c13821599764774d55516ab81a">
<version>2.7.1</version>
</hash>
</file>
<file src="wp-includes/js/thickbox/thickbox.css">
<hash md5="9c2bd2be0893adbe02a0f864526734c2">
<version>2.7</version>
</hash>
</file>
<file src="wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.js">
<hash md5="5b140ddf0f08034402ae78b31d8a1a28">
<version>2.6</version>
</hash>
</file>
<file src="wp-includes/js/tinymce/themes/advanced/js/image.js">
<hash md5="088245408531c58bb52cc092294cc384">
<version>2.5.1</version>
</hash>
</file>
<file src="wp-includes/js/tinymce/themes/advanced/js/link.js">
<hash md5="19c6f3118728c38eb7779aab4847d2d9">
<version>2.5</version>
</hash>
</file>
<file src="wp-includes/js/wp-ajax.js">
<hash md5="c5dbce0c3232c477033e0ce486c62755">
<version>2.2</version>
</hash>
</file>
<file src="$wp-content$/themes/default/style.css">
<hash md5="e44545f529a54de88209ce588676231c">
<version>2.0.1</version>
</hash>
<hash md5="f786f66d3a40846aa22dcdfeb44fa562">
<version>2.0</version>
</hash>
</file>
<file src="wp-layout.css">
<hash md5="7140e06c00ed03d2bb3dad7672557510">
<version>1.2.1</version>
</hash>
<hash md5="1bcc9253506c067eb130c9fc4f211a2f">
<version>1.2-delta</version>
</hash>
</file>
<file src="layout2b.css">
<hash md5="baec6b6ccbf71d8dced9f1bf67c751e1">
<version>0.71-gold</version>
</hash>
</file>
</wp-versions>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve" />
<xs:minLength value="1" />
<xs:pattern value="[^\s].+[^\s]|[^\s]"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="filetype">
<xs:sequence>
<xs:element name="hash" type="hashtype" maxOccurs="unbounded" minOccurs="1"/>
</xs:sequence>
<xs:attribute type="stringtype" name="src" use="required"/>
</xs:complexType>
<xs:simpleType name="md5type">
<xs:restriction base="stringtype">
<xs:pattern value="[0-9a-f]{32}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="hashtype">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="version" type="stringtype"/>
</xs:sequence>
<xs:attribute type="md5type" name="md5" use="required"/>
</xs:complexType>
<xs:element name="wp-versions">
<xs:complexType>
<xs:sequence>
<xs:element name="file" type="filetype" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
# ln -sf /Users/xxx/wpscan/dev/pre-commit-hook.rb /Users/xxx/wpscan/.git/hooks/pre-commit
# from the top level dir:
# ln -sf ../../dev/pre-commit-hook.rb .git/hooks/pre-commit
require 'pty'
html_path = 'rspec_results.html'

View File

@@ -16,14 +16,15 @@ class Browser
:proxy,
:proxy_auth,
:request_timeout,
:connect_timeout
:connect_timeout,
:cookie
]
@@instance = nil
attr_reader :hydra, :cache_dir
attr_accessor :referer
attr_accessor :referer, :cookie
# @param [ Hash ] options
#
@@ -153,6 +154,7 @@ class Browser
params.merge!(cookiejar: @cache_dir + '/cookie-jar')
params.merge!(cookiefile: @cache_dir + '/cookie-jar')
params.merge!(cookie: @cookie) if @cookie
params
end

View File

@@ -18,7 +18,7 @@ class CacheFileStore
# YAML is Human Readable, contrary to Marshal which store in a binary format
# Marshal does not need any "require"
def initialize(storage_path, serializer = Marshal)
@storage_path = File.expand_path(storage_path + '/' + storage_dir)
@storage_path = File.expand_path(File.join(storage_path, storage_dir))
@serializer = serializer
# File.directory? for ruby <= 1.9 otherwise,
@@ -35,11 +35,9 @@ class CacheFileStore
end
def read_entry(key)
entry_file_path = get_entry_file_path(key)
if File.exists?(entry_file_path)
return @serializer.load(File.read(entry_file_path))
end
@serializer.load(File.read(get_entry_file_path(key)))
rescue
nil
end
def write_entry(key, data_to_store, cache_ttl)

View File

@@ -80,13 +80,31 @@ class WpItems < Array
#
# @return [ WpItems ]
def passive_detection(wp_target, options = {})
results = new(wp_target)
body = Browser.get(wp_target.url).body
results = new(wp_target)
# improves speed
body = remove_base64_images_from_html(body)
names = body.scan(passive_detection_pattern(wp_target))
body = remove_base64_images_from_html(Browser.get(wp_target.url).body)
page = Nokogiri::HTML(body)
names = []
names.flatten.uniq.each { |name| results.add(name) }
page.css('link,script,style').each do |tag|
%w(href src).each do |attribute|
attr_value = tag.attribute(attribute).to_s
next unless attr_value
names << Regexp.last_match[1] if attr_value.match(attribute_pattern(wp_target))
end
next unless tag.name == 'script' || tag.name == 'style'
code = tag.text.to_s
next if code.empty?
code.scan(code_pattern(wp_target)).flatten.uniq.each do |item_name|
names << item_name
end
end
names.uniq.each { |name| results.add(name) }
results.sort!
results
@@ -97,13 +115,29 @@ class WpItems < Array
# @param [ WpTarget ] wp_target
#
# @return [ Regex ]
def passive_detection_pattern(wp_target)
type = self.to_s.gsub(/Wp/, '').downcase
regex1 = %r{(?:[^=:\(]+)\s?(?:=|:|\()\s?(?:"|')[^"']+\\?/}
regex2 = %r{\\?/}
regex3 = %r{\\?/([^/\\"']+)\\?(?:/|"|')}
def item_pattern(wp_target)
type = to_s.gsub(/Wp/, '').downcase
wp_content_dir = wp_target.wp_content_dir
wp_content_url = wp_target.uri.merge(wp_content_dir).to_s
/#{regex1}#{Regexp.escape(wp_target.wp_content_dir)}#{regex2}#{Regexp.escape(type)}#{regex3}/i
url = /#{wp_content_url.gsub(%r{\A(?:http|https)}, 'https?').gsub('/', '\\\\\?\/')}/i
content_dir = %r{(?:#{url}|\\?\/\\?\/?#{wp_content_dir})}i
%r{#{content_dir}\\?/#{type}\\?/}
end
# @param [ WpTarget ] wp_target
#
# @return [ Regex ]
def attribute_pattern(wp_target)
/\A#{item_pattern(wp_target)}([^\/]+)/i
end
# @param [ WpTarget ] wp_target
#
# @return [ Regex ]
def code_pattern(wp_target)
/["'\(]#{item_pattern(wp_target)}([^\\\/\)"']+)/i
end
# The default request parameters
@@ -142,16 +176,17 @@ class WpItems < Array
# @return [ Array<WpItem> ]
def vulnerable_targets_items(wp_target, item_class, vulns_file)
targets = []
xml = xml(vulns_file)
json = json(vulns_file)
xml.xpath(item_xpath).each do |node|
[*json].each do |item|
targets << create_item(
item_class,
node.attribute('name').text,
item.keys.inject,
wp_target,
vulns_file
)
end
targets
end
@@ -190,6 +225,7 @@ class WpItems < Array
)
end
end
targets
end

View File

@@ -9,9 +9,9 @@ class WpPlugins < WpItems
end
# @return [ String ]
def item_xpath
'//plugin'
end
# def item_xpath
# '//plugin'
# end
# @param [ WpTarget ] wp_target
# @param [ Hash ] options
@@ -68,6 +68,10 @@ class WpPlugins < WpItems
wp_plugins.add('all-in-one-seo-pack', version: $1)
end
if body =~ /<!-- This site is optimized with the Yoast WordPress SEO plugin v([^\s]+) -/i
wp_plugins.add('wordpress-seo', version: $1)
end
wp_plugins
end

View File

@@ -9,9 +9,9 @@ class WpThemes < WpItems
end
# @return [ String ]
def item_xpath
'//theme'
end
# def item_xpath
# '//theme'
# end
end
end

View File

@@ -1,40 +1,40 @@
# encoding: UTF-8
LIB_DIR = File.expand_path(File.dirname(__FILE__) + '/..')
ROOT_DIR = File.expand_path(LIB_DIR + '/..') # expand_path is used to get "wpscan/" instead of "wpscan/lib/../"
DATA_DIR = ROOT_DIR + '/data'
CONF_DIR = ROOT_DIR + '/conf'
CACHE_DIR = ROOT_DIR + '/cache'
WPSCAN_LIB_DIR = LIB_DIR + '/wpscan'
WPSTOOLS_LIB_DIR = LIB_DIR + '/wpstools'
UPDATER_LIB_DIR = LIB_DIR + '/updater'
COMMON_LIB_DIR = LIB_DIR + '/common'
MODELS_LIB_DIR = COMMON_LIB_DIR + '/models'
COLLECTIONS_LIB_DIR = COMMON_LIB_DIR + '/collections'
LIB_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..'))
ROOT_DIR = File.expand_path(File.join(LIB_DIR, '..')) # expand_path is used to get "wpscan/" instead of "wpscan/lib/../"
DATA_DIR = File.join(ROOT_DIR, 'data')
CONF_DIR = File.join(ROOT_DIR, 'conf')
CACHE_DIR = File.join(ROOT_DIR, 'cache')
WPSCAN_LIB_DIR = File.join(LIB_DIR, 'wpscan')
WPSTOOLS_LIB_DIR = File.join(LIB_DIR, 'wpstools')
UPDATER_LIB_DIR = File.join(LIB_DIR, 'updater')
COMMON_LIB_DIR = File.join(LIB_DIR, 'common')
MODELS_LIB_DIR = File.join(COMMON_LIB_DIR, 'models')
COLLECTIONS_LIB_DIR = File.join(COMMON_LIB_DIR, 'collections')
LOG_FILE = ROOT_DIR + '/log.txt'
LOG_FILE = File.join(ROOT_DIR, 'log.txt')
# Plugins directories
COMMON_PLUGINS_DIR = COMMON_LIB_DIR + '/plugins'
WPSCAN_PLUGINS_DIR = WPSCAN_LIB_DIR + '/plugins' # Not used ATM
WPSTOOLS_PLUGINS_DIR = WPSTOOLS_LIB_DIR + '/plugins'
COMMON_PLUGINS_DIR = File.join(COMMON_LIB_DIR, 'plugins')
WPSCAN_PLUGINS_DIR = File.join(WPSCAN_LIB_DIR, 'plugins') # Not used ATM
WPSTOOLS_PLUGINS_DIR = File.join(WPSTOOLS_LIB_DIR, 'plugins')
# Data files
PLUGINS_FILE = DATA_DIR + '/plugins.txt'
PLUGINS_FULL_FILE = DATA_DIR + '/plugins_full.txt'
PLUGINS_VULNS_FILE = DATA_DIR + '/plugin_vulns.xml'
THEMES_FILE = DATA_DIR + '/themes.txt'
THEMES_FULL_FILE = DATA_DIR + '/themes_full.txt'
THEMES_VULNS_FILE = DATA_DIR + '/theme_vulns.xml'
WP_VULNS_FILE = DATA_DIR + '/wp_vulns.xml'
WP_VERSIONS_FILE = DATA_DIR + '/wp_versions.xml'
LOCAL_FILES_FILE = DATA_DIR + '/local_vulnerable_files.xml'
VULNS_XSD = DATA_DIR + '/vuln.xsd'
WP_VERSIONS_XSD = DATA_DIR + '/wp_versions.xsd'
LOCAL_FILES_XSD = DATA_DIR + '/local_vulnerable_files.xsd'
USER_AGENTS_FILE = DATA_DIR + '/user-agents.txt'
PLUGINS_FILE = File.join(DATA_DIR, 'plugins.txt')
PLUGINS_FULL_FILE = File.join(DATA_DIR, 'plugins_full.txt')
PLUGINS_VULNS_FILE = File.join(DATA_DIR, 'plugin_vulns.json')
THEMES_FILE = File.join(DATA_DIR, 'themes.txt')
THEMES_FULL_FILE = File.join(DATA_DIR, 'themes_full.txt')
THEMES_VULNS_FILE = File.join(DATA_DIR, 'theme_vulns.json')
WP_VULNS_FILE = File.join(DATA_DIR, 'wp_vulns.json')
WP_VERSIONS_FILE = File.join(DATA_DIR, 'wp_versions.xml')
LOCAL_FILES_FILE = File.join(DATA_DIR, 'local_vulnerable_files.xml')
# VULNS_XSD = File.join(DATA_DIR, 'vuln.xsd')
WP_VERSIONS_XSD = File.join(DATA_DIR, 'wp_versions.xsd')
LOCAL_FILES_XSD = File.join(DATA_DIR, 'local_vulnerable_files.xsd')
USER_AGENTS_FILE = File.join(DATA_DIR, 'user-agents.txt')
WPSCAN_VERSION = '2.4'
WPSCAN_VERSION = '2.5'
$LOAD_PATH.unshift(LIB_DIR)
$LOAD_PATH.unshift(WPSCAN_LIB_DIR)
@@ -54,7 +54,7 @@ require 'environment'
def require_files_from_directory(absolute_dir_path, files_pattern = '*.rb')
files = Dir[File.join(absolute_dir_path, files_pattern)]
# Files in the root dir are loaded first, then thoses in the subdirectories
# Files in the root dir are loaded first, then those in the subdirectories
files.sort_by { |file| [file.count("/"), file] }.each do |f|
f = File.expand_path(f)
#puts "require #{f}" # Used for debug
@@ -64,14 +64,6 @@ end
require_files_from_directory(COMMON_LIB_DIR, '**/*.rb')
# Hook to check if the target if down during the scan
# The target is considered down after 10 requests with status = 0
down = 0
Typhoeus.on_complete do |response|
down += 1 if response.code == 0
fail 'The target seems to be down' if down >= 10
end
# Add protocol
def add_http_protocol(url)
url =~ /^https?:/ ? url : "http://#{url}"
@@ -81,18 +73,56 @@ def add_trailing_slash(url)
url =~ /\/$/ ? url : "#{url}/"
end
# loading the updater
require_files_from_directory(UPDATER_LIB_DIR)
@updater = UpdaterFactory.get_updater(ROOT_DIR)
if @updater
REVISION = @updater.local_revision_number()
else
REVISION = nil
def missing_db_file?
DbUpdater::FILES.each do |db_file|
return true unless File.exist?(File.join(DATA_DIR, db_file))
end
false
end
def version
REVISION ? "v#{WPSCAN_VERSION}r#{REVISION}" : "v#{WPSCAN_VERSION}"
# Define colors
def colorize(text, color_code)
if $COLORSWITCH
"#{text}"
else
"\e[#{color_code}m#{text}\e[0m"
end
end
def bold(text)
colorize(text, 1)
end
def red(text)
colorize(text, 31)
end
def green(text)
colorize(text, 32)
end
def amber(text)
colorize(text, 33)
end
def blue(text)
colorize(text, 34)
end
def critical(text)
red(text)
end
def warning(text)
amber(text)
end
def info(text)
green(text)
end
def notice(text)
blue(text)
end
# our 1337 banner
@@ -106,36 +136,30 @@ def banner
puts ' \\/ \\/ |_| |_____/ \\___|\\__,_|_| |_|'
puts
puts ' WordPress Security Scanner by the WPScan Team '
# Alignment of the version (w & w/o the Revision)
if REVISION
puts " Version #{version}"
else
puts " Version #{version}"
end
puts " Version #{WPSCAN_VERSION}"
puts ' Sponsored by the RandomStorm Open Source Initiative'
puts ' @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_'
puts '_______________________________________________________________'
puts
end
def colorize(text, color_code)
"\e[#{color_code}m#{text}\e[0m"
end
def red(text)
colorize(text, 31)
end
def green(text)
colorize(text, 32)
end
def xml(file)
Nokogiri::XML(File.open(file)) do |config|
config.noblanks
end
end
def json(file)
content = File.open(file).read
begin
JSON.parse(content)
rescue => e
puts "[ERROR] In JSON file parsing #{file} #{e}"
raise
end
end
def redefine_constant(constant, value)
Object.send(:remove_const, constant)
Object.const_set(constant, value)
@@ -212,3 +236,10 @@ def get_random_user_agent
# return ransom user-agent
user_agents.sample
end
# Directory listing enabled on url?
#
# @return [ Boolean ]
def directory_listing_enabled?(url)
Browser.get(url.to_s).body[%r{<title>Index of}] ? true : false
end

115
lib/common/db_updater.rb Normal file
View File

@@ -0,0 +1,115 @@
# encoding: UTF-8
# DB Updater
class DbUpdater
FILES = %w(
local_vulnerable_files.xml local_vulnerable_files.xsd malwares.txt
plugins_full.txt plugins.txt themes_full.txt themes.txt
timthumbs.txt user-agents.txt wp_versions.xml wp_versions.xsd
plugin_vulns.json theme_vulns.json wp_vulns.json
)
attr_reader :repo_directory
def initialize(repo_directory)
@repo_directory = repo_directory
fail "#{repo_directory} is not writable" unless \
Pathname.new(repo_directory).writable?
end
# @return [ Hash ] The params for Typhoeus::Request
def request_params
{
ssl_verifyhost: 2,
ssl_verifypeer: true
}
end
# @return [ String ] The raw file URL associated with the given filename
def remote_file_url(filename)
"https://raw.githubusercontent.com/wpscanteam/vulndb/master/#{filename}"
end
# @return [ String ] The checksum of the associated remote filename
def remote_file_checksum(filename)
url = "#{remote_file_url(filename)}.sha512"
res = Browser.get(url, request_params)
fail "Unable to get #{url}" unless res.code == 200
res.body
end
def local_file_path(filename)
File.join(repo_directory, "#{filename}")
end
def local_file_checksum(filename)
Digest::SHA512.file(local_file_path(filename)).hexdigest
end
def backup_file_path(filename)
File.join(repo_directory, "#{filename}.back")
end
def create_backup(filename)
return unless File.exist?(local_file_path(filename))
FileUtils.cp(local_file_path(filename), backup_file_path(filename))
end
def restore_backup(filename)
return unless File.exist?(backup_file_path(filename))
FileUtils.cp(backup_file_path(filename), local_file_path(filename))
end
def delete_backup(filename)
FileUtils.rm(backup_file_path(filename))
end
# @return [ String ] The checksum of the downloaded file
def download(filename)
file_path = local_file_path(filename)
file_url = remote_file_url(filename)
res = Browser.get(file_url, request_params)
fail "Error while downloading #{file_url}" unless res.code == 200
File.write(file_path, res.body)
local_file_checksum(filename)
end
def update(verbose = false)
FILES.each do |filename|
begin
puts "[+] Checking #{filename}" if verbose
db_checksum = remote_file_checksum(filename)
# Checking if the file needs to be updated
if File.exist?(local_file_path(filename)) && db_checksum == local_file_checksum(filename)
puts ' [i] Already Up-To-Date' if verbose
next
end
puts ' [i] Needs to be updated' if verbose
create_backup(filename)
puts ' [i] Backup Created' if verbose
puts ' [i] Downloading new file' if verbose
dl_checksum = download(filename)
puts " [i] Downloaded File Checksum: #{dl_checksum}" if verbose
unless dl_checksum == db_checksum
fail "#{filename}: checksums do not match"
end
rescue => e
puts ' [i] Restoring Backup due to error' if verbose
restore_backup(filename)
raise e
ensure
if File.exist?(backup_file_path(filename))
puts ' [i] Deleting Backup' if verbose
delete_backup(filename)
end
end
end
end
end

View File

@@ -51,7 +51,7 @@ end
def puts(o = '')
# remove color for logging
if o.respond_to?(:gsub)
temp = o.gsub(/\e\[\d+m(.*)?\e\[0m/, '\1')
temp = o.gsub(/\e\[\d+m/, '')
File.open(LOG_FILE, 'a+') { |f| f.puts(temp) }
end
super(o)

View File

@@ -35,27 +35,26 @@ class Vulnerability
end
# :nocov:
# Create the Vulnerability from the xml_node
# Create the Vulnerability from the json_item
#
# @param [ Nokogiri::XML::Node ] xml_node
# @param [ Hash ] json_item
#
# @return [ Vulnerability ]
def self.load_from_xml_node(xml_node)
def self.load_from_json_item(json_item)
references = {}
refs = xml_node.search('references')
if refs
references[:url] = refs.search('url').map(&:text)
references[:cve] = refs.search('cve').map(&:text)
references[:secunia] = refs.search('secunia').map(&:text)
references[:osvdb] = refs.search('osvdb').map(&:text)
references[:metasploit] = refs.search('metasploit').map(&:text)
references[:exploitdb] = refs.search('exploitdb').map(&:text)
%w(id url cve secunia osvdb metasploit exploitdb).each do |key|
if json_item[key]
json_item[key] = [json_item[key]] if json_item[key].class != Array
references[key] = json_item[key]
end
end
new(
xml_node.search('title').text,
xml_node.search('type').text,
json_item['title'],
json_item['type'],
references,
xml_node.search('fixed_in').text,
json_item['fixed_in'],
)
end

View File

@@ -5,17 +5,17 @@ class Vulnerability
# output the vulnerability
def output(verbose = false)
puts ' |'
puts ' | ' + red("* Title: #{title}")
puts
puts "#{critical('[!]')} Title: #{title}"
references.each do |key, urls|
methodname = "url_#{key}"
urls.each do |u|
url = send(methodname, u)
puts ' | ' + red("* Reference: #{url}") if url
puts " Reference: #{url}" if url
end
end
if !fixed_in.empty?
puts " | * Fixed in: #{fixed_in}"
if !fixed_in.nil?
puts "#{notice('[i]')} Fixed in: #{fixed_in}"
end
end
end

View File

@@ -6,7 +6,7 @@ class Vulnerability
def url_metasploit(module_path)
# remove leading slash
module_path = module_path.sub(/^\//, '')
"http://www.metasploit.com/modules/#{module_path}"
"http://www.rapid7.com/db/modules/#{module_path}"
end
def url_url(url)
@@ -22,12 +22,15 @@ class Vulnerability
end
def url_secunia(id)
"http://secunia.com/advisories/#{id}"
"https://secunia.com/advisories/#{id}"
end
def url_exploitdb(id)
"http://www.exploit-db.com/exploits/#{id}/"
end
def url_id(id)
"https://wpvulndb.com/vulnerability/#{id}"
end
end
end

View File

@@ -40,7 +40,7 @@ class WpItem
# @return [ Boolean ]
def has_directory_listing?
Browser.get(@uri.to_s).body[%r{<title>Index of}] ? true : false
directory_listing_enabled?(@uri)
end
# Discover any error_log files created by WordPress

View File

@@ -6,16 +6,21 @@ class WpItem
# @return [ Void ]
def output(verbose = false)
puts
puts " | Name: #{self}" #this will also output the version number if detected
puts " | Location: #{url}"
puts "#{info('[+]')} Name: #{self}" #this will also output the version number if detected
puts " | Location: #{url}"
#puts " | WordPress: #{wordpress_url}" if wordpress_org_item?
puts " | Readme: #{readme_url}" if has_readme?
puts " | Changelog: #{changelog_url}" if has_changelog?
puts " | " + red('[!]') + " Directory listing is enabled: #{url}" if has_directory_listing?
puts " | " + red('[!]') + " An error_log file has been found: #{error_log_url}" if has_error_log?
puts " | Readme: #{readme_url}" if has_readme?
puts " | Changelog: #{changelog_url}" if has_changelog?
puts "#{warning('[!]')} Directory listing is enabled: #{url}" if has_directory_listing?
puts "#{warning('[!]')} An error_log file has been found: #{error_log_url}" if has_error_log?
additional_output(verbose) if respond_to?(:additional_output)
if version.nil? && vulnerabilities.length > 0
puts
puts "#{warning('[+]')} We could not determine a version so all vulnerabilities are printed out"
end
vulnerabilities.output
end
end

View File

@@ -2,22 +2,27 @@
class WpItem
module Vulnerable
attr_accessor :vulns_file, :vulns_xpath
attr_accessor :vulns_file, :identifier
# Get the vulnerabilities associated to the WpItem
# Filters out already fixed vulnerabilities
#
# @return [ Vulnerabilities ]
def vulnerabilities
xml = xml(vulns_file)
json = json(vulns_file)
vulnerabilities = Vulnerabilities.new
xml.xpath(vulns_xpath).each do |node|
vuln = Vulnerability.load_from_xml_node(node)
if vulnerable_to?(vuln)
vulnerabilities << vuln
json.each do |item|
asset = item[identifier]
if asset
asset['vulnerabilities'].each do |vulnerability|
vulnerability = Vulnerability.load_from_json_item(vulnerability)
vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
end
end
end
vulnerabilities
end
@@ -32,7 +37,7 @@ class WpItem
# @return [ Boolean ]
def vulnerable_to?(vuln)
if version && vuln && vuln.fixed_in && !vuln.fixed_in.empty?
unless VersionCompare::is_newer_or_same?(vuln.fixed_in, version)
unless VersionCompare::lesser_or_equal?(vuln.fixed_in, version)
return true
end
else
@@ -41,5 +46,4 @@ class WpItem
return false
end
end
end

View File

@@ -12,8 +12,8 @@ class WpPlugin < WpItem
end
# @return [ String ]
def vulns_xpath
"//plugin[@name='#{@name}']/vulnerability"
def identifier
@name
end
end

View File

@@ -15,15 +15,9 @@ class WpTheme < WpItem
include WpTheme::Output
include WpTheme::Childtheme
attr_writer :style_url
attr_accessor :referenced_url
def allowed_options; super << :style_url end
def initialize(*args)
super(*args)
parse_style
end
def allowed_options; super << :referenced_url end
# Sets the @uri
#
@@ -36,10 +30,7 @@ class WpTheme < WpItem
# @return [ String ] The url to the theme stylesheet
def style_url
unless @style_url
@style_url = uri.merge('style.css').to_s
end
@style_url
@uri.merge('style.css').to_s
end
end

View File

@@ -30,13 +30,13 @@ class WpTheme < WpItem
response = Browser.get_and_follow_location(target_uri.to_s)
# https + domain is optional because of relative links
matches = %r{(?:https?://[^"']+)?/([^/]+)/themes/([^"']+)/style.css}i.match(response.body)
matches = /(?:https?:\/\/[^"']+)?\/([^\/]+)\/themes\/([^"'\/]+)[^"']*\/style.css/i.match(response.body)
if matches
return new(
target_uri,
{
name: matches[2],
style_url: matches[0],
referenced_url: matches[0],
wp_content_dir: matches[1]
}
)

View File

@@ -5,18 +5,21 @@ class WpTheme
# @return [ Void ]
def additional_output(verbose = false)
puts " | Style URL: #{style_url}"
puts " | Theme Name: #@theme_name" if @theme_name
puts " | Theme URI: #@theme_uri" if @theme_uri
parse_style
theme_desc = verbose ? @theme_description : truncate(@theme_description, 100)
puts " | Description: #{theme_desc}"
puts " | Author: #@theme_author" if @theme_author
puts " | Author URI: #@theme_author_uri" if @theme_author_uri
puts " | Template: #@theme_template" if @theme_template and verbose
puts " | License: #@theme_license" if @theme_license and verbose
puts " | License URI: #@theme_license_uri" if @theme_license_uri and verbose
puts " | Tags: #@theme_tags" if @theme_tags and verbose
puts " | Text Domain: #@theme_text_domain" if @theme_text_domain and verbose
puts " | Style 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 URI: #@theme_uri" if @theme_uri
puts " | Description: #{theme_desc}"
puts " | Author: #@theme_author" if @theme_author
puts " | Author URI: #@theme_author_uri" if @theme_author_uri
puts " | Template: #@theme_template" if @theme_template and verbose
puts " | License: #@theme_license" if @theme_license and verbose
puts " | License URI: #@theme_license_uri" if @theme_license_uri and verbose
puts " | Tags: #@theme_tags" if @theme_tags and verbose
puts " | Text Domain: #@theme_text_domain" if @theme_text_domain and verbose
end
end

View File

@@ -12,9 +12,8 @@ class WpTheme < WpItem
end
# @return [ String ]
def vulns_xpath
"//theme[@name='#{@name}']/vulnerability"
def identifier
@name
end
end
end

View File

@@ -4,7 +4,10 @@ class WpTimthumb < WpItem
module Output
def output(verbose = false)
puts " | #{vulnerable? ? red('[!] Vulnerable') : green('[i] Not Vulnerable')} #{self}"
puts
puts "#{info('[+]')} #{self}" #this will also output the version number if detected
vulnerabilities.output
end
end

View File

@@ -2,8 +2,54 @@
class WpTimthumb < WpItem
module Vulnerable
def vulnerable?
VersionCompare.is_newer_or_same?(version, '1.34')
# @return [ Vulnerabilities ]
def vulnerabilities
vulns = Vulnerabilities.new
[:check_rce_132, :check_rce_webshot].each do |method|
vuln = self.send(method)
vulns << vuln if vuln
end
vulns
end
def check_rce_132
return rce_132_vuln unless VersionCompare.lesser_or_equal?('1.33', version)
end
# Vulnerable versions : > 1.35 (or >= 2.0) and < 2.8.14
def check_rce_webshot
return if VersionCompare.lesser_or_equal?('2.8.14', version) || VersionCompare.lesser_or_equal?(version, '1.35')
response = Browser.get(uri.merge('?webshot=1&src=http://' + default_allowed_domains.sample))
return rce_webshot_vuln unless response.body =~ /WEBSHOT_ENABLED == true/
end
# @return [ Array<String> ] The default allowed domains (between the 2.0 and 2.8.13)
def default_allowed_domains
%w(flickr.com picasa.com img.youtube.com upload.wikimedia.org)
end
# @return [ Vulnerability ] The RCE in the <= 1.32
def rce_132_vuln
Vulnerability.new(
'Timthumb <= 1.32 Remote Code Execution',
'RCE',
{ exploitdb: ['17602'] },
'1.33'
)
end
# @return [ Vulnerability ] The RCE due to the WebShot in the <= 2.8.13
def rce_webshot_vuln
Vulnerability.new(
'Timthumb <= 2.8.13 WebShot Remote Code Execution',
'RCE',
{ url: ['http://seclists.org/fulldisclosure/2014/Jun/117'] },
'2.8.14'
)
end
end
end

View File

@@ -29,7 +29,7 @@ class WpUser < WpItem
File.open(wordlist).each do |password|
password.chop!
# A successfull login will redirect us to the redirect_to parameter
# Generate a random one on each request
unless redirect_url
@@ -103,19 +103,19 @@ class WpUser < WpItem
# @return [ Boolean ]
def valid_password?(response, password, redirect_url, options = {})
if response.code == 302 && response.headers_hash && response.headers_hash['Location'] == redirect_url
progression = "#{green('[SUCCESS]')} Login : #{login} Password : #{password}\n\n"
progression = "#{info('[SUCCESS]')} Login : #{login} Password : #{password}\n\n"
valid = true
elsif response.body =~ /login_error/i
verbose = "\n Incorrect login and/or password."
elsif response.timed_out?
progression = "#{red('ERROR:')} Request timed out."
progression = "#{critical('ERROR:')} Request timed out."
elsif response.code == 0
progression = "#{red('ERROR:')} No response from remote server. WAF/IPS?"
progression = "#{critical('ERROR:')} No response from remote server. WAF/IPS?"
elsif response.code.to_s =~ /^50/
progression = "#{red('ERROR:')} Server error, try reducing the number of threads."
progression = "#{critical('ERROR:')} Server error, try reducing the number of threads."
else
progression = "#{red('ERROR:')} We received an unknown response for #{password}..."
verbose = red(" Code: #{response.code}\n Body: #{response.body}\n")
progression = "#{critical('ERROR:')} We received an unknown response for #{password}..."
verbose = critical(" Code: #{response.code}\n Body: #{response.body}\n")
end
puts "\n " + progression if progression && options[:show_progression]

View File

@@ -22,6 +22,8 @@ class WpUser < WpItem
if response.code == 301 # login in location?
location = response.headers_hash['Location']
return if location.nil? || location.empty?
@login = Existable.login_from_author_pattern(location)
@display_name = Existable.display_name_from_body(
Browser.get(location).body
@@ -66,9 +68,12 @@ class WpUser < WpItem
title_tag.force_encoding('UTF-8') if title_tag.encoding == Encoding::ASCII_8BIT
title_tag = Nokogiri::HTML::DocumentFragment.parse(title_tag).to_s
# &amp; are not decoded with Nokogiri
title_tag.sub!('&amp;', '&')
title_tag.gsub!('&amp;', '&')
name = title_tag[%r{([^|«]+) }, 1]
# replace UTF chars like &#187; with dummy character
title_tag.gsub!(/&#(\d+);/, '|')
name = title_tag[%r{([^|«»]+) }, 1]
return name.strip if name
end

View File

@@ -5,12 +5,12 @@ class WpVersion < WpItem
def output(verbose = false)
puts
puts green('[+]') + " WordPress version #{self.number} identified from #{self.found_from}"
puts "#{info('[+]')} WordPress version #{self.number} identified from #{self.found_from}"
vulnerabilities = self.vulnerabilities
unless vulnerabilities.empty?
puts red('[!]') + " #{vulnerabilities.size} vulnerabilities identified from the version number"
puts "#{critical('[!]')} #{vulnerabilities.size} vulnerabilities identified from the version number"
vulnerabilities.output
end

View File

@@ -12,9 +12,14 @@ class WpVersion < WpItem
end
# @return [ String ]
def vulns_xpath
"//wordpress[@version='#{@number}']/vulnerability"
end
def identifier
@number
end
# @return [ String ]
# def vulns_xpath
# "//wordpress[@version='#{@number}']/vulnerability"
# end
end
end

View File

@@ -1,37 +0,0 @@
# encoding: UTF-8
require 'common/updater/updater'
class GitUpdater < Updater
def is_installed?
%x[git #{repo_directory_arguments()} status 2>&1] =~ /On branch/ ? true : false
end
# Git has not a revsion number like SVN,
# so we will take the 7 first chars of the last commit hash
def local_revision_number
git_log = %x[git #{repo_directory_arguments()} log -1 2>&1]
git_log[/commit ([0-9a-z]{7})/i, 1].to_s
end
def update
%x[git #{repo_directory_arguments()} pull]
end
def has_local_changes?
%x[git #{repo_directory_arguments()} diff --exit-code 2>&1] =~ /diff/ ? true : false
end
def reset_head
%x[git #{repo_directory_arguments()} reset --hard HEAD]
end
protected
def repo_directory_arguments
if @repo_directory
return "--git-dir=\"#{@repo_directory}/.git\" --work-tree=\"#{@repo_directory}\""
end
end
end

View File

@@ -1,23 +0,0 @@
# encoding: UTF-8
require 'common/updater/updater'
class SvnUpdater < Updater
REVISION_PATTERN = /revision="(\d+)"/i
TRUNK_URL = 'https://github.com/wpscanteam/wpscan'
def is_installed?
%x[svn info "#@repo_directory" --xml 2>&1] =~ /revision=/ ? true : false
end
def local_revision_number
local_revision = %x[svn info "#@repo_directory" --xml 2>&1]
local_revision[REVISION_PATTERN, 1].to_s
end
def update
%x[svn up "#@repo_directory"]
end
end

View File

@@ -1,25 +0,0 @@
# encoding: UTF-8
# This class act as an absract one
class Updater
attr_reader :repo_directory
# TODO : add a last '/ to repo_directory if it's not present
def initialize(repo_directory = nil)
@repo_directory = repo_directory
end
def is_installed?
raise NotImplementedError
end
def local_revision_number
raise NotImplementedError
end
def update
raise NotImplementedError
end
end

View File

@@ -1,23 +0,0 @@
# encoding: UTF-8
class UpdaterFactory
def self.get_updater(repo_directory)
self.available_updaters_classes().each do |updater_symbol|
updater = Object.const_get(updater_symbol).new(repo_directory)
if updater.is_installed?
return updater
end
end
nil
end
protected
# return array of class symbols
def self.available_updaters_classes
Object.constants.grep(/^.+Updater$/)
end
end

View File

@@ -2,14 +2,18 @@
class VersionCompare
# Compares two version strings. Returns true if version1 is equal to version2
# or when version1 is older than version2
# Compares two version strings. Returns true if version1 <= version2
# and false otherwise
#
# @param [ String ] version1
# @param [ String ] version2
#
# @return [ Boolean ]
def self.is_newer_or_same?(version1, version2)
def self.lesser_or_equal?(version1, version2)
# Prepend a '0' if the version starts with a '.'
version1 = "0#{version1}" if version1 && version1[0,1] == '.'
version2 = "0#{version2}" if version2 && version2[0,1] == '.'
return true if (version1 == version2)
# Both versions must be set
return false unless (version1 and version2)

View File

@@ -28,6 +28,7 @@ begin
require 'pp'
require 'shellwords'
require 'fileutils'
require 'pathname'
# Third party libs
require 'typhoeus'
require 'json'

View File

@@ -52,8 +52,12 @@ class WebSite
url ||= @uri.to_s
response = Browser.get(url)
redirected_uri = URI.parse(add_trailing_slash(add_http_protocol(url)))
if response.code == 301 || response.code == 302
redirection = response.headers_hash['location']
if redirection[0] == '/'
redirection = "#{redirected_uri.scheme}://#{redirected_uri.host}#{redirection}"
end
# Let's check if there is a redirection in the redirection
if other_redirection = redirection(redirection)

View File

@@ -12,9 +12,7 @@ class WebSite
# Gets a robots.txt URL
# @return [ String ]
def robots_url
temp = @uri.clone
temp.path = '/robots.txt'
temp.to_s
@uri.clone.merge('robots.txt').to_s
end

View File

@@ -5,6 +5,7 @@ require 'wp_target/malwares'
require 'wp_target/wp_readme'
require 'wp_target/wp_registrable'
require 'wp_target/wp_config_backup'
require 'wp_target/wp_must_use_plugins'
require 'wp_target/wp_login_protection'
require 'wp_target/wp_custom_directories'
require 'wp_target/wp_full_path_disclosure'
@@ -14,6 +15,7 @@ class WpTarget < WebSite
include WpTarget::WpReadme
include WpTarget::WpRegistrable
include WpTarget::WpConfigBackup
include WpTarget::WpMustUsePlugins
include WpTarget::WpLoginProtection
include WpTarget::WpCustomDirectories
include WpTarget::WpFullPathDisclosure
@@ -28,7 +30,6 @@ class WpTarget < WebSite
@wp_plugins_dir = options[:wp_plugins_dir]
@multisite = nil
Browser.instance(options.merge(:max_threads => options[:threads]))
Browser.instance.referer = url
end
@@ -122,7 +123,12 @@ class WpTarget < WebSite
# @return [ String ]
def debug_log_url
@uri.merge("#{wp_content_dir()}/debug.log").to_s
@uri.merge("#{wp_content_dir}/debug.log").to_s
end
# @return [ String ]
def upload_dir_url
@uri.merge("#{wp_content_dir}/uploads/").to_s
end
# Script for replacing strings in wordpress databases
@@ -139,4 +145,8 @@ class WpTarget < WebSite
resp = Browser.get(search_replace_db_2_url)
resp.code == 200 && resp.body[%r{by interconnect}i]
end
def upload_directory_listing_enabled?
directory_listing_enabled?(upload_dir_url)
end
end

View File

@@ -40,9 +40,9 @@ class WpTarget < WebSite
# @return [ Array ]
def self.config_backup_files
%w{
wp-config.php~ #wp-config.php# wp-config.php.save wp-config.php.swp wp-config.php.swo wp-config.php_bak
wp-config.bak wp-config.php.bak wp-config.save wp-config.old wp-config.php.old wp-config.php.orig
wp-config.orig wp-config.php.original wp-config.original wp-config.txt
wp-config.php~ #wp-config.php# wp-config.php.save .wp-config.php.swp wp-config.php.swp wp-config.php.swo
wp-config.php_bak wp-config.bak wp-config.php.bak wp-config.save wp-config.old wp-config.php.old
wp-config.php.orig wp-config.orig wp-config.php.original wp-config.original wp-config.txt
} # thanks to Feross.org for these
end

View File

@@ -0,0 +1,26 @@
# encoding: UTF-8
class WpTarget < WebSite
module WpMustUsePlugins
# Checks to see if the must use plugin folder exists
#
# @return [ Boolean ]
def has_must_use_plugins?
response = Browser.get(must_use_url)
if response && WpTarget.valid_response_codes.include?(response.code)
hash = WebSite.page_hash(response.body)
return true if hash != error_404_hash && hash != homepage_hash
end
false
end
# @return [ String ] The must use plugins directory URL
def must_use_url
@uri.merge("#{wp_content_dir}/mu-plugins/").to_s
end
end
end

View File

@@ -46,7 +46,7 @@ def usage
puts '-Use custom plugins directory ...'
puts "ruby #{script_name} -u www.example.com --wp-plugins-dir wp-content/custom-plugins"
puts
puts '-Update ...'
puts '-Update the DB ...'
puts "ruby #{script_name} --update"
puts
puts '-Debug output ...'
@@ -60,13 +60,12 @@ end
def help
puts 'Help :'
puts
puts 'Some values are settable in conf/browser.conf.json :'
puts ' user-agent, proxy, proxy-auth, threads, cache timeout and request timeout'
puts 'Some values are settable in a config file, see the example.conf.json'
puts
puts '--update Update to the latest revision'
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 '--enumerate | -e [option(s)] Enumeration.'
puts '--update Update to the database to the latest version.'
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 '--enumerate | -e [option(s)] Enumeration.'
puts ' option :'
puts ' u usernames from id 1 to 10'
puts ' u[10-20] usernames from id 10 to 20 (you must write [] chars)'
@@ -80,27 +79,40 @@ def help
puts ' Multiple values are allowed : "-e tt,p" will enumerate timthumbs and plugins'
puts ' If no option is supplied, the default is "vt,tt,u,vp"'
puts
puts '--exclude-content-based "<regexp or string>" Used with the enumeration option, will exclude all occurrences based on the regexp or string supplied'
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'
puts '--user-agent | -a <User-Agent> Use the specified 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 '--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'
puts '--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'
puts '--proxy <[protocol://]host:port> Supply a proxy (will override the one from conf/browser.conf.json).'
puts ' HTTP, SOCKS4 SOCKS4A and SOCKS5 are supported. If no protocol is given (format host:port), HTTP will be used'
puts '--proxy-auth <username:password> Supply the proxy login credentials (will override the one from conf/browser.conf.json).'
puts '--basic-auth <username:password> Set the HTTP Basic authentication'
puts '--wordlist | -w <wordlist> Supply a wordlist for the password bruter and do the brute.'
puts '--threads | -t <number of threads> The number of threads to use when multi-threading requests. (will override the value from conf/browser.conf.json)'
puts '--username | -U <username> Only brute force the supplied username.'
puts '--cache-ttl <cache-ttl> Typhoeus cache TTL'
puts '--request-timeout <request-timeout> Request Timeout'
puts '--connect-timeout <connect-timeout> Connect Timeout'
puts '--max-threads <max-threads> Maximum Threads'
puts '--help | -h This help screen.'
puts '--verbose | -v Verbose output.'
puts '--batch Never ask for user input, use the default behaviour.'
puts '--exclude-content-based "<regexp or string>"'
puts ' Used with the enumeration option, will exclude all occurrences based on the regexp or string supplied.'
puts ' You do not need to provide the regexp delimiters, but you must write the quotes (simple or double).'
puts '--config-file | -c <config file> Use the specified config file, see the example.conf.json.'
puts '--user-agent | -a <User-Agent> Use the specified User-Agent.'
puts '--cookie <String> String to read cookies from.'
puts '--random-agent | -r Use a random User-Agent.'
puts '--follow-redirection If the target url has a redirection, it will be followed without asking if you wanted to do so or not'
puts '--batch Never ask for user input, use the default behaviour.'
puts '--no-color Do not use colors in the output.'
puts '--wp-content-dir <wp content dir> WPScan try to find the content directory (ie wp-content) by scanning the index page, however you can specified it.'
puts ' Subdirectories are allowed.'
puts '--wp-plugins-dir <wp plugins dir> Same thing than --wp-content-dir but for the plugins directory.'
puts ' If not supplied, WPScan will use wp-content-dir/plugins. Subdirectories are allowed'
puts '--proxy <[protocol://]host:port> Supply a proxy. HTTP, SOCKS4 SOCKS4A and SOCKS5 are supported.'
puts ' If no protocol is given (format host:port), HTTP will be used.'
puts '--proxy-auth <username:password> Supply the proxy login credentials.'
puts '--basic-auth <username:password> Set the HTTP Basic authentication.'
puts '--wordlist | -w <wordlist> Supply a wordlist for the password bruter and do the brute.'
puts '--username | -U <username> Only brute force the supplied username.'
puts '--threads | -t <number of threads> The number of threads to use when multi-threading requests.'
puts '--cache-ttl <cache-ttl> Typhoeus cache TTL.'
puts '--request-timeout <request-timeout> Request Timeout.'
puts '--connect-timeout <connect-timeout> Connect Timeout.'
puts '--max-threads <max-threads> Maximum Threads.'
puts '--help | -h This help screen.'
puts '--verbose | -v Verbose output.'
puts
end
# Hook to check if the target if down during the scan
# The target is considered down after 10 requests with status = 0
down = 0
Typhoeus.on_complete do |response|
down += 1 if response.code == 0
fail 'The target seems to be down' if down >= 10
end

View File

@@ -13,6 +13,7 @@ class WpscanOptions
:enumerate_timthumbs,
:enumerate_usernames,
:enumerate_usernames_range,
:no_color,
:proxy,
:proxy_auth,
:threads,
@@ -28,6 +29,7 @@ class WpscanOptions
:wp_plugins_dir,
:help,
:config_file,
:cookie,
:exclude_content_based,
:basic_auth,
:debug_output,
@@ -257,7 +259,9 @@ class WpscanOptions
['--request-timeout', GetoptLong::REQUIRED_ARGUMENT],
['--connect-timeout', GetoptLong::REQUIRED_ARGUMENT],
['--max-threads', GetoptLong::REQUIRED_ARGUMENT],
['--batch', GetoptLong::NO_ARGUMENT]
['--batch', GetoptLong::NO_ARGUMENT],
['--no-color', GetoptLong::NO_ARGUMENT],
['--cookie', GetoptLong::REQUIRED_ARGUMENT]
)
end

View File

@@ -29,11 +29,18 @@ class CheckerPlugin < Plugin
puts '[+] Checking vulnerabilities reference urls'
vuln_ref_files.each do |vuln_ref_file|
xml = xml(vuln_ref_file)
json = json(vuln_ref_file)
urls = []
xml.xpath('//references/url').each { |node| urls << node.text }
json.each do |asset|
asset[asset.keys.inject]['vulnerabilities'].each do |url|
unless url['url'].nil?
url['url'].split(',').each do |url|
urls << url
end
end
end
end
urls.uniq!
puts "[!] No URLs found in #{vuln_ref_file}!" if urls.empty?
@@ -75,17 +82,19 @@ class CheckerPlugin < Plugin
end
def check_local_vulnerable_files(dir_to_scan)
if Dir::exist?(dir_to_scan)
if Dir.exist?(dir_to_scan)
xml_file = LOCAL_FILES_FILE
local_hashes = {}
file_extension_to_scan = '*.{js,php,swf,html,htm}'
print '[+] Generating local hashes ... '
Dir[File::join(dir_to_scan, '**', file_extension_to_scan)].each do |filename|
Dir[File.join(dir_to_scan, '**', file_extension_to_scan)]
.select { |f| File.file?(f) }
.each do |filename|
sha1sum = Digest::SHA1.file(filename).hexdigest
if local_hashes.has_key?(sha1sum)
if local_hashes.key?(sha1sum)
local_hashes[sha1sum] << filename
else
local_hashes[sha1sum] = [filename]

View File

@@ -1,104 +0,0 @@
# encoding: UTF-8
# This tool generates a list to use for plugin and theme enumeration
class GenerateList
attr_accessor :verbose
# type = themes | plugins
def initialize(type, verbose)
if type =~ /plugins/i
@type = 'plugin'
@svn_url = 'http://plugins.svn.wordpress.org/'
@popular_url = 'http://wordpress.org/plugins/browse/popular/'
@popular_regex = %r{<h3><a href="http://wordpress.org/plugins/([^/]+)/">.+</a></h3>}i
elsif type =~ /themes/i
@type = 'theme'
@svn_url = 'http://themes.svn.wordpress.org/'
@popular_url = 'http://wordpress.org/themes/browse/popular/'
@popular_regex = %r{<h3><a href="http://wordpress.org/themes/([^/]+)">.+</a></h3>}i
else
raise "Type #{type} not defined"
end
@verbose = verbose
@browser = Browser.instance(request_timeout: 20000, connect_timeout: 20000, max_threads: 1, cache_ttl: 0)
end
def set_file_name(type)
case @type
when 'plugin'
case type
when :full
@file_name = PLUGINS_FULL_FILE
when :popular
@file_name = PLUGINS_FILE
else
raise 'Unknown type'
end
when 'theme'
case type
when :full
@file_name = THEMES_FULL_FILE
when :popular
@file_name = THEMES_FILE
else
raise 'Unknown type'
end
else
raise "Unknown type #@type"
end
end
def generate_full_list
set_file_name(:full)
items = SvnParser.new(@svn_url).parse
save items
end
def generate_popular_list(pages)
set_file_name(:popular)
items = get_popular_items(pages)
save items
end
# Send a HTTP request to the WordPress most popular theme or plugin webpage
# parse the response for the names.
def get_popular_items(pages)
found_items = []
page_count = 1
(1...(pages.to_i + 1)).each do |page|
# First page has another URL
url = (page == 1) ? @popular_url : @popular_url + 'page/' + page.to_s + '/'
puts "[+] Parsing page #{page_count}" if @verbose
code = 0
while code != 200
puts red("[!] Retrying request for page #{page} (Code: #{code})") unless code == 0
request = @browser.forge_request(url)
response = request.run
code = response.code
sleep(5) unless code == 200
end
page_count += 1
found = 0
response.body.scan(@popular_regex).each do |item|
found_items << item[0]
found = found + 1
end
puts "[+] Found #{found} items on page #{page}" if @verbose
end
found_items.sort!
found_items.uniq
end
# Save the file
def save(items)
items.sort!
items.uniq!
puts "[*] We have parsed #{items.length} #{@type}s"
File.open(@file_name, 'w') { |f| f.puts(items) }
puts "New #@file_name file created"
end
end

View File

@@ -1,53 +0,0 @@
# encoding: UTF-8
class ListGeneratorPlugin < Plugin
def initialize
super(author: 'WPScanTeam - @FireFart')
register_options(
['--generate-plugin-list [NUMBER_OF_PAGES]', '--gpl', Integer, 'Generate a new data/plugins.txt file. (supply number of *pages* to parse, default : 150)'],
['--generate-full-plugin-list', '--gfpl', 'Generate a new full data/plugins.txt file'],
['--generate-theme-list [NUMBER_OF_PAGES]', '--gtl', Integer, 'Generate a new data/themes.txt file. (supply number of *pages* to parse, default : 20)'],
['--generate-full-theme-list', '--gftl', 'Generate a new full data/themes.txt file'],
['--generate-all', '--ga', 'Generate a new full plugins, full themes, popular plugins and popular themes list']
)
end
def run(options = {})
@verbose = options[:verbose] || false
generate_all = options[:generate_all] || false
if options.has_key?(:generate_plugin_list) || generate_all
most_popular('plugin', options[:generate_plugin_list] || 150)
end
if options[:generate_full_plugin_list] || generate_all
full('plugin')
end
if options.has_key?(:generate_theme_list) || generate_all
most_popular('theme', options[:generate_theme_list] || 20)
end
if options[:generate_full_theme_list] || generate_all
full('theme')
end
end
private
def most_popular(type, number_of_pages)
puts "[+] Generating new most popular #{type} list"
puts
GenerateList.new(type + 's', @verbose).generate_popular_list(number_of_pages)
end
def full(type)
puts "[+] Generating new full #{type} list"
puts
GenerateList.new(type + 's', @verbose).generate_full_list
end
end

View File

@@ -1,31 +0,0 @@
# encoding: UTF-8
# This Class Parses SVN Repositories via HTTP
class SvnParser
attr_accessor :verbose, :svn_root, :keep_empty_dirs
def initialize(svn_root)
@svn_root = svn_root
end
def parse
get_root_directories
end
#Private methods start here
private
# Gets all directories in the SVN root
def get_root_directories
dirs = []
rootindex = Browser.get(@svn_root).body
rootindex.scan(%r{<li><a href=".+">(.+)/</a></li>}i).each do |dir|
dirs << dir[0]
end
dirs.sort!
dirs.uniq
end
end

View File

@@ -6,7 +6,7 @@ class StatsPlugin < Plugin
super(author: 'WPScanTeam - Christian Mehlmauer')
register_options(
['--stats', '--s', 'Show WpScan Database statistics']
['--stats', '-s', 'Show WpScan Database statistics.']
)
end
@@ -26,8 +26,13 @@ class StatsPlugin < Plugin
puts "[#] Total vulnerable themes: #{vuln_theme_count}"
puts
puts "[#] Total version vulnerabilities: #{version_vulns_count}"
puts "[#] Total fixed vulnerabilities: #{fix_version_count}"
puts
puts "[#] Total plugin vulnerabilities: #{plugin_vulns_count}"
puts "[#] Total fixed vulnerabilities: #{fix_plugin_count}"
puts
puts "[#] Total theme vulnerabilities: #{theme_vulns_count}"
puts "[#] Total fixed vulnerabilities: #{fix_theme_count}"
puts
puts "[#] Total plugins to enumerate: #{total_plugins}"
puts "[#] Total themes to enumerate: #{total_themes}"
@@ -43,27 +48,39 @@ class StatsPlugin < Plugin
end
def vuln_core_count(file=WP_VULNS_FILE)
xml(file).xpath('count(//wordpress)').to_i
json(file).size
end
def vuln_plugin_count(file=PLUGINS_VULNS_FILE)
xml(file).xpath('count(//plugin)').to_i
json(file).size
end
def vuln_theme_count(file=THEMES_VULNS_FILE)
xml(file).xpath('count(//theme)').to_i
json(file).size
end
def version_vulns_count(file=WP_VULNS_FILE)
xml(file).xpath('count(//vulnerability)').to_i
asset_vulns_count(json(file))
end
def fix_version_count(file=WP_VULNS_FILE)
asset_fixed_in_count(json(file))
end
def plugin_vulns_count(file=PLUGINS_VULNS_FILE)
xml(file).xpath('count(//vulnerability)').to_i
asset_vulns_count(json(file))
end
def fix_plugin_count(file=PLUGINS_VULNS_FILE)
asset_fixed_in_count(json(file))
end
def theme_vulns_count(file=THEMES_VULNS_FILE)
xml(file).xpath('count(//vulnerability)').to_i
asset_vulns_count(json(file))
end
def fix_theme_count(file=THEMES_VULNS_FILE)
asset_fixed_in_count(json(file))
end
def total_plugins(file=PLUGINS_FULL_FILE)
@@ -78,4 +95,12 @@ class StatsPlugin < Plugin
IO.readlines(file).size
end
def asset_vulns_count(json)
json.map { |asset| asset[asset.keys.inject]['vulnerabilities'].size }.inject(:+)
end
def asset_fixed_in_count(json)
json.map { |asset| asset[asset.keys.inject]['vulnerabilities'].map {|a| a['fixed_in'].nil? ? 0 : 1 }.inject(:+) }.inject(:+)
end
end

View File

@@ -12,21 +12,6 @@ def usage
puts
puts 'Examples:'
puts
puts "- Generate a new 'most popular' plugin list, up to 150 pages ..."
puts "ruby #{script_name} --generate-plugin-list 150"
puts
puts '- Generate a new full plugin list'
puts "ruby #{script_name} --generate-full-plugin-list"
puts
puts "- Generate a new 'most popular' theme list, up to 150 pages ..."
puts "ruby #{script_name} --generate-theme-list 150"
puts
puts '- Generate a new full theme list'
puts "ruby #{script_name} --generate-full-theme-list"
puts
puts '- Generate all list'
puts "ruby #{script_name} --generate-all"
puts
puts 'Locally scan a wordpress installation for vulnerable files or shells'
puts "ruby #{script_name} --check-local-vulnerable-files /var/www/wordpress/"
puts

View File

@@ -25,7 +25,7 @@ describe Browser do
json_expected_vars['max_threads'] ||= 20 # max_thread can not be nil
instance_vars_to_check.each do |variable_name|
browser.send(:"#{variable_name}").should === json_expected_vars[variable_name]
expect(browser.send(:"#{variable_name}")).to be === json_expected_vars[variable_name]
end
end
@@ -50,7 +50,7 @@ describe Browser do
let(:cache_dir) { CACHE_DIR + '/somewhere' }
let(:options) { { cache_dir: cache_dir } }
after { subject.cache_dir.should == cache_dir }
after { expect(subject.cache_dir).to eq cache_dir }
it 'sets @cache_dir' do
@json_expected_vars = json_config_without_proxy
@@ -84,11 +84,11 @@ describe Browser do
describe '::append_params_header_field' do
after :each do
Browser.append_params_header_field(
expect(Browser.append_params_header_field(
@params,
@field,
@field_value
).should === @expected
)).to be === @expected
end
context 'when there is no headers' do
@@ -140,7 +140,7 @@ describe Browser do
browser.user_agent = 'SomeUA'
browser.cache_ttl = 250
browser.merge_request_params(params).should == @expected
expect(browser.merge_request_params(params)).to eq @expected
end
it 'sets the User-Agent header field and cache_ttl' do
@@ -190,18 +190,27 @@ describe Browser do
@expected = default_expectation.merge(params)
end
end
context 'when @cookie' do
let(:cookie) { 'foor=bar;bar=foo' }
before { browser.cookie = cookie }
it 'sets the cookie' do
@expected = default_expectation.merge(cookie: cookie)
end
end
end
describe '#forge_request' do
let(:url) { 'http://example.localhost' }
it 'returns the correct Typhoeus::Request' do
subject.stub(merge_request_params: { cache_ttl: 10 })
allow(subject).to receive_messages(merge_request_params: { cache_ttl: 10 })
request = subject.forge_request(url)
request.should be_a Typhoeus::Request
request.url.should == url
request.cache_ttl.should == 10
expect(request).to be_a Typhoeus::Request
expect(request.url).to eq url
expect(request.cache_ttl).to eq 10
end
end
@@ -216,7 +225,7 @@ describe Browser do
response1 = Browser.get(url)
response2 = Browser.get(url)
response1.body.should == response2.body
expect(response1.body).to eq response2.body
#WebMock.should have_requested(:get, url).times(1) # This one fail, dunno why :s (but it works without mock)
end
end

View File

@@ -17,14 +17,14 @@ describe CacheFileStore do
describe '#storage_path' do
it 'returns the storage path given in the #new' do
@cache.storage_path.should match(/#{cache_dir}/)
expect(@cache.storage_path).to match(/#{cache_dir}/)
end
end
describe '#serializer' do
it 'should return the default serializer : Marshal' do
@cache.serializer.should == Marshal
@cache.serializer.should_not == YAML
expect(@cache.serializer).to eq Marshal
expect(@cache.serializer).not_to eq YAML
end
end
@@ -35,15 +35,31 @@ describe CacheFileStore do
File.new(@cache.storage_path + "/file_#{i}.txt", File::CREAT)
end
count_files_in_dir(@cache.storage_path, 'file_*.txt').should == 6
expect(count_files_in_dir(@cache.storage_path, 'file_*.txt')).to eq 6
@cache.clean
count_files_in_dir(@cache.storage_path).should == 0
expect(count_files_in_dir(@cache.storage_path)).to eq 0
end
end
describe '#read_entry (nonexistent entry)' do
it 'should return nil' do
@cache.read_entry(Digest::SHA1.hexdigest('hello world')).should be_nil
describe '#read_entry' do
after { expect(@cache.read_entry(key)).to eq @expected }
context 'when the entry does not exist' do
let(:key) { Digest::SHA1.hexdigest('hello world') }
it 'should return nil' do
@expected = nil
end
end
context 'when the file exist but is empty (marshal data too short error)' do
let(:key) { 'empty-file' }
it 'returns nil' do
File.new(File.join(@cache.storage_path, key), File::CREAT)
@expected = nil
end
end
end
@@ -51,7 +67,7 @@ describe CacheFileStore do
after :each do
@cache.write_entry(@key, @data, @timeout)
@cache.read_entry(@key).should === @expected
expect(@cache.read_entry(@key)).to be === @expected
end
it 'should get the correct entry (string)' do
@@ -79,7 +95,7 @@ describe CacheFileStore do
storage_dirs << CacheFileStore.new(cache_dir).storage_path
end
storage_dirs.uniq.size.should == 5
expect(storage_dirs.uniq.size).to eq 5
end
end
end

View File

@@ -10,20 +10,15 @@ describe WpItems do
let(:expected) do
{
request_params: { cache_ttl: 0, followlocation: true },
targets_items_from_file: [ WpItem.new(uri, name: 'item1'),
WpItem.new(uri, name:'item-2'),
WpItem.new(uri, name: 'mr-smith')],
request_params: { cache_ttl: 0, followlocation: true },
targets_items_from_file: [ WpItem.new(uri, name: 'item1'),
WpItem.new(uri, name: 'item-2'),
WpItem.new(uri, name: 'mr-smith')],
vulnerable_targets_items: [ WpItem.new(uri, name: 'mr-smith'),
WpItem.new(uri, name: 'neo')],
vulnerable_targets_items: [ WpItem.new(uri, name: 'mr-smith'),
WpItem.new(uri, name: 'neo')],
passive_detection: WpItems.new << WpItem.new(uri, name: 'js-source') <<
WpItem.new(uri, name: 'escaped-url') <<
WpItem.new(uri, name: 'link-tag') <<
WpItem.new(uri, name: 'script-tag') <<
WpItem.new(uri, name: 'style-tag') <<
WpItem.new(uri, name: 'style-tag-import')
passive_detection: (1..13).reduce(WpItems.new) { |o, i| o << WpItem.new(uri, name: "detect-me-#{i}") }
}
end
end

View File

@@ -15,7 +15,7 @@ describe 'WpPlugins::Detectable' do
context 'when no header' do
it 'returns an empty WpPlugins' do
stub_request(:get, url).to_return(status: 200)
subject.send(:from_header, wp_target).should == subject.new
expect(subject.send(:from_header, wp_target)).to eq subject.new
end
end
@@ -25,7 +25,7 @@ describe 'WpPlugins::Detectable' do
after :each do
stub_request(:get, url).to_return(status: 200, headers: headers, body: '')
subject.send(:from_header, wp_target).should == expected
expect(subject.send(:from_header, wp_target)).to eq expected
end
context 'when w3-total-cache detected' do
@@ -66,7 +66,7 @@ describe 'WpPlugins::Detectable' do
context 'when no body' do
it 'returns an empty WpPlugins' do
stub_request(:get, url).to_return(status: 200, body: '')
subject.send(:from_content, wp_target).should == subject.new
expect(subject.send(:from_content, wp_target)).to eq subject.new
end
end
@@ -77,7 +77,7 @@ describe 'WpPlugins::Detectable' do
after :each do
stub_request(:get, url).to_return(status: 200, body: @body)
stub_request(:get, /readme\.txt/i).to_return(status: 404)
subject.send(:from_content, wp_target).should == expected
expect(subject.send(:from_content, wp_target)).to eq expected
end
context 'when w3 total cache detected' do

View File

@@ -19,8 +19,7 @@ describe WpPlugins do
vulnerable_targets_items: [ WpPlugin.new(uri, name: 'mr-smith'),
WpPlugin.new(uri, name: 'neo')],
passive_detection: WpPlugins.new << WpPlugin.new(uri, name: 'js-source') <<
WpPlugin.new(uri, name: 'escaped-url') <<
passive_detection: WpPlugins.new << WpPlugin.new(uri, name: 'escaped-url') <<
WpPlugin.new(uri, name: 'link-tag') <<
WpPlugin.new(uri, name: 'script-tag') <<
WpPlugin.new(uri, name: 'style-tag') <<

View File

@@ -38,7 +38,7 @@ describe 'WpTimthumbs::Detectable' do
describe '::passive_detection' do
it 'returns an empty WpTimthumbs' do
subject.passive_detection(wp_target).should == subject.new
expect(subject.passive_detection(wp_target)).to eq subject.new
end
end
@@ -46,7 +46,7 @@ describe 'WpTimthumbs::Detectable' do
after do
targets = subject.send(:targets_items_from_file, file, wp_target)
targets.map { |t| t.url }.should == @expected.map { |t| t.url }
expect(targets.map { |t| t.url }).to eq @expected.map { |t| t.url }
end
context 'when an empty file' do
@@ -71,7 +71,7 @@ describe 'WpTimthumbs::Detectable' do
theme = 'hello-world'
targets = subject.send(:theme_timthumbs, theme, wp_target)
targets.map { |t| t.url }.should == expected_targets_from_theme(theme).map { |t| t.url }
expect(targets.map { |t| t.url }).to eq expected_targets_from_theme(theme).map { |t| t.url }
end
end
@@ -81,7 +81,7 @@ describe 'WpTimthumbs::Detectable' do
after do
targets = subject.send(:targets_items, wp_target, options)
targets.map { |t| t.url }.should == @expected.sort.map { |t| t.url }
expect(targets.map { |t| t.url }).to eq @expected.sort.map { |t| t.url }
end
context 'when no :theme_name' do

View File

@@ -22,13 +22,13 @@ describe 'WpUsers::Detectable' do
describe '::request_params' do
it 'return an empty Hash' do
subject.request_params.should === {}
expect(subject.request_params).to be === {}
end
end
describe '::passive_detection' do
it 'return an empty WpUsers' do
subject.passive_detection(wp_target).should == subject.new
expect(subject.passive_detection(wp_target)).to eq subject.new
end
end
@@ -36,7 +36,7 @@ describe 'WpUsers::Detectable' do
after do
targets = subject.send(:targets_items, wp_target, options)
targets.should == @expected
expect(targets).to eq @expected
end
context 'when no :range' do

View File

@@ -25,7 +25,7 @@ describe 'WpUsers::Output' do
subject.push(@input)
subject.flatten!
subject.remove_junk_from_display_names
subject.should === @expected
expect(subject).to be === @expected
end
it 'should return an empty array' do

View File

@@ -7,7 +7,7 @@ describe 'common_helper' do
after :each do
output = get_equal_string_end(@input)
output.should == @expected
expect(output).to eq @expected
end
it 'returns an empty string' do
@@ -75,7 +75,7 @@ describe 'common_helper' do
describe '#remove_base64_images_from_html' do
after :each do
output = remove_base64_images_from_html(@html)
output.should == @expected
expect(output).to eq @expected
end
it 'removes the valid base64 image' do
@@ -92,7 +92,7 @@ describe 'common_helper' do
describe '#truncate' do
after :each do
output = truncate(@input, @length, @trailing)
output.should == @expected
expect(output).to eq @expected
end
it 'returns nil on no input' do

View File

@@ -15,7 +15,7 @@ describe CustomOptionParser do
if @exception
expect { CustomOptionParser::option_to_symbol(@option) }.to raise_error(@exception)
else
CustomOptionParser::option_to_symbol(@option).should === @expected
expect(CustomOptionParser::option_to_symbol(@option)).to be === @expected
end
end
@@ -100,7 +100,7 @@ describe CustomOptionParser do
parser.add_option(['-v', '--verbose'])
parser.add_option(['--url TARGET_URL'])
parser.symbols_used.sort.should === [:url, :verbose]
expect(parser.symbols_used.sort).to be === [:url, :verbose]
end
context 'parsing' do
@@ -118,7 +118,7 @@ describe CustomOptionParser do
it 'should retrieve the correct argument' do
parser.parse!(['-u', 'iam_the_target'])
parser.results.should === { url: 'iam_the_target' }
expect(parser.results).to be === { url: 'iam_the_target' }
end
end
end
@@ -134,8 +134,8 @@ describe CustomOptionParser do
context 'single option' do
it 'should add the :url option, and retrieve the correct argument' do
parser.symbols_used.should === [:url]
parser.results(['-u', 'target.com']).should === { url: 'target.com' }
expect(parser.symbols_used).to be === [:url]
expect(parser.results(['-u', 'target.com'])).to be === { url: 'target.com' }
end
end
@@ -146,8 +146,8 @@ describe CustomOptionParser do
['--test [TEST_NUMBER]']
])
parser.symbols_used.sort.should === [:test, :url, :verbose]
parser.results(['-u', 'wp.com', '-v', '--test']).should === { test: nil, url: 'wp.com', verbose: true }
expect(parser.symbols_used.sort).to be === [:test, :url, :verbose]
expect(parser.results(['-u', 'wp.com', '-v', '--test'])).to be === { test: nil, url: 'wp.com', verbose: true }
end
end
end

View File

@@ -13,41 +13,43 @@ describe Vulnerability do
context 'w/o metasploit and fixed version modules argument' do
subject(:vulnerability) { Vulnerability.new(title, type, references) }
its(:title) { should be title }
its(:references) { should be references }
its(:type) { should be type }
its(:fixed_in) { should be_empty }
its(:title) { should be title }
its(:references) { should be references }
its(:type) { should be type }
its(:fixed_in) { should be_empty }
end
context 'with fixed version argument' do
let(:fixed_version) { '1.0' }
its(:title) { should be title }
its(:references) { should be references }
its(:type) { should be type }
its(:fixed_in) { should be fixed_version }
let(:fixed_version) { '1.0' }
its(:title) { should be title }
its(:references) { should be references }
its(:type) { should be type }
its(:fixed_in) { should be fixed_version }
end
end
describe '::load_from_xml_node' do
subject(:vulnerability) { Vulnerability.load_from_xml_node(node) }
let(:node) {
xml(MODELS_FIXTURES + '/vulnerability/xml_node.xml').xpath('//vulnerability')
describe '::load_from_json_item' do
subject(:vulnerability) { Vulnerability.load_from_json_item(item) }
let(:item) {
json(MODELS_FIXTURES + '/vulnerability/json_item.json')
}
expected_refs = {
:url=>['Ref 1', 'Ref 2'],
:cve=>['2011-001'],
:secunia=>['secunia'],
:osvdb=>['osvdb'],
:metasploit=>['exploit/ex1'],
:exploitdb=>['exploitdb']
'id' => ['3911'],
'url' => ['Ref 1,Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
}
its(:title) { should == 'Vuln Title' }
its(:type) { should == 'CSRF' }
its(:references) { should == expected_refs}
its(:fixed_in) { should == '1.0'}
its(:title) { should == 'Vuln Title' }
its(:type) { should == 'CSRF' }
its(:references) { should == expected_refs}
its(:fixed_in) { should == '1.0'}
end
end

View File

@@ -11,17 +11,18 @@ describe WpItem do
end
it_behaves_like 'WpItem::Versionable'
it_behaves_like 'WpItem::Vulnerable' do
let(:vulns_file) { MODELS_FIXTURES + '/wp_item/vulnerable/items_vulns.xml' }
let(:vulns_xpath) { "//item[@name='neo']/vulnerability" }
let(:vulns_file) { MODELS_FIXTURES + '/wp_item/vulnerable/items_vulns.json' }
let(:identifier) { 'neo' }
let(:expected_refs) { {
:url => ['Ref 1', 'Ref 2'],
:cve => ['2011-001'],
:secunia => ['secunia'],
:osvdb => ['osvdb'],
:metasploit => ['exploit/ex1'],
:exploitdb => ['exploitdb']
'id' => [2993],
'url' => ['Ref 1,Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
} }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new("I'm the one", 'XSS', expected_refs) }
let(:expected_vulns) { Vulnerabilities.new(1, Vulnerability.new("I'm the one", 'XSS', expected_refs)) }
end
subject(:wp_item) { WpItem.new(uri, options) }
@@ -30,30 +31,30 @@ describe WpItem do
describe '#new' do
context 'with no options' do
its(:wp_content_dir) { should == 'wp-content' }
its(:wp_plugins_dir) { should == 'wp-content/plugins' }
its(:uri) { should be uri }
its(:wp_content_dir) { is_expected.to eq 'wp-content' }
its(:wp_plugins_dir) { is_expected.to eq 'wp-content/plugins' }
its(:uri) { is_expected.to be uri }
end
context 'with :wp_content_dir' do
let(:options) { { wp_content_dir: 'custom' } }
its(:wp_content_dir) { should == 'custom' }
its(:wp_plugins_dir) { should == 'custom/plugins' }
its(:wp_content_dir) { is_expected.to eq 'custom' }
its(:wp_plugins_dir) { is_expected.to eq 'custom/plugins' }
end
context 'with :wp_plugins_dir' do
let(:options) { { wp_plugins_dir: 'c-plugins' } }
its(:wp_content_dir) { should == 'wp-content' }
its(:wp_plugins_dir) { should == 'c-plugins' }
its(:wp_content_dir) { is_expected.to eq 'wp-content' }
its(:wp_plugins_dir) { is_expected.to eq 'c-plugins' }
end
end
describe '#set_options' do
context 'no an allowed option' do
it 'ignores the option' do
wp_item.should_not_receive(:not_allowed=)
expect(wp_item).not_to receive(:not_allowed=)
wp_item.send(:set_options, { not_allowed: 'owned' })
end
@@ -61,7 +62,7 @@ describe WpItem do
context 'allowed option, w/o setter method' do
it 'raises an error' do
wp_item.stub(:allowed_options).and_return([:no_setter])
allow(wp_item).to receive(:allowed_options).and_return([:no_setter])
expect {
wp_item.send(:set_options, { no_setter: 'hello' })
@@ -73,7 +74,7 @@ describe WpItem do
describe '#path=' do
after do
wp_item.path = @path
wp_item.path.should == @expected
expect(wp_item.path).to eq @expected
end
context 'with default variable value' do
@@ -90,8 +91,8 @@ describe WpItem do
context 'whith custom variable values' do
before {
wp_item.stub(:wp_content_dir).and_return('custom-content')
wp_item.stub(:wp_plugins_dir).and_return('plugins')
allow(wp_item).to receive(:wp_content_dir).and_return('custom-content')
allow(wp_item).to receive(:wp_plugins_dir).and_return('plugins')
}
it 'replaces $wp-content$ by custom-content' do
@@ -117,7 +118,7 @@ describe WpItem do
path = 'somedir/somefile.php'
wp_item.path = path
wp_item.uri.should == uri.merge(path)
expect(wp_item.uri).to eq uri.merge(path)
end
end
end
@@ -127,7 +128,7 @@ describe WpItem do
wp_item.name = 'a-name'
other = WpItem.new(uri, name: 'other-name')
wp_item.<=>(other).should === 'a-name'.<=>('other-name')
expect(wp_item.<=>(other)).to be === 'a-name'.<=>('other-name')
end
end
@@ -137,7 +138,7 @@ describe WpItem do
wp_item.name = 'some-name'
other = WpItem.new(uri, name: 'some-name')
wp_item.should == other
expect(wp_item).to eq other
end
end
@@ -146,7 +147,7 @@ describe WpItem do
wp_item.name = 'Test'
other = WpItem.new(uri, name: 'hello')
wp_item.should_not == other
expect(wp_item).not_to eq other
end
end
end
@@ -156,13 +157,13 @@ describe WpItem do
context 'when the :name and :version are the same' do
it 'is ===' do
WpItem.new(uri, options).should === WpItem.new(uri.merge('yo'), options)
expect(WpItem.new(uri, options)).to be === WpItem.new(uri.merge('yo'), options)
end
end
context 'otherwise' do
it 'is not ===' do
WpItem.new(uri, options).should_not === WpItem.new(uri, options.merge(version: '1.0'))
expect(WpItem.new(uri, options)).not_to be === WpItem.new(uri, options.merge(version: '1.0'))
end
end
end

View File

@@ -6,14 +6,15 @@ describe WpPlugin do
it_behaves_like 'WpPlugin::Vulnerable'
it_behaves_like 'WpItem::Vulnerable' do
let(:options) { { name: 'white-rabbit' } }
let(:vulns_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins_vulns.xml' }
let(:vulns_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins_vulns.json' }
let(:expected_refs) { {
:url => ['Ref 1', 'Ref 2'],
:cve => ['2011-001'],
:secunia => ['secunia'],
:osvdb => ['osvdb'],
:metasploit => ['exploit/ex1'],
:exploitdb => ['exploitdb']
'id' => [2993],
'url' => ['Ref 1,Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
} }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('Follow me!', 'REDIRECT', expected_refs) }
end
@@ -23,7 +24,7 @@ describe WpPlugin do
let(:options) { { name: 'plugin-name' } }
describe '#forge_uri' do
its('uri.to_s') { should == 'http://example.com/wp-content/plugins/plugin-name/' }
its('uri.to_s') { is_expected.to eq 'http://example.com/wp-content/plugins/plugin-name/' }
end
end

View File

@@ -18,9 +18,9 @@ describe 'WpTheme::Findable' do
wp_theme = WpTheme.send(:find_from_css_link, uri)
if @expected
wp_theme.should be_a WpTheme
expect(wp_theme).to be_a WpTheme
end
wp_theme.should == @expected
expect(wp_theme).to eq @expected
end
context 'when theme is not present' do
@@ -52,6 +52,13 @@ describe 'WpTheme::Findable' do
end
end
context 'when other style.css is referenced' do
it 'returns the WpTheme' do
@file = 'yootheme.html'
@expected = WpTheme.new(uri, name: 'yoo_solar_wp', referenced_url: '/wp-content/themes/yoo_solar_wp/styles/wood/css/style.css')
end
end
end
describe '::find_from_wooframework' do
@@ -66,9 +73,9 @@ describe 'WpTheme::Findable' do
wp_theme = WpTheme.send(:find_from_wooframework, uri)
if @expected
wp_theme.should be_a WpTheme
expect(wp_theme).to be_a WpTheme
end
wp_theme.should == @expected
expect(wp_theme).to eq @expected
end
context 'when theme is not present' do
@@ -96,7 +103,7 @@ describe 'WpTheme::Findable' do
# Stub all WpTheme::find_from_* to return nil
def stub_all_to_nil
WpTheme.methods.grep(/^find_from_/).each do |method|
WpTheme.stub(method).and_return(nil)
allow(WpTheme).to receive(method).and_return(nil)
end
end
@@ -120,7 +127,7 @@ describe 'WpTheme::Findable' do
it 'returns nil' do
stub_all_to_nil()
WpTheme.find(uri).should be_nil
expect(WpTheme.find(uri)).to be_nil
end
end
@@ -130,12 +137,12 @@ describe 'WpTheme::Findable' do
stub_request(:get, /.+\/the-oracle\/style.css$/).to_return(status: 200)
expected = WpTheme.new(uri, name: 'the-oracle')
WpTheme.stub(:find_from_css_link).and_return(expected)
allow(WpTheme).to receive(:find_from_css_link).and_return(expected)
wp_theme = WpTheme.find(uri)
wp_theme.should be_a WpTheme
wp_theme.should == expected
wp_theme.found_from.should === 'css link'
expect(wp_theme).to be_a WpTheme
expect(wp_theme).to eq expected
expect(wp_theme.found_from).to be === 'css link'
end
end

View File

@@ -3,22 +3,19 @@
require 'spec_helper'
describe WpTheme do
before do
stub_request(:get, /.+\/style.css$/).to_return(status: 200)
end
it_behaves_like 'WpTheme::Versionable'
it_behaves_like 'WpTheme::Vulnerable'
it_behaves_like 'WpItem::Vulnerable' do
let(:options) { { name: 'the-oracle' } }
let(:vulns_file) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.xml' }
let(:vulns_file) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.json' }
let(:expected_refs) { {
:url => ['Ref 1', 'Ref 2'],
:cve => ['2011-001'],
:secunia => ['secunia'],
:osvdb => ['osvdb'],
:metasploit => ['exploit/ex1'],
:exploitdb => ['exploitdb']
'id' => [2993],
'url' => ['Ref 1,Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
} }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('I see you', 'FPD', expected_refs) }
end
@@ -29,24 +26,11 @@ describe WpTheme do
let(:theme_path) { 'wp-content/themes/theme-name/' }
describe '#allowed_options' do
its(:allowed_options) { should include :style_url }
its(:allowed_options) { is_expected.to include :referenced_url }
end
describe '#forge_uri' do
its(:uri) { should == uri.merge(theme_path) }
end
describe '#style_url' do
its(:style_url) { should == uri.merge(theme_path + '/style.css').to_s }
context 'when its already set' do
it 'returns it instead of the default one' do
url = uri.merge(theme_path + '/custom.css').to_s
wp_theme.style_url = url
wp_theme.style_url.should == url
end
end
its(:uri) { is_expected.to eq uri.merge(theme_path) }
end
end

View File

@@ -13,17 +13,19 @@ describe WpTimthumb do
describe '#==' do
context 'when both url are equal' do
it 'returns true' do
WpTimthumb.new(uri, path: 'timtuhumb.php').
should ==
expect(WpTimthumb.new(uri, path: 'timtuhumb.php')).
to eq(
WpTimthumb.new(uri, path: 'timtuhumb.php')
)
end
end
context 'when urls are different' do
it 'returns false' do
WpTimthumb.new(uri, path: 'hello/timtuhumb.php').
should_not ==
expect(WpTimthumb.new(uri, path: 'hello/timtuhumb.php')).
not_to eq(
WpTimthumb.new(uri, path: 'some-dir/timtuhumb.php')
)
end
end
end

View File

@@ -12,10 +12,10 @@ describe WpUser do
describe '#allowed_options' do
[:id, :login, :display_name, :password].each do |sym|
its(:allowed_options) { should include sym }
its(:allowed_options) { is_expected.to include sym }
end
its(:allowed_options) { should_not include :name }
its(:allowed_options) { is_expected.not_to include :name }
end
describe '#uri' do
@@ -29,7 +29,7 @@ describe WpUser do
it 'returns the uri to the auhor page' do
wp_user.id = 2
wp_user.uri.should == uri.merge('?author=2')
expect(wp_user.uri).to eq uri.merge('?author=2')
end
end
end
@@ -37,7 +37,7 @@ describe WpUser do
describe '#to_s' do
after do
subject.id = 1
subject.to_s.should == @expected
expect(subject.to_s).to eq @expected
end
it 'returns @id' do
@@ -67,20 +67,20 @@ describe WpUser do
wp_user.id = 1
other = WpUser.new(uri, id: 3)
wp_user.<=>(other).should === 1.<=>(3)
expect(wp_user.<=>(other)).to be === 1.<=>(3)
end
end
describe '#===, #==' do
context 'when the :id and :login are the same' do
it 'is ===, and ==' do
WpUser.new(uri, id: 1, name: 'yo').should == WpUser.new(uri, id: 1, name: 'yo')
expect(WpUser.new(uri, id: 1, name: 'yo')).to eq WpUser.new(uri, id: 1, name: 'yo')
end
end
context 'when :id and :login are different' do
it 'is not === or ==' do
WpUser.new(uri, id: 1, name: 'yo').should_not == WpUser.new(uri, id: 2, name:'yo')
expect(WpUser.new(uri, id: 1, name: 'yo')).not_to eq WpUser.new(uri, id: 2, name:'yo')
end
end
end

View File

@@ -26,7 +26,7 @@ describe 'WpVersion::Findable' do
fixture = fixtures_dir + dir_name + @fixture
stub_request_to_fixture(url: url, fixture: fixture)
WpVersion.send(method, uri).should == @expected
expect(WpVersion.send(method, uri)).to eq @expected
end
context 'when generator not found' do
@@ -81,7 +81,7 @@ describe 'WpVersion::Findable' do
:find_from_advanced_fingerprinting,
uri, wp_content_dir, wp_plugins_dir, versions_xml
)
version.should == @expected
expect(version).to eq @expected
end
context 'when' do
@@ -108,7 +108,7 @@ describe 'WpVersion::Findable' do
fixture = fixtures_dir + 'readme' + @fixture
stub_request_to_fixture(url: url, fixture: fixture)
WpVersion.send(:find_from_readme, uri).should == @expected
expect(WpVersion.send(:find_from_readme, uri)).to eq @expected
end
context 'when version not found' do
@@ -138,7 +138,7 @@ describe 'WpVersion::Findable' do
fixture = fixtures_dir + 'links_opml' + @fixture
stub_request_to_fixture(url: url, fixture: fixture)
WpVersion.send(:find_from_links_opml, uri).should == @expected
expect(WpVersion.send(:find_from_links_opml, uri)).to eq @expected
end
it 'returns 3.4.2' do
@@ -158,7 +158,7 @@ describe 'WpVersion::Findable' do
# Stub all WpVersion::find_from_* to return nil
def stub_all_to_nil
WpVersion.methods.grep(/^find_from_/).each do |method|
WpVersion.stub(method).and_return(nil)
allow(WpVersion).to receive(method).and_return(nil)
end
end
@@ -170,9 +170,9 @@ describe 'WpVersion::Findable' do
stub_request(:get, /#{uri.to_s}.*/).to_return(status: 0)
version = WpVersion.find(uri, wp_content_dir, wp_plugins_dir, version_xml)
version.should == @expected
expect(version).to eq @expected
if @expected
version.found_from.should == @found_from
expect(version.found_from).to eq @found_from
end
end
@@ -191,7 +191,7 @@ describe 'WpVersion::Findable' do
it "returns the correct WpVersion" do
stub_all_to_nil()
WpVersion.stub(method).and_return(number)
allow(WpVersion).to receive(method).and_return(number)
@expected = WpVersion.new(uri, number: number)
@found_from = found_from

View File

@@ -6,14 +6,15 @@ describe WpVersion do
it_behaves_like 'WpVersion::Vulnerable'
it_behaves_like 'WpItem::Vulnerable' do
let(:options) { { number: '3.2' } }
let(:vulns_file) { MODELS_FIXTURES + '/wp_version/vulnerable/versions_vulns.xml' }
let(:vulns_file) { MODELS_FIXTURES + '/wp_version/vulnerable/versions_vulns.json' }
let(:expected_refs) { {
:url => ['Ref 1', 'Ref 2'],
:cve => ['2011-001'],
:secunia => ['secunia'],
:osvdb => ['osvdb'],
:metasploit => ['exploit/ex1'],
:exploitdb => ['exploitdb']
'id' => [2993],
'url' => ['Ref 1,Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
} }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('Here I Am', 'SQLI', expected_refs) }
end
@@ -24,7 +25,7 @@ describe WpVersion do
describe '#allowed_options' do
[:number, :found_from].each do |sym|
its(:allowed_options) { should include sym }
its(:allowed_options) { is_expected.to include sym }
end
end

View File

@@ -10,7 +10,7 @@ describe Plugin do
subject(:plugin) { Plugin.new(infos) }
let(:infos) { { author: 'John' } }
its(:author) { should === infos[:author] }
its(:author) { is_expected.to be === infos[:author] }
end
end
@@ -26,7 +26,7 @@ describe Plugin do
expect { plugin.register_options(*@options) }.to raise_error(@exception)
else
plugin.register_options(*@options)
plugin.registered_options.sort.should === @expected.sort
expect(plugin.registered_options.sort).to be === @expected.sort
end
end

View File

@@ -23,18 +23,18 @@ describe Plugins do
describe '#new' do
context 'without argument' do
its(:option_parser) { should be_a CustomOptionParser }
its(:option_parser) { is_expected.to be_a CustomOptionParser }
it 'should be an Array' do
plugins.should be_an Array
expect(plugins).to be_an Array
end
end
context 'with an option_parser argument' do
subject(:plugin) { Plugins.new(CustomOptionParser.new('the banner')) }
its(:option_parser) { should be_a CustomOptionParser }
its('option_parser.banner') { should === 'the banner' }
its(:option_parser) { is_expected.to be_a CustomOptionParser }
its('option_parser.banner') { is_expected.to be === 'the banner' }
it 'should raise an eror if the parser is not an instance of CustomOptionParser' do
expect { Plugins.new(OptionParser.new) }.to raise_error('The parser must be an instance of CustomOptionParser, OptionParser supplied')
@@ -48,8 +48,8 @@ describe Plugins do
expect { plugins.register_plugin(@plugin) }.to raise_error(@exception)
else
plugins.register_plugin(@plugin)
plugins.should include(@plugin)
plugins.should === @expected
expect(plugins).to include(@plugin)
expect(plugins).to be === @expected
end
end
@@ -78,11 +78,11 @@ describe Plugins do
plugins.register(*@plugins_to_register)
@plugins_to_register.each do |plugin|
plugins.should include(plugin)
expect(plugins).to include(plugin)
end
# For the correct order
plugins.should === @plugins_to_register
expect(plugins).to be === @plugins_to_register
end
it 'should register 1 plugin' do

View File

@@ -1,74 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe GitUpdater do
before :each do
@git_updater = GitUpdater.new
end
describe '#is_installed?' do
after :each do
stub_system_command(@git_updater, /^git .* status/, @stub_value)
@git_updater.is_installed?.should === @expected
end
it 'should return false if the command is not found' do
@stub_value = 'git: command not found'
@expected = false
end
it 'should return true if the repo is a git one' do
@stub_value = "# On branch master\n# Changed but not updated:"
@expected = true
end
end
describe '#local_revision_number' do
after :each do
stub_system_command(@git_updater, /^git .* log/, @stub_value)
@git_updater.local_revision_number.should === @expected
end
it 'should return 79c01f3' do
@stub_value = '
commit 79c01f3ed535a8e33876ea091d8217cae7df4028
Author: Moi <tadimm>
Date: Wed Jul 11 23:22:16 2012 +0100'
@expected = '79c01f3'
end
end
describe '#update' do
it 'should do nothing xD' do
stub_system_command(@git_updater, /^git .* pull/, 'Already up-to-date.')
@git_updater.update().should === 'Already up-to-date.'
end
end
describe '#has_local_changes?' do
after :each do
stub_system_command(@git_updater, /^git .* diff --exit-code 2>&1/, @stub_value)
@git_updater.has_local_changes?.should === @expected
end
it 'should return true if there are local changes' do
@stub_value = 'diff'
@expected = true
end
it 'should return false if there are no local changes' do
@stub_value = ''
@expected = false
end
end
describe '#reset_head' do
it 'should reset the local repo' do
stub_system_command(@git_updater, /^git .* reset --hard HEAD/, 'HEAD is now at')
@git_updater.reset_head.should match(/^HEAD is now at/)
end
end
end

View File

@@ -1,86 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe SvnUpdater do
before :each do
@svn_updater = SvnUpdater.new
end
describe '#is_installed?' do
after :each do
stub_system_command(@svn_updater, /^svn info/, @stub_value)
@svn_updater.is_installed?.should === @expected
end
it 'should return false if the svn command is not found' do
@stub_value = 'svn: command not found'
@expected = false
end
it 'should return false if the repository is not manage by svn' do
@stub_value = "svn: '.' is not a working copy"
@expected = false
end
it 'should return true' do
@stub_value = '<?xml version="1.0"?>
<info>
<entry kind="dir" path="." revision="362">
<url>https://wpscan.googlecode.com/svn/trunk</url>
<repository>
<root>https://wpscan.googlecode.com/svn</root>
<uuid>0b0242d5-46e6-2201-410d-bc09fd35266c</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit revision="362">
<author>author@mail.tld</author>
<date>2012-06-02T06:26:25.309806Z</date>
</commit>
</entry>
</info>'
@expected = true
end
end
describe '#local_revision_number' do
after :each do
stub_system_command(@svn_updater, /^svn info/, @stub_value)
@svn_updater.local_revision_number.should === @expected
end
it 'should return 399' do
@stub_value = '<?xml version="1.0"?>
<info>
<entry kind="dir" path="." revision="362">
<url>https://wpscan.googlecode.com/svn/trunk</url>
<repository>
<root>https://wpscan.googlecode.com/svn</root>
<uuid>0b0242d5-46e6-2201-410d-bc09fd35266c</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit revision="362">
<author>author@mail.tld</author>
<date>2012-06-02T06:26:25.309806Z</date>
</commit>
</entry>
</info>'
@expected = '362'
end
end
describe '#update' do
it 'should do nothing xD' do
stub_system_command(@svn_updater, /^svn up/, 'At revision 425.')
@svn_updater.update().should === 'At revision 425.'
end
end
end

View File

@@ -1,29 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe UpdaterFactory do
describe '#available_updaters_classes' do
after :each do
UpdaterFactory.available_updaters_classes.sort.should === @expected.sort
end
it 'should return [:GitUpdater, :SvnUpdater]' do
@expected = [:GitUpdater, :SvnUpdater]
end
it 'should return [:TestUpdater, :GitUpdater, :SvnUpdater]' do
class TestUpdater < Updater
end
@expected = [:GitUpdater, :SvnUpdater, :TestUpdater]
end
end
# TODO : Find a way to test that
describe '#get_updater' do
end
end

View File

@@ -1,27 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe Updater do
before :all do
class TestUpdater < Updater
end
end
after :all do
Object.send(:remove_const, :TestUpdater)
end
describe 'non implementation of #is_installed?, #has_update? and #update' do
it 'should raise errors' do
test_updater = TestUpdater.new
methods_to_call = [:is_installed?, :update, :local_revision_number]
methods_to_call.each do |method_to_call|
expect { test_updater.send(method_to_call) }.to raise_error(NotImplementedError)
end
end
end
end

View File

@@ -3,9 +3,9 @@
require 'spec_helper'
describe 'VersionCompare' do
describe '::is_newer_or_same?' do
describe '::lesser_or_equal?' do
context 'version checked is newer' do
after { VersionCompare::is_newer_or_same?(@version1, @version2).should be_true }
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_truthy }
it 'returns true' do
@version1 = '1.0'
@@ -36,10 +36,15 @@ describe 'VersionCompare' do
@version1 = '0.4.2b'
@version2 = '2.3.3'
end
it 'returns true' do
@version1 = '.47'
@version2 = '.50.3'
end
end
context 'version checked is older' do
after { VersionCompare::is_newer_or_same?(@version1, @version2).should be_false }
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_falsey }
it 'returns false' do
@version1 = '1'
@@ -60,10 +65,15 @@ describe 'VersionCompare' do
@version1 = '1.6.3.7.3.4'
@version2 = '1.2.4.567.679.8.e'
end
it 'returns false' do
@version1 = '.47'
@version2 = '.46.3'
end
end
context 'version checked is the same' do
after { VersionCompare::is_newer_or_same?(@version1, @version2).should be_true }
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_truthy }
it 'returns true' do
@version1 = '1'
@@ -78,7 +88,7 @@ describe 'VersionCompare' do
end
context 'version number causes Gem::Version new Exception' do
after { VersionCompare::is_newer_or_same?(@version1, @version2).should be_false }
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_falsey }
it 'returns false' do
@version1 = 'a'
@@ -87,7 +97,7 @@ describe 'VersionCompare' do
end
context 'one version number is not set' do
after { VersionCompare::is_newer_or_same?(@version1, @version2).should be_false }
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_falsey }
it 'returns false (version2 nil)' do
@version1 = '1'

View File

@@ -18,13 +18,13 @@ describe 'WebSite' do
end
describe "#new" do
its(:url) { should === 'http://example.localhost/' }
its(:url) { is_expected.to be === 'http://example.localhost/' }
end
describe '#url=' do
after :each do
web_site.url = @uri
web_site.url.should === @expected
expect(web_site.url).to be === @expected
end
context 'when protocol or trailing slash is missing' do
@@ -45,30 +45,30 @@ describe 'WebSite' do
describe '#online?' do
it 'should not be considered online if the status code is 0' do
stub_request(:get, web_site.url).to_return(status: 0)
web_site.should_not be_online
expect(web_site).not_to be_online
end
it 'should be considered online if the status code is != 0' do
stub_request(:get, web_site.url).to_return(status: 200)
web_site.should be_online
expect(web_site).to be_online
end
end
describe '#has_basic_auth?' do
it 'should detect that the wpsite is basic auth protected' do
stub_request(:get, web_site.url).to_return(status: 401)
web_site.should have_basic_auth
expect(web_site).to have_basic_auth
end
it 'should not have a basic auth for a 200' do
stub_request(:get, web_site.url).to_return(status: 200)
web_site.should_not have_basic_auth
expect(web_site).not_to have_basic_auth
end
end
describe '#xml_rpc_url' do
it 'returns the xmlrpc url' do
web_site.xml_rpc_url.should === "http://example.localhost/xmlrpc.php"
expect(web_site.xml_rpc_url).to be === "http://example.localhost/xmlrpc.php"
end
end
@@ -77,17 +77,63 @@ describe 'WebSite' do
stub_request(:get, web_site.xml_rpc_url).
to_return(status: 200, body: "XML-RPC server accepts POST requests only")
web_site.should have_xml_rpc
expect(web_site).to have_xml_rpc
end
it 'returns false' do
stub_request(:get, web_site.xml_rpc_url).to_return(status: 200)
web_site.should_not have_xml_rpc
expect(web_site).not_to have_xml_rpc
end
end
describe '#redirection' do
it 'returns nil if no redirection detected' do
stub_request(:get, web_site.url).to_return(status: 200, body: '')
expect(web_site.redirection).to be_nil
end
[301, 302].each do |status_code|
it "returns http://new-location.com if the status code is #{status_code}" do
new_location = 'http://new-location.com'
stub_request(:get, web_site.url).
to_return(status: status_code, headers: { location: new_location })
stub_request(:get, new_location).to_return(status: 200)
expect(web_site.redirection).to be === 'http://new-location.com'
end
end
context 'when relative URI in Location' do
it 'returns the absolute URI' do
relative_location = '/blog/'
absolute_location = web_site.uri.merge(relative_location).to_s
stub_request(:get, web_site.url).to_return(status: 301, headers: { location: relative_location })
stub_request(:get, absolute_location)
expect(web_site.redirection).to eql absolute_location
end
end
context 'when multiple redirections' do
it 'returns the last redirection' do
first_redirection = 'www.redirection.com'
last_redirection = 'redirection.com'
stub_request(:get, web_site.url).to_return(status: 301, headers: { location: first_redirection })
stub_request(:get, first_redirection).to_return(status: 302, headers: { location: last_redirection })
stub_request(:get, last_redirection).to_return(status: 200)
expect(web_site.redirection).to be === last_redirection
end
end
end
describe '#page_hash' do
after { WebSite.page_hash(page).should == Digest::MD5.hexdigest(@expected) }
after { expect(WebSite.page_hash(page)).to eq Digest::MD5.hexdigest(@expected) }
context 'when the page is an url' do
let(:page) { 'http://e.localhost/somepage.php' }
@@ -125,7 +171,7 @@ describe 'WebSite' do
body = 'Hello World'
stub_request(:get, web_site.url).to_return(body: body)
web_site.homepage_hash.should === Digest::MD5.hexdigest(body)
expect(web_site.homepage_hash).to be === Digest::MD5.hexdigest(body)
end
end
@@ -134,19 +180,19 @@ describe 'WebSite' do
stub_request(:any, /.*/).
to_return(status: 404, body: '404 page !')
web_site.error_404_hash.should === Digest::MD5.hexdigest('404 page !')
expect(web_site.error_404_hash).to be === Digest::MD5.hexdigest('404 page !')
end
end
describe '#rss_url' do
it 'returns nil if the url is not found' do
stub_request(:get, web_site.url).to_return(body: 'No RSS link in this body !')
web_site.rss_url.should be_nil
expect(web_site.rss_url).to be_nil
end
it "returns 'http://lamp-wp/wordpress-3.5/?feed=rss2'" do
stub_request_to_fixture(url: web_site.url, fixture: fixtures_dir + '/rss_url/wordpress-3.5.htm')
web_site.rss_url.should === 'http://lamp-wp/wordpress-3.5/?feed=rss2'
expect(web_site.rss_url).to be === 'http://lamp-wp/wordpress-3.5/?feed=rss2'
end
end
@@ -156,7 +202,7 @@ describe 'WebSite' do
after do
stub_request_to_fixture(url: log_url, fixture: fixtures_dir + "/has_log/#{@file}")
WebSite.has_log?(log_url, pattern).should == @expected
expect(WebSite.has_log?(log_url, pattern)).to eq @expected
end
context 'when the pattern does not match' do

View File

@@ -37,7 +37,7 @@ describe WpTarget do
it 'returns the login url of the target' do
stub_request(:get, login_url).to_return(status: 200, body: '')
wp_target.login_url.should === login_url
expect(wp_target.login_url).to be === login_url
end
it 'returns the redirection url if there is one (ie: for https)' do
@@ -46,7 +46,7 @@ describe WpTarget do
stub_request(:get, login_url).to_return(status: 302, headers: { location: https_login_url })
stub_request(:get, https_login_url).to_return(status: 200)
wp_target.login_url.should === https_login_url
expect(wp_target.login_url).to be === https_login_url
end
end
@@ -57,7 +57,7 @@ describe WpTarget do
to_return(status: 200, body: '', headers: { 'X-Pingback' => wp_target.uri.merge('xmlrpc.php')})
# Preventing redirection check from login_url()
wp_target.stub(redirection: nil)
allow(wp_target).to receive_messages(redirection: nil)
[wp_target.login_url, wp_target.xml_rpc_url].each do |url|
stub_request(:get, url).to_return(status: 404, body: '')
@@ -67,25 +67,25 @@ describe WpTarget do
it 'returns true if there is a /wp-content/ detected in the index page source' do
stub_request_to_fixture(url: wp_target.url, fixture: fixtures_dir + '/wp_content_dir/wordpress-3.4.1.htm')
wp_target.should be_wordpress
expect(wp_target).to be_wordpress
end
it 'returns true if the xmlrpc is found' do
stub_request(:get, wp_target.xml_rpc_url).
to_return(status: 200, body: File.new(fixtures_dir + '/xmlrpc.php'))
wp_target.should be_wordpress
expect(wp_target).to be_wordpress
end
it 'returns true if the wp-login is found and is a valid wordpress one' do
stub_request(:get, wp_target.login_url).
to_return(status: 200, body: File.new(fixtures_dir + '/wp-login.php'))
wp_target.should be_wordpress
expect(wp_target).to be_wordpress
end
it 'returns false if both files are not found (404)' do
wp_target.should_not be_wordpress
expect(wp_target).not_to be_wordpress
end
context 'when the url contains "wordpress" and is a 404' do
@@ -94,7 +94,7 @@ describe WpTarget do
it 'returns false' do
stub_request(:get, wp_target.login_url).to_return(status: 404, body: 'The requested URL /wordpress-3.5. was not found on this server.')
wp_target.should_not be_wordpress
expect(wp_target).not_to be_wordpress
end
end
@@ -110,58 +110,24 @@ describe WpTarget do
describe '#wordpress_hosted?' do
it 'returns true if target url is a wordpress.com subdomain' do
target = WpTarget.new('http://test.wordpress.com/')
target.wordpress_hosted?.should be_true
expect(target.wordpress_hosted?).to be_truthy
end
it 'returns true if target url is a wordpress.com subdomain and has querystring' do
target = WpTarget.new('http://test.wordpress.com/path/file.php?a=b')
target.wordpress_hosted?.should be_true
expect(target.wordpress_hosted?).to be_truthy
end
it 'returns false if target url is not a wordpress.com subdomain' do
target = WpTarget.new('http://test.example.com/')
target.wordpress_hosted?.should be_false
end
end
describe '#redirection' do
it 'returns nil if no redirection detected' do
stub_request(:get, wp_target.url).to_return(status: 200, body: '')
wp_target.redirection.should be_nil
end
[301, 302].each do |status_code|
it "returns http://new-location.com if the status code is #{status_code}" do
new_location = 'http://new-location.com'
stub_request(:get, wp_target.url).
to_return(status: status_code, headers: { location: new_location })
stub_request(:get, new_location).to_return(status: 200)
wp_target.redirection.should === 'http://new-location.com'
end
end
context 'when multiple redirections' do
it 'returns the last redirection' do
first_redirection = 'www.redirection.com'
last_redirection = 'redirection.com'
stub_request(:get, wp_target.url).to_return(status: 301, headers: { location: first_redirection })
stub_request(:get, first_redirection).to_return(status: 302, headers: { location: last_redirection })
stub_request(:get, last_redirection).to_return(status: 200)
wp_target.redirection.should === last_redirection
end
expect(target.wordpress_hosted?).to be_falsey
end
end
describe '#debug_log_url' do
it "returns 'http://example.localhost/wp-content/debug.log" do
wp_target.stub(wp_content_dir: 'wp-content')
wp_target.debug_log_url.should === 'http://example.localhost/wp-content/debug.log'
allow(wp_target).to receive_messages(wp_content_dir: 'wp-content')
expect(wp_target.debug_log_url).to be === 'http://example.localhost/wp-content/debug.log'
end
end
@@ -169,9 +135,9 @@ describe WpTarget do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_TARGET_DIR + '/debug_log' }
after :each do
wp_target.stub(wp_content_dir: 'wp-content')
allow(wp_target).to receive_messages(wp_content_dir: 'wp-content')
stub_request_to_fixture(url: wp_target.debug_log_url(), fixture: @fixture)
wp_target.has_debug_log?.should === @expected
expect(wp_target.has_debug_log?).to be === @expected
end
it 'returns false' do
@@ -192,24 +158,24 @@ describe WpTarget do
describe '#search_replace_db_2_url' do
it 'returns the correct url' do
wp_target.search_replace_db_2_url.should == 'http://example.localhost/searchreplacedb2.php'
expect(wp_target.search_replace_db_2_url).to eq 'http://example.localhost/searchreplacedb2.php'
end
end
describe '#search_replace_db_2_exists?' do
it 'returns true' do
stub_request(:any, wp_target.search_replace_db_2_url).to_return(status: 200, body: 'asdf by interconnect asdf')
wp_target.search_replace_db_2_exists?.should be_true
expect(wp_target.search_replace_db_2_exists?).to be_truthy
end
it 'returns false' do
stub_request(:any, wp_target.search_replace_db_2_url).to_return(status: 500)
wp_target.search_replace_db_2_exists?.should be_false
expect(wp_target.search_replace_db_2_exists?).to be_falsey
end
it 'returns false' do
stub_request(:any, wp_target.search_replace_db_2_url).to_return(status: 500, body: 'asdf by interconnect asdf')
wp_target.search_replace_db_2_exists?.should be_false
expect(wp_target.search_replace_db_2_exists?).to be_falsey
end
end

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