diff --git a/app/finders/interesting_findings.rb b/app/finders/interesting_findings.rb index fd0c91ed..249f1b91 100644 --- a/app/finders/interesting_findings.rb +++ b/app/finders/interesting_findings.rb @@ -4,7 +4,7 @@ require_relative 'interesting_findings/readme' require_relative 'interesting_findings/wp_cron' require_relative 'interesting_findings/multisite' require_relative 'interesting_findings/debug_log' -require_relative 'interesting_findings/backup_db' +require_relative 'interesting_findings/plugin_backup_folders' require_relative 'interesting_findings/mu_plugins' require_relative 'interesting_findings/registration' require_relative 'interesting_findings/tmm_db_migrate' @@ -24,7 +24,7 @@ module WPScan super(target) %w[ - Readme DebugLog FullPathDisclosure BackupDB DuplicatorInstallerLog + Readme DebugLog FullPathDisclosure PluginBackupFolders DuplicatorInstallerLog Multisite MuPlugins Registration UploadDirectoryListing TmmDbMigrate UploadSQLDump EmergencyPwdResetScript WPCron ].each do |f| diff --git a/app/finders/interesting_findings/backup_db.rb b/app/finders/interesting_findings/backup_db.rb deleted file mode 100644 index c6358b81..00000000 --- a/app/finders/interesting_findings/backup_db.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -module WPScan - module Finders - module InterestingFindings - # BackupDB finder - class BackupDB < CMSScanner::Finders::Finder - # @return [ InterestingFinding ] - def aggressive(_opts = {}) - path = 'wp-content/backup-db/' - res = target.head_and_get(path, [200, 403]) - - return unless [200, 403].include?(res.code) && !target.homepage_or_404?(res) - - Model::BackupDB.new( - target.url(path), - confidence: 70, - found_by: DIRECT_ACCESS, - interesting_entries: target.directory_listing_entries(path), - references: { url: 'https://github.com/wpscanteam/wpscan/issues/422' } - ) - end - end - end - end -end diff --git a/app/finders/interesting_findings/plugin_backup_folders.rb b/app/finders/interesting_findings/plugin_backup_folders.rb new file mode 100644 index 00000000..ee228aa9 --- /dev/null +++ b/app/finders/interesting_findings/plugin_backup_folders.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module WPScan + module Finders + module InterestingFindings + # BackupDB finder + class PluginBackupFolders < CMSScanner::Finders::Finder + PATHS = %w[wp-content/backup-db/ wp-content/backups-dup-pro/ wp-content/updraft/].freeze + + # @return [ InterestingFinding ] + def aggressive(_opts = {}) + found = [] + + PATHS.each do |path| + res = target.head_and_get(path, [200, 403]) + + next unless [200, 403].include?(res.code) && !target.homepage_or_404?(res) + + found << Model::PluginBackupFolder.new( + target.url(path), + confidence: 70, + found_by: DIRECT_ACCESS, + interesting_entries: target.directory_listing_entries(path), + references: { url: ['https://github.com/wpscanteam/wpscan/issues/422', + 'https://github.com/wpscanteam/wpscan/issues/1342'] } + ) + end + + found + end + end + end + end +end diff --git a/app/models/interesting_finding.rb b/app/models/interesting_finding.rb index 61e44da6..2ba04b23 100644 --- a/app/models/interesting_finding.rb +++ b/app/models/interesting_finding.rb @@ -10,7 +10,7 @@ module WPScan # # Empty classes for the #type to be correctly displayed (as taken from the self.class from the parent) # - class BackupDB < InterestingFinding + class PluginBackupFolder < InterestingFinding end class DebugLog < InterestingFinding diff --git a/spec/app/finders/interesting_findings/backup_db_spec.rb b/spec/app/finders/interesting_findings/backup_db_spec.rb deleted file mode 100644 index 00cdb89a..00000000 --- a/spec/app/finders/interesting_findings/backup_db_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -describe WPScan::Finders::InterestingFindings::BackupDB do - subject(:finder) { described_class.new(target) } - let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } - let(:url) { 'http://ex.lo/' } - let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'backup_db') } - let(:wp_content) { 'wp-content' } - let(:dir_url) { target.url("#{wp_content}/backup-db/") } - - before do - expect(target).to receive(:content_dir).at_least(1).and_return(wp_content) - expect(target).to receive(:head_or_get_params).and_return(method: :head) - end - - describe '#aggressive' do - context 'when not a 200 or 403' do - it 'returns nil' do - stub_request(:head, dir_url).to_return(status: 404) - - expect(finder.aggressive).to eql nil - end - end - - context 'when 200 and matching the homepage' do - it 'returns nil' do - stub_request(:head, dir_url) - stub_request(:get, dir_url) - - expect(target).to receive(:homepage_or_404?).and_return(true) - - expect(finder.aggressive).to eql nil - end - end - - context 'when 200 or 403' do - before do - stub_request(:head, dir_url) - stub_request(:get, dir_url).and_return(body: body) - - expect(target).to receive(:homepage_or_404?).and_return(false) - end - - after do - found = finder.aggressive - - expect(found).to eql WPScan::Model::BackupDB.new( - dir_url, - confidence: 70, - found_by: described_class::DIRECT_ACCESS - ) - - expect(found.interesting_entries).to eq @expected_entries - end - - context 'when no directory listing' do - let(:body) { '' } - - it 'returns an empty interesting_findings attribute' do - @expected_entries = [] - end - end - - context 'when directory listing enabled' do - let(:body) { File.read(fixtures.join('dir_listing.html')) } - - it 'returns the expected interesting_findings attribute' do - @expected_entries = %w[sqldump.sql test.txt] - end - end - end - end -end diff --git a/spec/app/finders/interesting_findings/plugin_backup_folders_spec.rb b/spec/app/finders/interesting_findings/plugin_backup_folders_spec.rb new file mode 100644 index 00000000..ca87ffbe --- /dev/null +++ b/spec/app/finders/interesting_findings/plugin_backup_folders_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +describe WPScan::Finders::InterestingFindings::PluginBackupFolders do + subject(:finder) { described_class.new(target) } + let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) } + let(:url) { 'http://ex.lo/' } + let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'plugin_backup_folders') } + let(:wp_content) { 'wp-content' } + + before do + expect(target).to receive(:content_dir).at_least(1).and_return(wp_content) + + finder.class::PATHS.each { |path| stub_request(:head, target.url(path)).to_return(status: 404) } + + allow(target).to receive(:head_or_get_params).and_return(method: :head) + end + + describe '#aggressive' do + context 'when none of them exist' do + it 'returns an empty array' do + expect(finder.aggressive).to eql([]) + end + end + + context 'when one exist but matches the homepage' do + let(:existing_url) { target.url(finder.class::PATHS.sample) } + + it 'ignores it' do + stub_request(:head, existing_url) + stub_request(:get, existing_url) + + expect(target).to receive(:homepage_or_404?).and_return(true) + + expect(finder.aggressive).to eql([]) + end + end + + context 'when 200 or 403' do + let(:existing_url) { target.url(finder.class::PATHS.sample) } + + before do + stub_request(:head, existing_url) + stub_request(:get, existing_url).and_return(body: body) + + expect(target).to receive(:homepage_or_404?).and_return(false) + end + + after do + found = finder.aggressive + + expect(found.size).to eql 1 + + expect(found).to eql([WPScan::Model::PluginBackupFolder.new(existing_url, + confidence: 70, + found_by: described_class::DIRECT_ACCESS)]) + + expect(found.first.interesting_entries).to eq @expected_entries + end + + context 'when no directory listing' do + let(:body) { '' } + + it 'returns an empty interesting_findings attribute' do + @expected_entries = [] + end + end + + context 'when directory listing enabled' do + let(:body) { File.read(fixtures.join('dir_listing.html')) } + + it 'returns the expected interesting_findings attribute' do + @expected_entries = %w[sqldump.sql test.txt] + end + end + end + end +end diff --git a/spec/fixtures/finders/interesting_findings/backup_db/dir_listing.html b/spec/fixtures/finders/interesting_findings/plugin_backup_folders/dir_listing.html similarity index 100% rename from spec/fixtures/finders/interesting_findings/backup_db/dir_listing.html rename to spec/fixtures/finders/interesting_findings/plugin_backup_folders/dir_listing.html