From d1a7a0ee1fe80db704af30f42f8dfc2a9e7c5c11 Mon Sep 17 00:00:00 2001 From: erwanlr Date: Wed, 10 Sep 2014 12:52:52 +0200 Subject: [PATCH] Db Update draft --- .gitignore | 1 + lib/common/updater/db_updater.rb | 90 +++++++++++++++++++++++++++ lib/common/updater/updater_factory.rb | 13 ++-- wpscan.rb | 6 ++ 4 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 lib/common/updater/db_updater.rb diff --git a/.gitignore b/.gitignore index 41dc3eaa..f34e8fd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ cache coverage +data/*_vulns.json .bundle .DS_Store .DS_Store? diff --git a/lib/common/updater/db_updater.rb b/lib/common/updater/db_updater.rb new file mode 100644 index 00000000..d8a54dcb --- /dev/null +++ b/lib/common/updater/db_updater.rb @@ -0,0 +1,90 @@ +# encoding: UTF-8 + +require 'common/updater/updater' + +# Updater for the Database (currently only 3 .json) +class DbUpdater < Updater + FILENAMES = %w(plugin_vulns theme_vulns wp_vulns) + + 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}.json" + end + + # @return [ String ] The checksum of the associated remote filename + def remote_file_checksum(filename) + url = "#{remote_file_url(filename)}.sha2" + + res = Browser.get(url, request_params) + fail "Unable to get #{url}" unless res && res.code == 200 + res.body.chomp + end + + def local_file_path(filename) + File.join(repo_directory, "#{filename}.json") + end + + def backup_file_path(filename) + File.join(repo_directory, "#{filename}.back.json") + 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) + FileUtils.cp(backup_file_path(filename), local_file_path(filename)) + end + + def delete_backup(filename) + FileUtils.rm(backup_file_path(filename), force: true) + 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) + fail "Error while downloading #{file_url}" unless res && res.code == 200 + File.write(file_path, res.body.chomp) + + Digest::MD5.file(file_path).hexdigest + end + + def update + FILENAMES.each do |filename| + begin + create_backup(filename) + checksum = download(filename) + # p checksum + + # unless checksum == remote_file_checksum(filename) + # fail "#{filename}: checksums do not match" + # end + rescue => e + # p e + restore_backup(filename) + raise e + ensure + delete_backup(filename) + end + end + end +end diff --git a/lib/common/updater/updater_factory.rb b/lib/common/updater/updater_factory.rb index 4bfb5276..2f12443a 100644 --- a/lib/common/updater/updater_factory.rb +++ b/lib/common/updater/updater_factory.rb @@ -1,23 +1,20 @@ # encoding: UTF-8 +# Factory class UpdaterFactory - def self.get_updater(repo_directory) - self.available_updaters_classes().each do |updater_symbol| + available_updaters_classes.each do |updater_symbol| updater = Object.const_get(updater_symbol).new(repo_directory) - if updater.is_installed? - return updater - end + return updater if updater.is_installed? end nil end protected - # return array of class symbols + # @return [ Array ] The symbols related to code updaters def self.available_updaters_classes - Object.constants.grep(/^.+Updater$/) + Object.constants.grep(/^(?:Svn|Git|Test)Updater$/) end - end diff --git a/wpscan.rb b/wpscan.rb index 02013e28..6abdd9c2 100755 --- a/wpscan.rb +++ b/wpscan.rb @@ -39,6 +39,12 @@ def main # Check for updates if wpscan_options.update + puts 'Updating the DB ..' + DbUpdater.new(DATA_DIR).update + puts 'Done.' + + exit # remove me + if !@updater.nil? if @updater.has_local_changes? print "#{red('[!]')} Local file changes detected, an update will override local changes, do you want to continue updating? [y/n] "