From c4aed0ec8908695aee58b979009cbbdd110cbd84 Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Fri, 14 Aug 2015 00:19:22 +0200 Subject: [PATCH 01/15] Initial attempt at implementing apiv2 #853 --- .rspec | 2 +- lib/common/collections/wp_items.rb | 1 + lib/common/collections/wp_items/detectable.rb | 28 ++++++------- .../collections/wp_plugins/detectable.rb | 8 +--- .../collections/wp_themes/detectable.rb | 8 +--- lib/common/common_helper.rb | 23 +++++------ lib/common/db_updater.rb | 3 +- lib/common/models/vulnerability.rb | 11 +++--- lib/common/models/vulnerability/output.rb | 8 ++-- lib/common/models/wp_item/output.rb | 2 + lib/common/models/wp_item/vulnerable.rb | 7 ++-- lib/common/models/wp_plugin/vulnerable.rb | 2 +- lib/common/models/wp_theme/vulnerable.rb | 2 +- lib/common/models/wp_version/vulnerable.rb | 2 +- wpscan.rb | 39 ++++++++++++++++--- 15 files changed, 81 insertions(+), 65 deletions(-) diff --git a/.rspec b/.rspec index ba44b749..9c3c126f 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ --color ---fail-fast +#--fail-fast diff --git a/lib/common/collections/wp_items.rb b/lib/common/collections/wp_items.rb index 5fdb17ec..0ac3adb4 100755 --- a/lib/common/collections/wp_items.rb +++ b/lib/common/collections/wp_items.rb @@ -67,6 +67,7 @@ class WpItems < Array end protected + # @return [ Class ] def item_class Object.const_get(self.class.to_s.gsub(/.$/, '')) diff --git a/lib/common/collections/wp_items/detectable.rb b/lib/common/collections/wp_items/detectable.rb index d27925df..96ca5057 100755 --- a/lib/common/collections/wp_items/detectable.rb +++ b/lib/common/collections/wp_items/detectable.rb @@ -155,15 +155,7 @@ class WpItems < Array item_class = self.item_class vulns_file = self.vulns_file - targets = vulnerable_targets_items(wp_target, item_class, vulns_file) - - unless options[:only_vulnerable] - unless options[:file] - raise 'A file must be supplied' - end - - targets += targets_items_from_file(options[:file], wp_target, item_class, vulns_file) - end + targets = target_items(wp_target, item_class, vulns_file, options[:type]) targets.uniq! { |t| t.name } targets.sort_by { rand } @@ -174,14 +166,25 @@ class WpItems < Array # @param [ String ] vulns_file # # @return [ Array ] - def vulnerable_targets_items(wp_target, item_class, vulns_file) + def target_items(wp_target, item_class, vulns_file, type) targets = [] json = json(vulns_file) - [*json].each do |item| + case type + when :vulnerable + item_names = json.select { |item| !item['vulnerabilities'].empty? }.map {|item| item['name'] } + when :popular + item_names = json.select { |item| item['popular'] == true }.map {|item| item['name'] } + when :all + item_names = [*json].map { |item| item['name'] } + else + raise "Known type #{type}" + end + + item_names.each do |item_name| targets << create_item( item_class, - item.keys.inject, + item_name, wp_target, vulns_file ) @@ -233,6 +236,5 @@ class WpItems < Array def item_class Object.const_get(self.to_s.gsub(/.$/, '')) end - end end diff --git a/lib/common/collections/wp_plugins/detectable.rb b/lib/common/collections/wp_plugins/detectable.rb index 3eb43c3c..30be4381 100644 --- a/lib/common/collections/wp_plugins/detectable.rb +++ b/lib/common/collections/wp_plugins/detectable.rb @@ -2,17 +2,11 @@ class WpPlugins < WpItems module Detectable - # @return [ String ] def vulns_file - PLUGINS_VULNS_FILE + PLUGINS_FILE end - # @return [ String ] - # def item_xpath - # '//plugin' - # end - # @param [ WpTarget ] wp_target # @param [ Hash ] options # diff --git a/lib/common/collections/wp_themes/detectable.rb b/lib/common/collections/wp_themes/detectable.rb index a2c3e594..7e28b8b1 100644 --- a/lib/common/collections/wp_themes/detectable.rb +++ b/lib/common/collections/wp_themes/detectable.rb @@ -5,13 +5,7 @@ class WpThemes < WpItems # @return [ String ] def vulns_file - THEMES_VULNS_FILE + THEMES_FILE end - - # @return [ String ] - # def item_xpath - # '//theme' - # end - end end diff --git a/lib/common/common_helper.rb b/lib/common/common_helper.rb index 82f40516..34604f93 100644 --- a/lib/common/common_helper.rb +++ b/lib/common/common_helper.rb @@ -18,20 +18,15 @@ COMMON_PLUGINS_DIR = File.join(COMMON_LIB_DIR, 'plugins') WPSCAN_PLUGINS_DIR = File.join(WPSCAN_LIB_DIR, 'plugins') # Not used ATM # Data files -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') -LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update') +WORDPRESSES_FILE = File.join(DATA_DIR, 'wordpresses.json') +PLUGINS_FILE = File.join(DATA_DIR, 'plugins.json') +THEMES_FILE = File.join(DATA_DIR, 'themes.json') +WP_VERSIONS_FILE = File.join(DATA_DIR, 'wp_versions.xml') +LOCAL_FILES_FILE = File.join(DATA_DIR, 'local_vulnerable_files.xml') +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') +LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update') WPSCAN_VERSION = '2.8' diff --git a/lib/common/db_updater.rb b/lib/common/db_updater.rb index 0204a9df..55a37095 100644 --- a/lib/common/db_updater.rb +++ b/lib/common/db_updater.rb @@ -4,9 +4,8 @@ class DbUpdater FILES = %w( local_vulnerable_files.xml local_vulnerable_files.xsd - 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 LICENSE + wordpresses.json plugins.json themes.json LICENSE ) attr_reader :repo_directory diff --git a/lib/common/models/vulnerability.rb b/lib/common/models/vulnerability.rb index 1e6dccc7..c1a94992 100755 --- a/lib/common/models/vulnerability.rb +++ b/lib/common/models/vulnerability.rb @@ -42,11 +42,12 @@ class Vulnerability # @return [ Vulnerability ] def self.load_from_json_item(json_item) references = {} + references['id'] = [json_item['id']] - %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] + %w(url cve secunia osvdb metasploit exploitdb).each do |key| + if json_item['references'][key] + json_item['references'][key] = [json_item['references'][key]] if json_item['references'][key].class != Array + references[key] = json_item['references'][key] end end @@ -54,7 +55,7 @@ class Vulnerability json_item['title'], json_item['type'], references, - json_item['fixed_in'], + json_item['fixed_in'] ) end diff --git a/lib/common/models/vulnerability/output.rb b/lib/common/models/vulnerability/output.rb index e6170338..06e81798 100644 --- a/lib/common/models/vulnerability/output.rb +++ b/lib/common/models/vulnerability/output.rb @@ -2,22 +2,22 @@ class Vulnerability module Output - # output the vulnerability def output(verbose = false) puts puts critical("Title: #{title}") + references.each do |key, urls| methodname = "url_#{key}" + urls.each do |u| next unless respond_to?(methodname) url = send(methodname, u) puts " Reference: #{url}" if url end end - unless fixed_in.nil? - puts notice("Fixed in: #{fixed_in}") - end + + puts notice("Fixed in: #{fixed_in}") if fixed_in end end end diff --git a/lib/common/models/wp_item/output.rb b/lib/common/models/wp_item/output.rb index 889883e1..17e8f219 100644 --- a/lib/common/models/wp_item/output.rb +++ b/lib/common/models/wp_item/output.rb @@ -7,6 +7,8 @@ class WpItem def output(verbose = false) puts puts info("Name: #{self}") #this will also output the version number if detected + puts " | Latest version:" + puts " | Last updated:" puts " | Location: #{url}" #puts " | WordPress: #{wordpress_url}" if wordpress_org_item? puts " | Readme: #{readme_url}" if has_readme? diff --git a/lib/common/models/wp_item/vulnerable.rb b/lib/common/models/wp_item/vulnerable.rb index 3b7619cf..99b9a189 100755 --- a/lib/common/models/wp_item/vulnerable.rb +++ b/lib/common/models/wp_item/vulnerable.rb @@ -9,15 +9,16 @@ class WpItem # # @return [ Vulnerabilities ] def vulnerabilities - json = json(vulns_file) + json = json(vulns_file).select { |item| !item['vulnerabilities'].empty? } vulnerabilities = Vulnerabilities.new json.each do |item| - asset = item[identifier] + asset = item['version'][identifier] if item['version'] + asset = item['name'][identifier] if item['name'] next unless asset - asset['vulnerabilities'].each do |vulnerability| + item['vulnerabilities'].each do |vulnerability| vulnerability = Vulnerability.load_from_json_item(vulnerability) vulnerabilities << vulnerability if vulnerable_to?(vulnerability) end diff --git a/lib/common/models/wp_plugin/vulnerable.rb b/lib/common/models/wp_plugin/vulnerable.rb index 1d994d62..c19e6c07 100644 --- a/lib/common/models/wp_plugin/vulnerable.rb +++ b/lib/common/models/wp_plugin/vulnerable.rb @@ -6,7 +6,7 @@ class WpPlugin < WpItem # @return [ String ] The path to the file containing vulnerabilities def vulns_file unless @vulns_file - @vulns_file = PLUGINS_VULNS_FILE + @vulns_file = PLUGINS_FILE end @vulns_file end diff --git a/lib/common/models/wp_theme/vulnerable.rb b/lib/common/models/wp_theme/vulnerable.rb index 756f547a..60e5560c 100644 --- a/lib/common/models/wp_theme/vulnerable.rb +++ b/lib/common/models/wp_theme/vulnerable.rb @@ -6,7 +6,7 @@ class WpTheme < WpItem # @return [ String ] The path to the file containing vulnerabilities def vulns_file unless @vulns_file - @vulns_file = THEMES_VULNS_FILE + @vulns_file = THEMES_FILE end @vulns_file end diff --git a/lib/common/models/wp_version/vulnerable.rb b/lib/common/models/wp_version/vulnerable.rb index ad846a26..da23790b 100644 --- a/lib/common/models/wp_version/vulnerable.rb +++ b/lib/common/models/wp_version/vulnerable.rb @@ -6,7 +6,7 @@ class WpVersion < WpItem # @return [ String ] The path to the file containing vulnerabilities def vulns_file unless @vulns_file - @vulns_file = WP_VULNS_FILE + @vulns_file = WORDPRESSES_FILE end @vulns_file end diff --git a/wpscan.rb b/wpscan.rb index a95033f8..5cd6afd3 100755 --- a/wpscan.rb +++ b/wpscan.rb @@ -273,15 +273,29 @@ def main # Enumerate the installed plugins if wpscan_options.enumerate_plugins or wpscan_options.enumerate_only_vulnerable_plugins or wpscan_options.enumerate_all_plugins puts - puts info("Enumerating installed plugins #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_plugins} ...") + if wpscan_options.enumerate_only_vulnerable_plugins + puts info('Enumerating installed plugins (only ones with known vulnerabilities) ...') + plugin_enumeration_type = :vulnerable + end + + if wpscan_options.enumerate_plugins + puts info('Enumerating installed plugins (only ones marked as popular) ...') + plugin_enumeration_type = :popular + end + + if wpscan_options.enumerate_all_plugins + puts info('Enumerating all plugins (may take a while and use a lot of system resources) ...') + plugin_enumeration_type = :all + end puts wp_plugins = WpPlugins.aggressive_detection(wp_target, enum_options.merge( - file: wpscan_options.enumerate_all_plugins ? PLUGINS_FULL_FILE : PLUGINS_FILE, - only_vulnerable: wpscan_options.enumerate_only_vulnerable_plugins || false + file: PLUGINS_FILE, + type: plugin_enumeration_type ) ) + puts if !wp_plugins.empty? puts info("We found #{wp_plugins.size} plugins:") @@ -295,13 +309,26 @@ def main # Enumerate installed themes if wpscan_options.enumerate_themes or wpscan_options.enumerate_only_vulnerable_themes or wpscan_options.enumerate_all_themes puts - puts info("Enumerating installed themes #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_themes} ...") + if wpscan_options.enumerate_only_vulnerable_themes + puts info('Enumerating installed themes (only ones with known vulnerabilities) ...') + theme_enumeration_type = :vulnerable + end + + if wpscan_options.enumerate_themes + puts info('Enumerating installed themes (only ones marked as popular) ...') + theme_enumeration_type = :popular + end + + if wpscan_options.enumerate_all_themes + puts info('Enumerating all themes (may take a while and use a lot of system resources) ...') + theme_enumeration_type = :all + end puts wp_themes = WpThemes.aggressive_detection(wp_target, enum_options.merge( - file: wpscan_options.enumerate_all_themes ? THEMES_FULL_FILE : THEMES_FILE, - only_vulnerable: wpscan_options.enumerate_only_vulnerable_themes || false + file: THEMES_FILE, + type: theme_enumeration_type ) ) puts From a0fed4a9d049ac9bc78c7cb325900a74ca6a10ce Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Fri, 14 Aug 2015 00:22:48 +0200 Subject: [PATCH 02/15] Clean up last commit #853 --- .rspec | 2 +- lib/common/collections/wp_items/detectable.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rspec b/.rspec index 9c3c126f..ba44b749 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ --color -#--fail-fast +--fail-fast diff --git a/lib/common/collections/wp_items/detectable.rb b/lib/common/collections/wp_items/detectable.rb index 96ca5057..cbcfd47d 100755 --- a/lib/common/collections/wp_items/detectable.rb +++ b/lib/common/collections/wp_items/detectable.rb @@ -178,7 +178,7 @@ class WpItems < Array when :all item_names = [*json].map { |item| item['name'] } else - raise "Known type #{type}" + raise "Unknown type #{type}" end item_names.each do |item_name| From 01c357e1466f81d999aa5dfc4bf672b0368908af Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Fri, 14 Aug 2015 16:03:21 +0200 Subject: [PATCH 03/15] Fix specs #853 --- .rspec | 2 +- lib/common/models/wp_item/vulnerable.rb | 4 +- .../lib/common/collections/wp_plugins_spec.rb | 2 +- spec/lib/common/collections/wp_themes_spec.rb | 2 +- spec/lib/common/models/wp_plugin_spec.rb | 2 +- .../wp_items/detectable/vulns.json | 100 +++++++++-------- .../wp_plugins/detectable/vulns.json | 102 +++++++++-------- .../wp_themes/detectable/vulns.json | 104 ++++++++++-------- .../models/vulnerability/json_item.json | 14 ++- .../wp_item/vulnerable/items_vulns.json | 50 +++++---- .../wp_plugin/vulnerable/plugins_vulns.json | 56 ---------- .../wp_theme/vulnerable/themes_vulns.json | 72 ++++++------ .../wp_version/vulnerable/versions_vulns.json | 54 ++++----- spec/shared_examples/wp_items_detectable.rb | 24 +--- spec/shared_examples/wp_plugin_vulnerable.rb | 2 +- spec/shared_examples/wp_theme_vulnerable.rb | 2 +- spec/shared_examples/wp_version_vulnerable.rb | 2 +- 17 files changed, 278 insertions(+), 316 deletions(-) delete mode 100644 spec/samples/common/models/wp_plugin/vulnerable/plugins_vulns.json diff --git a/.rspec b/.rspec index ba44b749..9c3c126f 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ --color ---fail-fast +#--fail-fast diff --git a/lib/common/models/wp_item/vulnerable.rb b/lib/common/models/wp_item/vulnerable.rb index 99b9a189..4b03eda2 100755 --- a/lib/common/models/wp_item/vulnerable.rb +++ b/lib/common/models/wp_item/vulnerable.rb @@ -8,8 +8,8 @@ class WpItem # Filters out already fixed vulnerabilities # # @return [ Vulnerabilities ] - def vulnerabilities - json = json(vulns_file).select { |item| !item['vulnerabilities'].empty? } + def vulnerabilities + json = json(vulns_file).select { |item| !item['vulnerabilities'].empty? } vulnerabilities = Vulnerabilities.new json.each do |item| diff --git a/spec/lib/common/collections/wp_plugins_spec.rb b/spec/lib/common/collections/wp_plugins_spec.rb index b1214f0d..5b0a1804 100644 --- a/spec/lib/common/collections/wp_plugins_spec.rb +++ b/spec/lib/common/collections/wp_plugins_spec.rb @@ -11,7 +11,7 @@ describe WpPlugins do let(:expected) do { request_params: { cache_ttl: 0, followlocation: true }, - vulns_file: PLUGINS_VULNS_FILE, + vulns_file: PLUGINS_FILE, targets_items_from_file: [ WpPlugin.new(uri, name: 'plugin1'), WpPlugin.new(uri, name:'plugin-2'), WpPlugin.new(uri, name: 'mr-smith')], diff --git a/spec/lib/common/collections/wp_themes_spec.rb b/spec/lib/common/collections/wp_themes_spec.rb index d173e396..b29c56ec 100644 --- a/spec/lib/common/collections/wp_themes_spec.rb +++ b/spec/lib/common/collections/wp_themes_spec.rb @@ -13,7 +13,7 @@ describe WpThemes do let(:expected) do { request_params: { cache_ttl: 0, followlocation: true }, - vulns_file: THEMES_VULNS_FILE, + vulns_file: THEMES_FILE, targets_items_from_file: [ WpTheme.new(uri, name: '3colours'), WpTheme.new(uri, name:'42k'), WpTheme.new(uri, name: 'a-ri')], diff --git a/spec/lib/common/models/wp_plugin_spec.rb b/spec/lib/common/models/wp_plugin_spec.rb index 29425678..6b740667 100644 --- a/spec/lib/common/models/wp_plugin_spec.rb +++ b/spec/lib/common/models/wp_plugin_spec.rb @@ -6,7 +6,7 @@ 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.json' } + let(:vulns_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins.json' } let(:expected_refs) { { 'id' => [2993], 'url' => ['Ref 1,Ref 2'], diff --git a/spec/samples/common/collections/wp_items/detectable/vulns.json b/spec/samples/common/collections/wp_items/detectable/vulns.json index fa7b920d..ebd99762 100644 --- a/spec/samples/common/collections/wp_items/detectable/vulns.json +++ b/spec/samples/common/collections/wp_items/detectable/vulns.json @@ -1,58 +1,66 @@ [ { - "mr-smith":{ - "vulnerabilities":[ - { - "id":2989, - "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", - "references":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:43:41.000Z" + "name": "mr-smith", + "vulnerabilities":[ + { + "id":2989, + "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", + "references": { + "url": "https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com" }, - { - "id":2990, - "title":"Potential Authentication Cookie Forgery", - "references":"https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:43:41.000Z" + }, + { + "id":2990, + "title":"Potential Authentication Cookie Forgery", + "references": { + "url": "https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be", "osvdb":"105620", - "cve":"2014-0166", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" + "cve":"2014-0166" }, - { - "id":2991, - "title":"Privilege escalation: contributors publishing posts", - "references":"https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + }, + { + "id":2991, + "title":"Privilege escalation: contributors publishing posts", + "references": { + "url": "https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165", "osvdb":"105630", - "cve":"2014-0165", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" + "cve":"2014-0165" }, - { - "id":2992, - "title":"Plupload Unspecified XSS", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + }, + { + "id":2992, + "title":"Plupload Unspecified XSS", + "references": { "osvdb":"105622", - "secunia":"57769", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" - } - ] - } + "secunia":"57769" + }, + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + } + ] }, { - "neo":{ - "vulnerabilities":[ - { - "id":2993, - "title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure", - "references":"http://seclists.org/fulldisclosure/2013/Dec/135", - "osvdb":"101101", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } + "name": "neo", + "vulnerabilities":[ + { + "id":2993, + "title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure", + "references": { + "url": "http://seclists.org/fulldisclosure/2013/Dec/135", + "osvdb":"101101" + }, + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] } ] \ No newline at end of file diff --git a/spec/samples/common/collections/wp_plugins/detectable/vulns.json b/spec/samples/common/collections/wp_plugins/detectable/vulns.json index fa7b920d..53777e54 100644 --- a/spec/samples/common/collections/wp_plugins/detectable/vulns.json +++ b/spec/samples/common/collections/wp_plugins/detectable/vulns.json @@ -1,58 +1,66 @@ [ { - "mr-smith":{ - "vulnerabilities":[ - { - "id":2989, - "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", - "references":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:43:41.000Z" + "name": "mr-smith", + "vulnerabilities":[ + { + "id":2989, + "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", + "references": { + "url": "https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com" }, - { - "id":2990, - "title":"Potential Authentication Cookie Forgery", - "references":"https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be", - "osvdb":"105620", - "cve":"2014-0166", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:43:41.000Z" + }, + { + "id":2990, + "title":"Potential Authentication Cookie Forgery", + "references": { + "url": "https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be" }, - { - "id":2991, - "title":"Privilege escalation: contributors publishing posts", - "references":"https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165", + "osvdb":"105620", + "cve":"2014-0166", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + }, + { + "id":2991, + "title":"Privilege escalation: contributors publishing posts", + "references": { + "url": "https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165", "osvdb":"105630", - "cve":"2014-0165", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" + "cve":"2014-0165" }, - { - "id":2992, - "title":"Plupload Unspecified XSS", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + }, + { + "id":2992, + "title":"Plupload Unspecified XSS", + "references": { "osvdb":"105622", - "secunia":"57769", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" - } - ] - } + "secunia":"57769" + }, + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + } + ] }, { - "neo":{ - "vulnerabilities":[ - { - "id":2993, - "title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure", - "references":"http://seclists.org/fulldisclosure/2013/Dec/135", - "osvdb":"101101", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } + "name":"neo", + "vulnerabilities":[ + { + "id":2993, + "title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure", + "references": { + "url": "http://seclists.org/fulldisclosure/2013/Dec/135", + "osvdb":"101101" + }, + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] } ] \ No newline at end of file diff --git a/spec/samples/common/collections/wp_themes/detectable/vulns.json b/spec/samples/common/collections/wp_themes/detectable/vulns.json index 80a614e5..fdcc83dc 100644 --- a/spec/samples/common/collections/wp_themes/detectable/vulns.json +++ b/spec/samples/common/collections/wp_themes/detectable/vulns.json @@ -1,58 +1,66 @@ [ { - "shopperpress":{ - "vulnerabilities":[ - { - "id":2989, - "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", - "references":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:43:41.000Z" + "name": "shopperpress", + "vulnerabilities":[ + { + "id":2989, + "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", + "references": { + "url": "https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com" }, - { - "id":2990, - "title":"Potential Authentication Cookie Forgery", - "references":"https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be", - "osvdb":"105620", - "cve":"2014-0166", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:43:41.000Z" + }, + { + "id":2990, + "title":"Potential Authentication Cookie Forgery", + "references": { + "url": "https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be", + "osvdb":"105620", + "cve":"2014-0166" }, - { - "id":2991, - "title":"Privilege escalation: contributors publishing posts", - "references":"https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165", - "osvdb":"105630", - "cve":"2014-0165", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + }, + { + "id":2991, + "title":"Privilege escalation: contributors publishing posts", + "references": { + "url": "https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165", + "osvdb":"105630", + "cve":"2014-0165" }, - { - "id":2992, - "title":"Plupload Unspecified XSS", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + }, + { + "id":2992, + "title":"Plupload Unspecified XSS", + "references": { "osvdb":"105622", - "secunia":"57769", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z", - "fixed_in":"3.8.2" - } - ] - } + "secunia":"57769" + }, + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z", + "fixed_in":"3.8.2" + } + ] }, { - "webfolio":{ - "vulnerabilities":[ - { - "id":2993, - "title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure", - "references":"http://seclists.org/fulldisclosure/2013/Dec/135", - "osvdb":"101101", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } + "name": "webfolio", + "vulnerabilities":[ + { + "id":2993, + "title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure", + "references": { + "url": "http://seclists.org/fulldisclosure/2013/Dec/135", + "osvdb":"101101" + }, + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] } ] diff --git a/spec/samples/common/models/vulnerability/json_item.json b/spec/samples/common/models/vulnerability/json_item.json index 46b4fdfe..778d4ba5 100644 --- a/spec/samples/common/models/vulnerability/json_item.json +++ b/spec/samples/common/models/vulnerability/json_item.json @@ -1,12 +1,14 @@ { "id": "3911", "title": "Vuln Title", - "url": "Ref 1,Ref 2", - "secunia": "secunia", - "osvdb": "osvdb", - "cve": "2011-001", - "metasploit": "exploit/ex1", - "exploitdb": "exploitdb", + "references":{ + "url": "Ref 1,Ref 2", + "secunia": "secunia", + "osvdb": "osvdb", + "cve": "2011-001", + "metasploit": "exploit/ex1", + "exploitdb": "exploitdb" + }, "created_at": "2014-07-28T12:10:45.000Z", "updated_at": "2014-07-28T12:10:45.000Z", "type": "CSRF", diff --git a/spec/samples/common/models/wp_item/vulnerable/items_vulns.json b/spec/samples/common/models/wp_item/vulnerable/items_vulns.json index 46ae9b2c..4c9a3b2e 100644 --- a/spec/samples/common/models/wp_item/vulnerable/items_vulns.json +++ b/spec/samples/common/models/wp_item/vulnerable/items_vulns.json @@ -1,35 +1,37 @@ [ { - "not-this-one":{ - "vulnerabilities":[ - { - "id":2989, - "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", - "url":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:43:41.000Z" - } - ] - } + "name": "not-this-one", + "vulnerabilities":[ + { + "id":2989, + "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", + "references": { + "url":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com" + }, + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:43:41.000Z" + } + ] }, { - "neo":{ - "vulnerabilities":[ - { - "id":2993, - "title":"I'm the one", + "name": "neo", + "vulnerabilities":[ + { + "id":2993, + "title":"I'm the one", + "references": { "url":"Ref 1,Ref 2", "osvdb":"osvdb", "cve":"2011-001", "secunia":"secunia", "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"XSS", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } + "exploitdb":"exploitdb" + }, + "type":"XSS", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] } ] \ No newline at end of file diff --git a/spec/samples/common/models/wp_plugin/vulnerable/plugins_vulns.json b/spec/samples/common/models/wp_plugin/vulnerable/plugins_vulns.json deleted file mode 100644 index 878c1692..00000000 --- a/spec/samples/common/models/wp_plugin/vulnerable/plugins_vulns.json +++ /dev/null @@ -1,56 +0,0 @@ -[ - { - "mr-smith":{ - "vulnerabilities":[ - { - "id":2989, - "title":"I should not appear in the results", - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"XSS", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - }, - { - "id":2989, - "title":"Neither do I", - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"XSS", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } - }, - { - "white-rabbit":{ - "vulnerabilities":[ - { - "id":2993, - "title":"Follow me!", - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"REDIRECT", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } - } -] diff --git a/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json b/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json index 03a89b8a..accd3061 100644 --- a/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json +++ b/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json @@ -1,56 +1,60 @@ [ { - "mr-smith":{ - "vulnerabilities":[ - { - "id":2989, - "title":"I should not appear in the results", + "name": "mr-smith", + "vulnerabilities":[ + { + "id":2989, + "title":"I should not appear in the results", + "references": { "url":"Ref 1,Ref 2", "osvdb":"osvdb", "cve":"2011-001", "secunia":"secunia", "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"XSS", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" + "exploitdb":"exploitdb" }, - { - "id":2989, - "title":"Neither do I", + "type":"XSS", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + }, + { + "id":2989, + "title":"Neither do I", + "references": { "url":"Ref 1,Ref 2", "osvdb":"osvdb", "cve":"2011-001", "secunia":"secunia", "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"XSS", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } + "exploitdb":"exploitdb" + }, + "type":"XSS", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } ] - } - }, + }, { - "the-oracle":{ - "vulnerabilities":[ - { - "id":2993, - "title":"I see you", + "name": "the-oracle", + "vulnerabilities":[ + { + "id":2993, + "title":"I see you", + "references": { "url":"Ref 1,Ref 2", "osvdb":"osvdb", "cve":"2011-001", "secunia":"secunia", "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"FPD", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } + "exploitdb":"exploitdb" + }, + "type":"FPD", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] } ] diff --git a/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json b/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json index 8ed78ed1..e348293e 100644 --- a/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json +++ b/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json @@ -1,42 +1,44 @@ [ { - "3.5":{ - "vulnerabilities":[ - { - "id":2989, - "title":"I should not appear in the results", + "version": "3.5", + "vulnerabilities":[ + { + "id":2989, + "title":"I should not appear in the results", + "references": { "url":"Ref 1,Ref 2", "osvdb":"osvdb", "cve":"2011-001", "secunia":"secunia", "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"XSS", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } + "exploitdb":"exploitdb" + }, + "type":"XSS", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] }, { - "3.2":{ - "vulnerabilities":[ - { - "id":2993, - "title":"Here I Am", + "version": "3.2", + "vulnerabilities":[ + { + "id":2993, + "title":"Here I Am", + "references": { "url":"Ref 1,Ref 2", "osvdb":"osvdb", "cve":"2011-001", "secunia":"secunia", "metasploit":"exploit/ex1", - "exploitdb":"exploitdb", - "type":"SQLI", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } + "exploitdb":"exploitdb" + }, + "type":"SQLI", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] } ] diff --git a/spec/shared_examples/wp_items_detectable.rb b/spec/shared_examples/wp_items_detectable.rb index 574621c0..7376e753 100644 --- a/spec/shared_examples/wp_items_detectable.rb +++ b/spec/shared_examples/wp_items_detectable.rb @@ -70,9 +70,9 @@ shared_examples 'WpItems::Detectable' do end end - describe '::vulnerable_targets_items' do + describe '::target_items' do after do - results = subject.send(:vulnerable_targets_items, wp_target, item_class, vulns_file) + results = subject.send(:target_items, wp_target, item_class, vulns_file, :all) expect(results.map { |i| i.name }).to eq @expected.map { |i| i.name } @@ -100,7 +100,7 @@ shared_examples 'WpItems::Detectable' do end describe '::targets_items' do - let(:options) { {} } + let(:options) { { type: :all } } after do if @expected @@ -111,28 +111,12 @@ shared_examples 'WpItems::Detectable' do end context 'when :only_vulnerable' do - let(:options) { { only_vulnerable: true } } + let(:options) { { type: :vulnerable } } it 'returns the expected Array of WpItem' do @expected = expected[:vulnerable_targets_items] end end - - context 'when not :only_vulnerable' do - context 'when no :file' do - it 'raises an error' do - expect { subject.send(:targets_items, wp_target, options) }.to raise_error('A file must be supplied') - end - end - - context 'when :file' do - let(:options) { { file: targets_items_file } } - - it 'returns the expected Array of WpItem' do - @expected = (expected[:targets_items_from_file] + expected[:vulnerable_targets_items]).uniq {|t| t.name } - end - end - end end describe '::passive_detection' do diff --git a/spec/shared_examples/wp_plugin_vulnerable.rb b/spec/shared_examples/wp_plugin_vulnerable.rb index 44a77f87..d46e854d 100644 --- a/spec/shared_examples/wp_plugin_vulnerable.rb +++ b/spec/shared_examples/wp_plugin_vulnerable.rb @@ -7,7 +7,7 @@ shared_examples 'WpPlugin::Vulnerable' do context 'when :vulns_file is no set' do it 'returns the default one' do - @expected = PLUGINS_VULNS_FILE + @expected = PLUGINS_FILE end end diff --git a/spec/shared_examples/wp_theme_vulnerable.rb b/spec/shared_examples/wp_theme_vulnerable.rb index 8552769a..fc7a4139 100644 --- a/spec/shared_examples/wp_theme_vulnerable.rb +++ b/spec/shared_examples/wp_theme_vulnerable.rb @@ -7,7 +7,7 @@ shared_examples 'WpTheme::Vulnerable' do context 'when :vulns_file is not set' do it 'returns the default one' do - @expected = THEMES_VULNS_FILE + @expected = THEMES_FILE end end diff --git a/spec/shared_examples/wp_version_vulnerable.rb b/spec/shared_examples/wp_version_vulnerable.rb index 1dd14320..428fee24 100644 --- a/spec/shared_examples/wp_version_vulnerable.rb +++ b/spec/shared_examples/wp_version_vulnerable.rb @@ -7,7 +7,7 @@ shared_examples 'WpVersion::Vulnerable' do context 'when :vulns_file is no set' do it 'returns the default one' do - @expected = WP_VULNS_FILE + @expected = WORDPRESSES_FILE end end From d0e868f5566e66fe238578cbc58a1b541f64277f Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Fri, 14 Aug 2015 16:04:26 +0200 Subject: [PATCH 04/15] Enable rspec fail-fast #853 --- .rspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rspec b/.rspec index 9c3c126f..ba44b749 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ --color -#--fail-fast +--fail-fast From 8727935cb2106db663289aab18c0b8de5a6240ec Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Fri, 14 Aug 2015 16:33:57 +0200 Subject: [PATCH 05/15] Fix specs #853 --- .../models/wp_plugin/vulnerable/plugins.json | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 spec/samples/common/models/wp_plugin/vulnerable/plugins.json diff --git a/spec/samples/common/models/wp_plugin/vulnerable/plugins.json b/spec/samples/common/models/wp_plugin/vulnerable/plugins.json new file mode 100644 index 00000000..25159019 --- /dev/null +++ b/spec/samples/common/models/wp_plugin/vulnerable/plugins.json @@ -0,0 +1,60 @@ +[ + { + "name": "mr-smith", + "vulnerabilities":[ + { + "id":2993, + "title":"I should not appear in the results", + "references": { + "url":"Ref 1,Ref 2", + "osvdb":"osvdb", + "cve":"2011-001", + "secunia":"secunia", + "metasploit":"exploit/ex1", + "exploitdb":"exploitdb" + }, + "type":"XSS", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + }, + { + "id":2989, + "title":"Neither do I", + "references": { + "url":"Ref 1,Ref 2", + "osvdb":"osvdb", + "cve":"2011-001", + "secunia":"secunia", + "metasploit":"exploit/ex1", + "exploitdb":"exploitdb" + }, + "type":"XSS", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] + }, + { + "name": "white-rabbit", + "vulnerabilities": [ + { + "id":2993, + "title":"Follow me!", + "references": { + "url":"Ref 1,Ref 2", + "osvdb":"osvdb", + "cve":"2011-001", + "secunia":"secunia", + "metasploit":"exploit/ex1", + "exploitdb":"exploitdb" + }, + "type":"REDIRECT", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] + } +] From 57f6206aeedacdaff0d8ddb17d4c39273634e359 Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Fri, 14 Aug 2015 21:51:55 +0200 Subject: [PATCH 06/15] Implement Erwan's feedbaxk #853 --- lib/common/models/wp_item/vulnerable.rb | 7 ++-- spec/lib/common/models/wp_item_spec.rb | 2 +- spec/lib/common/models/wp_plugin_spec.rb | 2 +- spec/lib/common/models/wp_theme_spec.rb | 2 +- .../wp_item/vulnerable/items_vulns.json | 14 ++++---- .../models/wp_plugin/vulnerable/plugins.json | 36 +++++++++---------- .../wp_theme/vulnerable/themes_vulns.json | 36 +++++++++---------- .../wp_version/vulnerable/versions_vulns.json | 24 ++++++------- 8 files changed, 61 insertions(+), 62 deletions(-) diff --git a/lib/common/models/wp_item/vulnerable.rb b/lib/common/models/wp_item/vulnerable.rb index 4b03eda2..2f4a5fc4 100755 --- a/lib/common/models/wp_item/vulnerable.rb +++ b/lib/common/models/wp_item/vulnerable.rb @@ -9,14 +9,13 @@ class WpItem # # @return [ Vulnerabilities ] def vulnerabilities - json = json(vulns_file).select { |item| !item['vulnerabilities'].empty? } + json = json(vulns_file) vulnerabilities = Vulnerabilities.new json.each do |item| - asset = item['version'][identifier] if item['version'] - asset = item['name'][identifier] if item['name'] + asset = item['version'] || item['name'] - next unless asset + next unless asset == identifier item['vulnerabilities'].each do |vulnerability| vulnerability = Vulnerability.load_from_json_item(vulnerability) diff --git a/spec/lib/common/models/wp_item_spec.rb b/spec/lib/common/models/wp_item_spec.rb index 2cc8f93f..6c2e1aa6 100644 --- a/spec/lib/common/models/wp_item_spec.rb +++ b/spec/lib/common/models/wp_item_spec.rb @@ -15,7 +15,7 @@ describe WpItem do let(:identifier) { 'neo' } let(:expected_refs) { { 'id' => [2993], - 'url' => ['Ref 1,Ref 2'], + 'url' => ['Ref 1', 'Ref 2'], 'cve' => ['2011-001'], 'secunia' => ['secunia'], 'osvdb' => ['osvdb'], diff --git a/spec/lib/common/models/wp_plugin_spec.rb b/spec/lib/common/models/wp_plugin_spec.rb index 6b740667..37848946 100644 --- a/spec/lib/common/models/wp_plugin_spec.rb +++ b/spec/lib/common/models/wp_plugin_spec.rb @@ -9,7 +9,7 @@ describe WpPlugin do let(:vulns_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins.json' } let(:expected_refs) { { 'id' => [2993], - 'url' => ['Ref 1,Ref 2'], + 'url' => ['Ref 1', 'Ref 2'], 'cve' => ['2011-001'], 'secunia' => ['secunia'], 'osvdb' => ['osvdb'], diff --git a/spec/lib/common/models/wp_theme_spec.rb b/spec/lib/common/models/wp_theme_spec.rb index 2809464d..a11b7959 100644 --- a/spec/lib/common/models/wp_theme_spec.rb +++ b/spec/lib/common/models/wp_theme_spec.rb @@ -10,7 +10,7 @@ describe WpTheme do let(:vulns_file) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.json' } let(:expected_refs) { { 'id' => [2993], - 'url' => ['Ref 1,Ref 2'], + 'url' => ['Ref 1', 'Ref 2'], 'cve' => ['2011-001'], 'secunia' => ['secunia'], 'osvdb' => ['osvdb'], diff --git a/spec/samples/common/models/wp_item/vulnerable/items_vulns.json b/spec/samples/common/models/wp_item/vulnerable/items_vulns.json index 4c9a3b2e..1d1685cc 100644 --- a/spec/samples/common/models/wp_item/vulnerable/items_vulns.json +++ b/spec/samples/common/models/wp_item/vulnerable/items_vulns.json @@ -6,7 +6,7 @@ "id":2989, "title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1", "references": { - "url":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com" + "url": ["https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/" ,"http://www.example.com"] }, "created_at":"2014-07-28T12:10:07.000Z", "updated_at":"2014-07-28T12:43:41.000Z" @@ -20,12 +20,12 @@ "id":2993, "title":"I'm the one", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"XSS", "fixed_in":"", diff --git a/spec/samples/common/models/wp_plugin/vulnerable/plugins.json b/spec/samples/common/models/wp_plugin/vulnerable/plugins.json index 25159019..fbd1ce83 100644 --- a/spec/samples/common/models/wp_plugin/vulnerable/plugins.json +++ b/spec/samples/common/models/wp_plugin/vulnerable/plugins.json @@ -6,12 +6,12 @@ "id":2993, "title":"I should not appear in the results", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1","Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"XSS", "fixed_in":"", @@ -22,12 +22,12 @@ "id":2989, "title":"Neither do I", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1" ,"Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"XSS", "fixed_in":"", @@ -43,12 +43,12 @@ "id":2993, "title":"Follow me!", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"REDIRECT", "fixed_in":"", diff --git a/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json b/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json index accd3061..b4cff81a 100644 --- a/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json +++ b/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json @@ -6,12 +6,12 @@ "id":2989, "title":"I should not appear in the results", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"XSS", "fixed_in":"", @@ -22,12 +22,12 @@ "id":2989, "title":"Neither do I", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"XSS", "fixed_in":"", @@ -43,12 +43,12 @@ "id":2993, "title":"I see you", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"FPD", "fixed_in":"", diff --git a/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json b/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json index e348293e..8df891a6 100644 --- a/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json +++ b/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json @@ -6,12 +6,12 @@ "id":2989, "title":"I should not appear in the results", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"XSS", "fixed_in":"", @@ -27,12 +27,12 @@ "id":2993, "title":"Here I Am", "references": { - "url":"Ref 1,Ref 2", - "osvdb":"osvdb", - "cve":"2011-001", - "secunia":"secunia", - "metasploit":"exploit/ex1", - "exploitdb":"exploitdb" + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] }, "type":"SQLI", "fixed_in":"", From e6d29f6f186e4d0a42fd2246c45e0cd85bfec209 Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Thu, 3 Sep 2015 22:04:44 +0200 Subject: [PATCH 07/15] New json structure implemented #853 --- lib/common/collections/wp_items/detectable.rb | 10 ++-- lib/common/models/wp_item/vulnerable.rb | 16 ++----- .../wp_items/detectable/vulns.json | 10 ++-- .../wp_plugins/detectable/vulns.json | 10 ++-- .../wp_themes/detectable/vulns.json | 11 ++--- .../wp_item/vulnerable/items_vulns.json | 10 ++-- .../models/wp_plugin/vulnerable/plugins.json | 48 +++++++++---------- .../wp_theme/vulnerable/themes_vulns.json | 47 +++++++++--------- .../wp_version/vulnerable/versions_vulns.json | 12 ++--- 9 files changed, 78 insertions(+), 96 deletions(-) diff --git a/lib/common/collections/wp_items/detectable.rb b/lib/common/collections/wp_items/detectable.rb index cbcfd47d..1085e748 100755 --- a/lib/common/collections/wp_items/detectable.rb +++ b/lib/common/collections/wp_items/detectable.rb @@ -172,19 +172,19 @@ class WpItems < Array case type when :vulnerable - item_names = json.select { |item| !item['vulnerabilities'].empty? }.map {|item| item['name'] } + items = json.select { |item| !json[item]['vulnerabilities'].empty? } when :popular - item_names = json.select { |item| item['popular'] == true }.map {|item| item['name'] } + items = json.select { |item| json[item]['popular'] == true } when :all - item_names = [*json].map { |item| item['name'] } + items = [*json] else raise "Unknown type #{type}" end - item_names.each do |item_name| + items.each do |item| targets << create_item( item_class, - item_name, + item[0], wp_target, vulns_file ) diff --git a/lib/common/models/wp_item/vulnerable.rb b/lib/common/models/wp_item/vulnerable.rb index 2f4a5fc4..a62aa33f 100755 --- a/lib/common/models/wp_item/vulnerable.rb +++ b/lib/common/models/wp_item/vulnerable.rb @@ -8,21 +8,15 @@ class WpItem # Filters out already fixed vulnerabilities # # @return [ Vulnerabilities ] - def vulnerabilities + def vulnerabilities json = json(vulns_file) vulnerabilities = Vulnerabilities.new - json.each do |item| - asset = item['version'] || item['name'] + return vulnerabilities if json.empty? - next unless asset == identifier - - item['vulnerabilities'].each do |vulnerability| - vulnerability = Vulnerability.load_from_json_item(vulnerability) - vulnerabilities << vulnerability if vulnerable_to?(vulnerability) - end - - break # No need to iterate any further + json[identifier]['vulnerabilities'].each do |vulnerability| + vulnerability = Vulnerability.load_from_json_item(vulnerability) + vulnerabilities << vulnerability if vulnerable_to?(vulnerability) end vulnerabilities diff --git a/spec/samples/common/collections/wp_items/detectable/vulns.json b/spec/samples/common/collections/wp_items/detectable/vulns.json index ebd99762..80ee2ba6 100644 --- a/spec/samples/common/collections/wp_items/detectable/vulns.json +++ b/spec/samples/common/collections/wp_items/detectable/vulns.json @@ -1,6 +1,5 @@ -[ - { - "name": "mr-smith", +{ + "mr-smith": { "vulnerabilities":[ { "id":2989, @@ -48,8 +47,7 @@ } ] }, - { - "name": "neo", + "neo": { "vulnerabilities":[ { "id":2993, @@ -63,4 +61,4 @@ } ] } -] \ No newline at end of file +} diff --git a/spec/samples/common/collections/wp_plugins/detectable/vulns.json b/spec/samples/common/collections/wp_plugins/detectable/vulns.json index 53777e54..6b0e28cc 100644 --- a/spec/samples/common/collections/wp_plugins/detectable/vulns.json +++ b/spec/samples/common/collections/wp_plugins/detectable/vulns.json @@ -1,6 +1,5 @@ -[ - { - "name": "mr-smith", +{ + "mr-smith": { "vulnerabilities":[ { "id":2989, @@ -48,8 +47,7 @@ } ] }, - { - "name":"neo", + "neo": { "vulnerabilities":[ { "id":2993, @@ -63,4 +61,4 @@ } ] } -] \ No newline at end of file +} diff --git a/spec/samples/common/collections/wp_themes/detectable/vulns.json b/spec/samples/common/collections/wp_themes/detectable/vulns.json index fdcc83dc..086ae752 100644 --- a/spec/samples/common/collections/wp_themes/detectable/vulns.json +++ b/spec/samples/common/collections/wp_themes/detectable/vulns.json @@ -1,6 +1,5 @@ -[ - { - "name": "shopperpress", +{ + "shopperpress": { "vulnerabilities":[ { "id":2989, @@ -48,8 +47,7 @@ } ] }, - { - "name": "webfolio", + "webfolio": { "vulnerabilities":[ { "id":2993, @@ -63,4 +61,5 @@ } ] } -] +} + diff --git a/spec/samples/common/models/wp_item/vulnerable/items_vulns.json b/spec/samples/common/models/wp_item/vulnerable/items_vulns.json index 1d1685cc..b221ffc9 100644 --- a/spec/samples/common/models/wp_item/vulnerable/items_vulns.json +++ b/spec/samples/common/models/wp_item/vulnerable/items_vulns.json @@ -1,6 +1,5 @@ -[ - { - "name": "not-this-one", +{ + "not-this-one": { "vulnerabilities":[ { "id":2989, @@ -13,8 +12,7 @@ } ] }, - { - "name": "neo", + "neo": { "vulnerabilities":[ { "id":2993, @@ -34,4 +32,4 @@ } ] } -] \ No newline at end of file +} diff --git a/spec/samples/common/models/wp_plugin/vulnerable/plugins.json b/spec/samples/common/models/wp_plugin/vulnerable/plugins.json index fbd1ce83..7498bd34 100644 --- a/spec/samples/common/models/wp_plugin/vulnerable/plugins.json +++ b/spec/samples/common/models/wp_plugin/vulnerable/plugins.json @@ -1,6 +1,5 @@ -[ - { - "name": "mr-smith", +{ + "mr-smith": { "vulnerabilities":[ { "id":2993, @@ -36,25 +35,24 @@ } ] }, - { - "name": "white-rabbit", - "vulnerabilities": [ - { - "id":2993, - "title":"Follow me!", - "references": { - "url": ["Ref 1", "Ref 2"], - "osvdb": ["osvdb"], - "cve": ["2011-001"], - "secunia": ["secunia"], - "metasploit": ["exploit/ex1"], - "exploitdb": ["exploitdb"] - }, - "type":"REDIRECT", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] - } -] + "white-rabbit": { + "vulnerabilities": [ + { + "id":2993, + "title":"Follow me!", + "references": { + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] + }, + "type":"REDIRECT", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] + } +} diff --git a/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json b/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json index b4cff81a..c123ae9f 100644 --- a/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json +++ b/spec/samples/common/models/wp_theme/vulnerable/themes_vulns.json @@ -1,6 +1,5 @@ -[ - { - "name": "mr-smith", +{ + "mr-smith": { "vulnerabilities":[ { "id":2989, @@ -36,25 +35,25 @@ } ] }, - { - "name": "the-oracle", - "vulnerabilities":[ - { - "id":2993, - "title":"I see you", - "references": { - "url": ["Ref 1", "Ref 2"], - "osvdb": ["osvdb"], - "cve": ["2011-001"], - "secunia": ["secunia"], - "metasploit": ["exploit/ex1"], - "exploitdb": ["exploitdb"] - }, - "type":"FPD", - "fixed_in":"", - "created_at":"2014-07-28T12:10:07.000Z", - "updated_at":"2014-07-28T12:10:07.000Z" - } - ] + "the-oracle": { + "vulnerabilities":[ + { + "id":2993, + "title":"I see you", + "references": { + "url": ["Ref 1", "Ref 2"], + "osvdb": ["osvdb"], + "cve": ["2011-001"], + "secunia": ["secunia"], + "metasploit": ["exploit/ex1"], + "exploitdb": ["exploitdb"] + }, + "type":"FPD", + "fixed_in":"", + "created_at":"2014-07-28T12:10:07.000Z", + "updated_at":"2014-07-28T12:10:07.000Z" + } + ] } -] +} + diff --git a/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json b/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json index 8df891a6..2d2407e4 100644 --- a/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json +++ b/spec/samples/common/models/wp_version/vulnerable/versions_vulns.json @@ -1,6 +1,5 @@ -[ - { - "version": "3.5", +{ + "3.5": { "vulnerabilities":[ { "id":2989, @@ -19,9 +18,8 @@ "updated_at":"2014-07-28T12:10:07.000Z" } ] - }, - { - "version": "3.2", + }, + "3.2": { "vulnerabilities":[ { "id":2993, @@ -41,4 +39,4 @@ } ] } -] +} From db528b27f4bcbd9d5eb72611ddedc496acfc61c1 Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Sat, 5 Sep 2015 13:49:03 +0200 Subject: [PATCH 08/15] Implement Erwan's feedback #853 --- lib/common/collections/wp_items/detectable.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/common/collections/wp_items/detectable.rb b/lib/common/collections/wp_items/detectable.rb index 1085e748..8d54234f 100755 --- a/lib/common/collections/wp_items/detectable.rb +++ b/lib/common/collections/wp_items/detectable.rb @@ -172,11 +172,11 @@ class WpItems < Array case type when :vulnerable - items = json.select { |item| !json[item]['vulnerabilities'].empty? } + items = json.select { |item| !json[item]['vulnerabilities'].empty? }.keys when :popular - items = json.select { |item| json[item]['popular'] == true } + items = json.select { |item| json[item]['popular'] == true }.keys when :all - items = [*json] + items = json.keys else raise "Unknown type #{type}" end @@ -184,7 +184,7 @@ class WpItems < Array items.each do |item| targets << create_item( item_class, - item[0], + item, wp_target, vulns_file ) From d31d45ba7167041b14219766d889e106763fc493 Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Sat, 5 Sep 2015 14:10:08 +0200 Subject: [PATCH 09/15] Remove unneede newline --- lib/common/models/wp_item.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/common/models/wp_item.rb b/lib/common/models/wp_item.rb index 81f00691..651d19b9 100755 --- a/lib/common/models/wp_item.rb +++ b/lib/common/models/wp_item.rb @@ -30,7 +30,6 @@ class WpItem # # @return [ WpItem ] def initialize(target_base_uri, options = {}) - options[:wp_content_dir] ||= 'wp-content' options[:wp_plugins_dir] ||= options[:wp_content_dir] + '/plugins' From c03a44d2259acf120af6474078ad19db197f0d8c Mon Sep 17 00:00:00 2001 From: erwanlr Date: Sun, 6 Sep 2015 13:32:08 +0100 Subject: [PATCH 10/15] Removes useless code --- lib/common/models/wp_plugin/vulnerable.rb | 7 +------ lib/common/models/wp_theme/vulnerable.rb | 6 +----- lib/common/models/wp_version/vulnerable.rb | 6 +----- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/lib/common/models/wp_plugin/vulnerable.rb b/lib/common/models/wp_plugin/vulnerable.rb index c19e6c07..f9eb4ac3 100644 --- a/lib/common/models/wp_plugin/vulnerable.rb +++ b/lib/common/models/wp_plugin/vulnerable.rb @@ -2,19 +2,14 @@ class WpPlugin < WpItem module Vulnerable - # @return [ String ] The path to the file containing vulnerabilities def vulns_file - unless @vulns_file - @vulns_file = PLUGINS_FILE - end - @vulns_file + @vulns_file ||= PLUGINS_FILE end # @return [ String ] def identifier @name end - end end diff --git a/lib/common/models/wp_theme/vulnerable.rb b/lib/common/models/wp_theme/vulnerable.rb index 60e5560c..a38bfd80 100644 --- a/lib/common/models/wp_theme/vulnerable.rb +++ b/lib/common/models/wp_theme/vulnerable.rb @@ -2,13 +2,9 @@ class WpTheme < WpItem module Vulnerable - # @return [ String ] The path to the file containing vulnerabilities def vulns_file - unless @vulns_file - @vulns_file = THEMES_FILE - end - @vulns_file + @vulns_file ||= THEMES_FILE end # @return [ String ] diff --git a/lib/common/models/wp_version/vulnerable.rb b/lib/common/models/wp_version/vulnerable.rb index da23790b..53b56ad3 100644 --- a/lib/common/models/wp_version/vulnerable.rb +++ b/lib/common/models/wp_version/vulnerable.rb @@ -2,13 +2,9 @@ class WpVersion < WpItem module Vulnerable - # @return [ String ] The path to the file containing vulnerabilities def vulns_file - unless @vulns_file - @vulns_file = WORDPRESSES_FILE - end - @vulns_file + @vulns_file ||= WORDPRESSES_FILE end # @return [ String ] From fd0c47f5d74d4abafde03d6e00ffeb00c0f3e05a Mon Sep 17 00:00:00 2001 From: erwanlr Date: Sun, 6 Sep 2015 14:23:33 +0100 Subject: [PATCH 11/15] Adds the latest_version, last_updated and popular? attributes - Ref #853 --- lib/common/models/wp_item.rb | 23 ++++++++++++++++++- lib/common/models/wp_item/output.rb | 4 ++-- lib/common/models/wp_item/vulnerable.rb | 13 +++++------ lib/common/models/wp_plugin.rb | 7 +++--- lib/common/models/wp_plugin/vulnerable.rb | 15 ------------ lib/common/models/wp_theme.rb | 5 ++-- lib/common/models/wp_theme/vulnerable.rb | 15 ------------ lib/common/models/wp_version.rb | 11 ++++++--- lib/common/models/wp_version/vulnerable.rb | 15 ------------ spec/lib/common/models/wp_item_spec.rb | 2 +- spec/lib/common/models/wp_plugin_spec.rb | 4 ++-- spec/lib/common/models/wp_theme_spec.rb | 2 +- spec/shared_examples/wp_item_vulnerable.rb | 16 ++++++------- spec/shared_examples/wp_plugin_vulnerable.rb | 14 +++++------ spec/shared_examples/wp_theme_vulnerable.rb | 14 +++++------ spec/shared_examples/wp_version_vulnerable.rb | 14 +++++------ 16 files changed, 77 insertions(+), 97 deletions(-) delete mode 100644 lib/common/models/wp_plugin/vulnerable.rb delete mode 100644 lib/common/models/wp_theme/vulnerable.rb delete mode 100644 lib/common/models/wp_version/vulnerable.rb diff --git a/lib/common/models/wp_item.rb b/lib/common/models/wp_item.rb index 651d19b9..5176c30d 100755 --- a/lib/common/models/wp_item.rb +++ b/lib/common/models/wp_item.rb @@ -22,7 +22,7 @@ class WpItem # @return [ Array ] # Make it private ? def allowed_options - [:name, :wp_content_dir, :wp_plugins_dir, :path, :version, :vulns_file] + [:name, :wp_content_dir, :wp_plugins_dir, :path, :version, :db_file] end # @param [ URI ] target_base_uri @@ -37,6 +37,27 @@ class WpItem forge_uri(target_base_uri) end + def identifier + @identifier ||= name + end + + # @return [ Hash ] + def db_data + @db_data ||= json(db_file)[identifier] || {} + end + + def latest_version + db_data['latest_version'] + end + + def last_updated + db_data['last_ipdated'] + end + + def popular? + db_data['popular'] + end + # @param [ Hash ] options # # @return [ void ] diff --git a/lib/common/models/wp_item/output.rb b/lib/common/models/wp_item/output.rb index 17e8f219..4d749017 100644 --- a/lib/common/models/wp_item/output.rb +++ b/lib/common/models/wp_item/output.rb @@ -7,8 +7,8 @@ class WpItem def output(verbose = false) puts puts info("Name: #{self}") #this will also output the version number if detected - puts " | Latest version:" - puts " | Last updated:" + puts " | Latest version: #{latest_version}" if latest_version + puts " | Last updated: #{last_updated}" if last_updated puts " | Location: #{url}" #puts " | WordPress: #{wordpress_url}" if wordpress_org_item? puts " | Readme: #{readme_url}" if has_readme? diff --git a/lib/common/models/wp_item/vulnerable.rb b/lib/common/models/wp_item/vulnerable.rb index a62aa33f..25c2413f 100755 --- a/lib/common/models/wp_item/vulnerable.rb +++ b/lib/common/models/wp_item/vulnerable.rb @@ -2,24 +2,23 @@ class WpItem module Vulnerable - attr_accessor :vulns_file, :identifier + attr_accessor :db_file, :identifier # Get the vulnerabilities associated to the WpItem # Filters out already fixed vulnerabilities # # @return [ Vulnerabilities ] def vulnerabilities - json = json(vulns_file) - vulnerabilities = Vulnerabilities.new + return @vulnerabilities if @vulnerabilities - return vulnerabilities if json.empty? + @vulnerabilities = Vulnerabilities.new - json[identifier]['vulnerabilities'].each do |vulnerability| + [*db_data['vulnerabilities']].each do |vulnerability| vulnerability = Vulnerability.load_from_json_item(vulnerability) - vulnerabilities << vulnerability if vulnerable_to?(vulnerability) + @vulnerabilities << vulnerability if vulnerable_to?(vulnerability) end - vulnerabilities + @vulnerabilities end def vulnerable? diff --git a/lib/common/models/wp_plugin.rb b/lib/common/models/wp_plugin.rb index bfc29200..8c47e158 100755 --- a/lib/common/models/wp_plugin.rb +++ b/lib/common/models/wp_plugin.rb @@ -1,10 +1,6 @@ # encoding: UTF-8 -require 'wp_plugin/vulnerable' - class WpPlugin < WpItem - include WpPlugin::Vulnerable - # Sets the @uri # # @param [ URI ] target_base_uri The URI of the wordpress blog @@ -14,4 +10,7 @@ class WpPlugin < WpItem @uri = target_base_uri.merge(URI.encode(wp_plugins_dir + '/' + name + '/')) end + def db_file + @db_file ||= PLUGINS_FILE + end end diff --git a/lib/common/models/wp_plugin/vulnerable.rb b/lib/common/models/wp_plugin/vulnerable.rb deleted file mode 100644 index f9eb4ac3..00000000 --- a/lib/common/models/wp_plugin/vulnerable.rb +++ /dev/null @@ -1,15 +0,0 @@ -# encoding: UTF-8 - -class WpPlugin < WpItem - module Vulnerable - # @return [ String ] The path to the file containing vulnerabilities - def vulns_file - @vulns_file ||= PLUGINS_FILE - end - - # @return [ String ] - def identifier - @name - end - end -end diff --git a/lib/common/models/wp_theme.rb b/lib/common/models/wp_theme.rb index 81f62a77..0a8a478b 100755 --- a/lib/common/models/wp_theme.rb +++ b/lib/common/models/wp_theme.rb @@ -2,7 +2,6 @@ require 'wp_theme/findable' require 'wp_theme/versionable' -require 'wp_theme/vulnerable' require 'wp_theme/info' require 'wp_theme/output' require 'wp_theme/childtheme' @@ -10,7 +9,6 @@ require 'wp_theme/childtheme' class WpTheme < WpItem extend WpTheme::Findable include WpTheme::Versionable - include WpTheme::Vulnerable include WpTheme::Info include WpTheme::Output include WpTheme::Childtheme @@ -33,4 +31,7 @@ class WpTheme < WpItem @uri.merge('style.css').to_s end + def db_file + @db_file ||= THEMES_FILE + end end diff --git a/lib/common/models/wp_theme/vulnerable.rb b/lib/common/models/wp_theme/vulnerable.rb deleted file mode 100644 index a38bfd80..00000000 --- a/lib/common/models/wp_theme/vulnerable.rb +++ /dev/null @@ -1,15 +0,0 @@ -# encoding: UTF-8 - -class WpTheme < WpItem - module Vulnerable - # @return [ String ] The path to the file containing vulnerabilities - def vulns_file - @vulns_file ||= THEMES_FILE - end - - # @return [ String ] - def identifier - @name - end - end -end diff --git a/lib/common/models/wp_version.rb b/lib/common/models/wp_version.rb index cdf38043..2c18161a 100755 --- a/lib/common/models/wp_version.rb +++ b/lib/common/models/wp_version.rb @@ -1,13 +1,10 @@ # encoding: UTF-8 require 'wp_version/findable' -require 'wp_version/vulnerable' require 'wp_version/output' class WpVersion < WpItem - extend WpVersion::Findable - include WpVersion::Vulnerable include WpVersion::Output # The version number @@ -17,6 +14,14 @@ class WpVersion < WpItem # @return [ Array ] def allowed_options; super << :number << :found_from end + def identifier + @identifier ||= number + end + + def db_file + @db_file ||= WORDPRESSES_FILE + end + # @param [ WpVersion ] other # # @return [ Boolean ] diff --git a/lib/common/models/wp_version/vulnerable.rb b/lib/common/models/wp_version/vulnerable.rb deleted file mode 100644 index 53b56ad3..00000000 --- a/lib/common/models/wp_version/vulnerable.rb +++ /dev/null @@ -1,15 +0,0 @@ -# encoding: UTF-8 - -class WpVersion < WpItem - module Vulnerable - # @return [ String ] The path to the file containing vulnerabilities - def vulns_file - @vulns_file ||= WORDPRESSES_FILE - end - - # @return [ String ] - def identifier - @number - end - end -end diff --git a/spec/lib/common/models/wp_item_spec.rb b/spec/lib/common/models/wp_item_spec.rb index 6c2e1aa6..3af882d8 100644 --- a/spec/lib/common/models/wp_item_spec.rb +++ b/spec/lib/common/models/wp_item_spec.rb @@ -11,7 +11,7 @@ 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.json' } + let(:db_file) { MODELS_FIXTURES + '/wp_item/vulnerable/items_vulns.json' } let(:identifier) { 'neo' } let(:expected_refs) { { 'id' => [2993], diff --git a/spec/lib/common/models/wp_plugin_spec.rb b/spec/lib/common/models/wp_plugin_spec.rb index 37848946..bc88247c 100644 --- a/spec/lib/common/models/wp_plugin_spec.rb +++ b/spec/lib/common/models/wp_plugin_spec.rb @@ -5,8 +5,8 @@ require 'spec_helper' 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.json' } + let(:options) { { name: 'white-rabbit' } } + let(:db_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins.json' } let(:expected_refs) { { 'id' => [2993], 'url' => ['Ref 1', 'Ref 2'], diff --git a/spec/lib/common/models/wp_theme_spec.rb b/spec/lib/common/models/wp_theme_spec.rb index a11b7959..2c7986e5 100644 --- a/spec/lib/common/models/wp_theme_spec.rb +++ b/spec/lib/common/models/wp_theme_spec.rb @@ -7,7 +7,7 @@ describe WpTheme do 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.json' } + let(:db_file) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.json' } let(:expected_refs) { { 'id' => [2993], 'url' => ['Ref 1', 'Ref 2'], diff --git a/spec/shared_examples/wp_item_vulnerable.rb b/spec/shared_examples/wp_item_vulnerable.rb index 1bf2e7d1..e062c735 100644 --- a/spec/shared_examples/wp_item_vulnerable.rb +++ b/spec/shared_examples/wp_item_vulnerable.rb @@ -3,8 +3,8 @@ shared_examples 'WpItem::Vulnerable' do # 2 variables have to be set in the described class or subject: - # let(:vulns_file) { } - # let(:expected_vulns) { } The expected Vulnerabilities when using vulns_file and vulns_xpath + # let(:db_file) { } + # let(:expected_vulns) { } The expected Vulnerabilities when using db_file and vulns_xpath # # 1 variable is optional, used if supplied, otherwise subject.vulns_xpath is used # let(:vulns_xpath) { } @@ -18,7 +18,7 @@ shared_examples 'WpItem::Vulnerable' do end after do - subject.vulns_file = @vulns_file + subject.db_file = @db_file subject.identifier = identifier if defined?(identifier) result = subject.vulnerabilities @@ -26,16 +26,16 @@ shared_examples 'WpItem::Vulnerable' do expect(result).to eq @expected end - context 'when the vulns_file is empty' do + context 'when the db_file is empty' do it 'returns an empty Vulnerabilities' do - @vulns_file = empty_file - @expected = Vulnerabilities.new + @db_file = empty_file + @expected = Vulnerabilities.new end end it 'returns the expected vulnerabilities' do - @vulns_file = vulns_file - @expected = expected_vulns + @db_file = db_file + @expected = expected_vulns end end diff --git a/spec/shared_examples/wp_plugin_vulnerable.rb b/spec/shared_examples/wp_plugin_vulnerable.rb index d46e854d..5569f603 100644 --- a/spec/shared_examples/wp_plugin_vulnerable.rb +++ b/spec/shared_examples/wp_plugin_vulnerable.rb @@ -2,25 +2,25 @@ shared_examples 'WpPlugin::Vulnerable' do - describe '#vulns_file' do - after { expect(subject.vulns_file).to eq @expected } + describe '#db_file' do + after { expect(subject.db_file).to eq @expected } - context 'when :vulns_file is no set' do + context 'when :db_file is no set' do it 'returns the default one' do @expected = PLUGINS_FILE end end - context 'when the :vulns_file is already set' do + context 'when the :db_file is already set' do it 'returns it' do - @expected = 'test.json' - subject.vulns_file = @expected + @expected = 'test.json' + subject.db_file = @expected end end end describe '#identifier' do - its(:identifier) { is_expected.to eq 'plugin-name' } + its(:identifier) { should eq 'plugin-name' } end end diff --git a/spec/shared_examples/wp_theme_vulnerable.rb b/spec/shared_examples/wp_theme_vulnerable.rb index fc7a4139..032a8408 100644 --- a/spec/shared_examples/wp_theme_vulnerable.rb +++ b/spec/shared_examples/wp_theme_vulnerable.rb @@ -2,25 +2,25 @@ shared_examples 'WpTheme::Vulnerable' do - describe '#vulns_file' do - after { expect(subject.vulns_file).to eq @expected } + describe '#db_file' do + after { expect(subject.db_file).to eq @expected } - context 'when :vulns_file is not set' do + context 'when :db_file is not set' do it 'returns the default one' do @expected = THEMES_FILE end end - context 'when the :vulns_file is already set' do + context 'when the :db_file is already set' do it 'returns it' do - @expected = 'test.json' - subject.vulns_file = @expected + @expected = 'test.json' + subject.db_file = @expected end end end describe '#identifier' do - its(:identifier) { is_expected.to eq 'theme-name' } + its(:identifier) { should eq 'theme-name' } end end diff --git a/spec/shared_examples/wp_version_vulnerable.rb b/spec/shared_examples/wp_version_vulnerable.rb index 428fee24..a98b36ed 100644 --- a/spec/shared_examples/wp_version_vulnerable.rb +++ b/spec/shared_examples/wp_version_vulnerable.rb @@ -2,25 +2,25 @@ shared_examples 'WpVersion::Vulnerable' do - describe '#vulns_file' do - after { expect(subject.vulns_file).to eq @expected } + describe '#db_file' do + after { expect(subject.db_file).to eq @expected } - context 'when :vulns_file is no set' do + context 'when :db_file is no set' do it 'returns the default one' do @expected = WORDPRESSES_FILE end end - context 'when the :vulns_file is already set' do + context 'when the :db_file is already set' do it 'returns it' do - @expected = 'test.json' - subject.vulns_file = @expected + @expected = 'test.json' + subject.db_file = @expected end end end describe '#identifier' do - its(:identifier) { is_expected.to eq '1.2' } + its(:identifier) { should eq '1.2' } end end From 3c92712a6eae1f5c728940acd9a95b27e6700663 Mon Sep 17 00:00:00 2001 From: erwanlr Date: Sun, 6 Sep 2015 14:29:41 +0100 Subject: [PATCH 12/15] Uses yajl as JSON parser to reduce memory used --- Gemfile | 2 +- lib/environment.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 134b17ec..51f2fa45 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' gem 'typhoeus', '~>0.7.0' gem 'nokogiri' gem 'addressable' -gem 'json' +gem 'yajl-ruby' # Better JSON parser regarding memory usage gem 'terminal-table', '~>1.4.5' gem 'ruby-progressbar', '>=1.6.0' diff --git a/lib/environment.rb b/lib/environment.rb index 46270890..85ae571d 100644 --- a/lib/environment.rb +++ b/lib/environment.rb @@ -31,7 +31,7 @@ begin require 'pathname' # Third party libs require 'typhoeus' - require 'json' + require 'yajl/json_gem' require 'nokogiri' require 'terminal-table' require 'ruby-progressbar' From aa464b476c4e7d6ddabcfba8635d9220ebe405bc Mon Sep 17 00:00:00 2001 From: erwanlr Date: Sun, 6 Sep 2015 15:25:29 +0100 Subject: [PATCH 13/15] Fixes a bug where -e vp was displaying non vulnerable plugins - Ref #853 --- lib/common/collections/wp_items/detectable.rb | 12 ++-- spec/shared_examples/wp_items_detectable.rb | 68 ++----------------- 2 files changed, 8 insertions(+), 72 deletions(-) diff --git a/lib/common/collections/wp_items/detectable.rb b/lib/common/collections/wp_items/detectable.rb index 8d54234f..e10a1990 100755 --- a/lib/common/collections/wp_items/detectable.rb +++ b/lib/common/collections/wp_items/detectable.rb @@ -32,11 +32,7 @@ class WpItems < Array progress_bar.progress += 1 if options[:show_progression] if target_item.exists?(exist_options, response) - unless results.include?(target_item) - if !options[:only_vulnerable] || options[:only_vulnerable] && target_item.vulnerable? - results << target_item - end - end + results << target_item unless results.include?(target_item) end end @@ -53,7 +49,7 @@ class WpItems < Array # run the remaining requests hydra.run - results.select!(&:vulnerable?) if options[:only_vulnerable] + results.select!(&:vulnerable?) if options[:type] == :vulnerable results.sort! results # can't just return results.sort as it would return an array, and we want a WpItems @@ -155,7 +151,7 @@ class WpItems < Array item_class = self.item_class vulns_file = self.vulns_file - targets = target_items(wp_target, item_class, vulns_file, options[:type]) + targets = target_items_from_type(wp_target, item_class, vulns_file, options[:type]) targets.uniq! { |t| t.name } targets.sort_by { rand } @@ -166,7 +162,7 @@ class WpItems < Array # @param [ String ] vulns_file # # @return [ Array ] - def target_items(wp_target, item_class, vulns_file, type) + def target_items_from_type(wp_target, item_class, vulns_file, type) targets = [] json = json(vulns_file) diff --git a/spec/shared_examples/wp_items_detectable.rb b/spec/shared_examples/wp_items_detectable.rb index 7376e753..883f4a80 100644 --- a/spec/shared_examples/wp_items_detectable.rb +++ b/spec/shared_examples/wp_items_detectable.rb @@ -39,66 +39,6 @@ shared_examples 'WpItems::Detectable' do end end - describe '::targets_items_from_file' do - after do - results = subject.send(:targets_items_from_file, file, wp_target, item_class, vulns_file) - - expect(results.map { |i| i.name }).to eq @expected.map { |i| i.name } - - unless results.empty? - results.each do |item| - expect(item).to be_a item_class - end - end - end - - # should raise error. - # context 'when an empty file' do - # let(:file) { empty_file } - - # it 'returns an empty Array' do - # @expected = [] - # end - # end - - context 'when a file' do - let(:file) { targets_items_file } - - it 'returns the expected Array of WpItem' do - @expected = expected[:targets_items_from_file] - end - end - end - - describe '::target_items' do - after do - results = subject.send(:target_items, wp_target, item_class, vulns_file, :all) - - expect(results.map { |i| i.name }).to eq @expected.map { |i| i.name } - - unless results.empty? - results.each do |item| - expect(item).to be_a item_class - end - end - end - - # should raise error. - # context 'when an empty file' do - # let(:file) { empty_file } - - # it 'returns an empty Array' do - # @expected = [] - # end - # end - - context 'when a file' do - it 'returns the expected Array of WpItem' do - @expected = expected[:vulnerable_targets_items] - end - end - end - describe '::targets_items' do let(:options) { { type: :all } } @@ -110,7 +50,7 @@ shared_examples 'WpItems::Detectable' do end end - context 'when :only_vulnerable' do + context 'when :type = :vulnerable' do let(:options) { { type: :vulnerable } } it 'returns the expected Array of WpItem' do @@ -160,8 +100,8 @@ shared_examples 'WpItems::Detectable' do expect(result.sort.map { |i| i.name }).to eq @expected.sort.map { |i| i.name } end - context 'when :only_vulnerable' do - let(:options) { { only_vulnerable: true } } + context 'when :type = :vulnerable' do + let(:options) { { type: :vulnerable } } let(:targets) { expected[:vulnerable_targets_items] } it 'only checks and return vulnerable targets' do @@ -191,7 +131,7 @@ shared_examples 'WpItems::Detectable' do end end - context 'when no :only_vulnerable' do + context 'when no :type = :vulnerable' do let(:targets) { (expected[:vulnerable_targets_items] + expected[:targets_items_from_file]).uniq { |t| t.name } } it 'checks all targets, and merge the results with passive_detection' do From a4a14c7e632964562978382776b4196ac5e79ee6 Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Tue, 8 Sep 2015 17:24:10 +0200 Subject: [PATCH 14/15] Better version output #862 --- lib/common/models/wp_item/infos.rb | 5 +++++ lib/common/models/wp_item/output.rb | 5 +++-- spec/shared_examples/wp_item_infos.rb | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/common/models/wp_item/infos.rb b/lib/common/models/wp_item/infos.rb index 1724b695..df9b92b2 100644 --- a/lib/common/models/wp_item/infos.rb +++ b/lib/common/models/wp_item/infos.rb @@ -10,6 +10,11 @@ class WpItem !readme_url.nil? end + # @return [ Boolean ] + def outdated?(installed_version, latest_version) + installed_version < latest_version + end + # @return [ String,nil ] The url to the readme file, nil if not found def readme_url # See https://github.com/wpscanteam/wpscan/pull/737#issuecomment-66375445 diff --git a/lib/common/models/wp_item/output.rb b/lib/common/models/wp_item/output.rb index 4d749017..b6cccd8e 100644 --- a/lib/common/models/wp_item/output.rb +++ b/lib/common/models/wp_item/output.rb @@ -7,12 +7,13 @@ class WpItem def output(verbose = false) puts puts info("Name: #{self}") #this will also output the version number if detected - puts " | Latest version: #{latest_version}" if latest_version + puts " | Latest version: #{latest_version} (up to date)" if latest_version && !outdated?(version, latest_version) puts " | Last updated: #{last_updated}" if last_updated 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 warning("The version is out of date, the latest version is #{latest_version}") if latest_version && outdated?(version, latest_version) + 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? diff --git a/spec/shared_examples/wp_item_infos.rb b/spec/shared_examples/wp_item_infos.rb index 1be9d8b0..4bf56269 100644 --- a/spec/shared_examples/wp_item_infos.rb +++ b/spec/shared_examples/wp_item_infos.rb @@ -53,6 +53,22 @@ shared_examples 'WpItem::Infos' do end end + describe '#outdated?' do + it 'returns true if outdated' do + latest_version = '1.0' + installed_version = '0.1' + + expect(subject.outdated?(installed_version, latest_version)).to be true + end + + it 'returns false if not outdated' do + latest_version = '1.0' + installed_version = '1.0' + + expect(subject.outdated?(installed_version, latest_version)).to be false + end + end + describe '#has_changelog?' do after :each do stub_request(:get, subject.changelog_url).to_return(status: @status) From 2208f2a8c00e4093fb064c8f2df3da44124588d5 Mon Sep 17 00:00:00 2001 From: ethicalhack3r Date: Tue, 8 Sep 2015 17:54:32 +0200 Subject: [PATCH 15/15] Implement lesser? method #862 --- lib/common/models/wp_item/infos.rb | 5 - lib/common/models/wp_item/output.rb | 6 +- lib/common/version_compare.rb | 36 +++++++- spec/lib/common/version_compare_spec.rb | 118 ++++++++++++++++++++++++ spec/shared_examples/wp_item_infos.rb | 16 ---- 5 files changed, 156 insertions(+), 25 deletions(-) diff --git a/lib/common/models/wp_item/infos.rb b/lib/common/models/wp_item/infos.rb index df9b92b2..1724b695 100644 --- a/lib/common/models/wp_item/infos.rb +++ b/lib/common/models/wp_item/infos.rb @@ -10,11 +10,6 @@ class WpItem !readme_url.nil? end - # @return [ Boolean ] - def outdated?(installed_version, latest_version) - installed_version < latest_version - end - # @return [ String,nil ] The url to the readme file, nil if not found def readme_url # See https://github.com/wpscanteam/wpscan/pull/737#issuecomment-66375445 diff --git a/lib/common/models/wp_item/output.rb b/lib/common/models/wp_item/output.rb index b6cccd8e..10c51cdd 100644 --- a/lib/common/models/wp_item/output.rb +++ b/lib/common/models/wp_item/output.rb @@ -5,14 +5,16 @@ class WpItem # @return [ Void ] def output(verbose = false) + outdated = VersionCompare.lesser?(version, latest_version) if latest_version + puts puts info("Name: #{self}") #this will also output the version number if detected - puts " | Latest version: #{latest_version} (up to date)" if latest_version && !outdated?(version, latest_version) + puts " | Latest version: #{latest_version} (up to date)" if latest_version && !outdated puts " | Last updated: #{last_updated}" if last_updated puts " | Location: #{url}" puts " | Readme: #{readme_url}" if has_readme? puts " | Changelog: #{changelog_url}" if has_changelog? - puts warning("The version is out of date, the latest version is #{latest_version}") if latest_version && outdated?(version, latest_version) + puts warning("The version is out of date, the latest version is #{latest_version}") if latest_version && outdated 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? diff --git a/lib/common/version_compare.rb b/lib/common/version_compare.rb index 3e0ded85..301388ec 100644 --- a/lib/common/version_compare.rb +++ b/lib/common/version_compare.rb @@ -11,8 +11,8 @@ class VersionCompare # @return [ Boolean ] 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] == '.' + version1 = prepend_zero(version1) + version2 = prepend_zero(version2) return true if (version1 == version2) # Both versions must be set @@ -27,4 +27,36 @@ class VersionCompare end return false end + + # Compares two version strings. Returns true if version1 < version2 + # and false otherwise + # + # @param [ String ] version1 + # @param [ String ] version2 + # + # @return [ Boolean ] + def self.lesser?(version1, version2) + # Prepend a '0' if the version starts with a '.' + version1 = prepend_zero(version1) + version2 = prepend_zero(version2) + + return false if (version1 == version2) + # Both versions must be set + return false unless (version1 and version2) + return false if (version1.empty? or version2.empty?) + begin + return true if (Gem::Version.new(version1) < Gem::Version.new(version2)) + rescue ArgumentError => e + # Example: ArgumentError: Malformed version number string a + return false if e.message =~ /Malformed version number string/ + raise + end + return false + end + + # @return [ String ] + def self.prepend_zero(version) + return nil if version.nil? + version[0,1] == '.' ? "0#{version}" : version + end end diff --git a/spec/lib/common/version_compare_spec.rb b/spec/lib/common/version_compare_spec.rb index 0a62b74f..80382179 100644 --- a/spec/lib/common/version_compare_spec.rb +++ b/spec/lib/common/version_compare_spec.rb @@ -121,4 +121,122 @@ describe 'VersionCompare' do end end + + describe '::lesser?' do + context 'version checked is newer' do + after { expect(VersionCompare::lesser?(@version1, @version2)).to be_truthy } + + it 'returns true' do + @version1 = '1.0' + @version2 = '2.0' + end + + it 'returns true' do + @version1 = '1.0' + @version2 = '1.1' + end + + it 'returns true' do + @version1 = '1.0a' + @version2 = '1.0b' + end + + it 'returns true' do + @version1 = '1.0' + @version2 = '5000000' + end + + it 'returns true' do + @version1 = '0' + @version2 = '1' + end + + it 'returns true' 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 { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey } + + it 'returns false' do + @version1 = '1' + @version2 = '0' + end + + it 'returns false' do + @version1 = '1.0' + @version2 = '0.5' + end + + it 'returns false' do + @version1 = '500000' + @version2 = '1' + end + + it 'returns false' 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 { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey } + + it 'returns true' do + @version1 = '1' + @version2 = '1' + end + + it 'returns true' do + @version1 = 'a' + @version2 = 'a' + end + + end + + context 'version number causes Gem::Version new Exception' do + after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey } + + it 'returns false' do + @version1 = 'a' + @version2 = 'b' + end + end + + context 'one version number is not set' do + after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey } + + it 'returns false (version2 nil)' do + @version1 = '1' + @version2 = nil + end + + it 'returns false (version1 nil)' do + @version1 = nil + @version2 = '1' + end + + it 'returns false (version2 empty)' do + @version1 = '1' + @version2 = '' + end + + it 'returns false (version1 empty)' do + @version1 = '' + @version2 = '1' + end + end + end end diff --git a/spec/shared_examples/wp_item_infos.rb b/spec/shared_examples/wp_item_infos.rb index 4bf56269..1be9d8b0 100644 --- a/spec/shared_examples/wp_item_infos.rb +++ b/spec/shared_examples/wp_item_infos.rb @@ -53,22 +53,6 @@ shared_examples 'WpItem::Infos' do end end - describe '#outdated?' do - it 'returns true if outdated' do - latest_version = '1.0' - installed_version = '0.1' - - expect(subject.outdated?(installed_version, latest_version)).to be true - end - - it 'returns false if not outdated' do - latest_version = '1.0' - installed_version = '1.0' - - expect(subject.outdated?(installed_version, latest_version)).to be false - end - end - describe '#has_changelog?' do after :each do stub_request(:get, subject.changelog_url).to_return(status: @status)