From a506adcb644a3e376ada06fc9751c5dcf6f4b8d7 Mon Sep 17 00:00:00 2001 From: erwanlr Date: Thu, 6 Aug 2020 10:51:08 +0200 Subject: [PATCH] Fixes #1529 --- app/finders/users.rb | 2 + app/finders/users/author_sitemap.rb | 36 ++++++++++++++ app/finders/users/yoast_seo_author_sitemap.rb | 22 +-------- spec/app/finders/users/author_sitemap_spec.rb | 48 +++++++++++++++++++ spec/app/finders/users_spec.rb | 2 +- .../users/author_sitemap/no_usernames.xml | 4 ++ .../users/author_sitemap/usernames.xml | 6 +++ 7 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 app/finders/users/author_sitemap.rb create mode 100644 spec/app/finders/users/author_sitemap_spec.rb create mode 100644 spec/fixtures/finders/users/author_sitemap/no_usernames.xml create mode 100644 spec/fixtures/finders/users/author_sitemap/usernames.xml diff --git a/app/finders/users.rb b/app/finders/users.rb index 22649b07..cfac4423 100644 --- a/app/finders/users.rb +++ b/app/finders/users.rb @@ -6,6 +6,7 @@ require_relative 'users/oembed_api' require_relative 'users/rss_generator' require_relative 'users/author_id_brute_forcing' require_relative 'users/login_error_messages' +require_relative 'users/author_sitemap' require_relative 'users/yoast_seo_author_sitemap' module WPScan @@ -22,6 +23,7 @@ module WPScan Users::WpJsonApi.new(target) << Users::OembedApi.new(target) << Users::RSSGenerator.new(target) << + Users::AuthorSitemap.new(target) << Users::YoastSeoAuthorSitemap.new(target) << Users::AuthorIdBruteForcing.new(target) << Users::LoginErrorMessages.new(target) diff --git a/app/finders/users/author_sitemap.rb b/app/finders/users/author_sitemap.rb new file mode 100644 index 00000000..58b26422 --- /dev/null +++ b/app/finders/users/author_sitemap.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module WPScan + module Finders + module Users + # Since WP 5.5, /wp-sitemap-users-1.xml is generated and contains + # the usernames of accounts who made a post + class AuthorSitemap < CMSScanner::Finders::Finder + # @param [ Hash ] opts + # + # @return [ Array ] + def aggressive(_opts = {}) + found = [] + + Browser.get(sitemap_url).html.xpath('//url/loc').each do |user_tag| + username = user_tag.text.to_s[%r{/author/([^/]+)/}, 1] + + next unless username && !username.strip.empty? + + found << Model::User.new(username, + found_by: found_by, + confidence: 100, + interesting_entries: [sitemap_url]) + end + + found + end + + # @return [ String ] The URL of the sitemap + def sitemap_url + @sitemap_url ||= target.url('wp-sitemap-users-1.xml') + end + end + end + end +end diff --git a/app/finders/users/yoast_seo_author_sitemap.rb b/app/finders/users/yoast_seo_author_sitemap.rb index 82f733dd..d067b938 100644 --- a/app/finders/users/yoast_seo_author_sitemap.rb +++ b/app/finders/users/yoast_seo_author_sitemap.rb @@ -5,27 +5,7 @@ module WPScan module Users # The YOAST SEO plugin has an author-sitemap.xml which can leak usernames # See https://github.com/wpscanteam/wpscan/issues/1228 - class YoastSeoAuthorSitemap < CMSScanner::Finders::Finder - # @param [ Hash ] opts - # - # @return [ Array ] - def aggressive(_opts = {}) - found = [] - - Browser.get(sitemap_url).html.xpath('//url/loc').each do |user_tag| - username = user_tag.text.to_s[%r{/author/([^/]+)/}, 1] - - next unless username && !username.strip.empty? - - found << Model::User.new(username, - found_by: found_by, - confidence: 100, - interesting_entries: [sitemap_url]) - end - - found - end - + class YoastSeoAuthorSitemap < AuthorSitemap # @return [ String ] The URL of the author-sitemap def sitemap_url @sitemap_url ||= target.url('author-sitemap.xml') diff --git a/spec/app/finders/users/author_sitemap_spec.rb b/spec/app/finders/users/author_sitemap_spec.rb new file mode 100644 index 00000000..2a03c035 --- /dev/null +++ b/spec/app/finders/users/author_sitemap_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +describe WPScan::Finders::Users::AuthorSitemap do + subject(:finder) { described_class.new(target) } + let(:target) { WPScan::Target.new(url) } + let(:url) { 'http://wp.lab/' } + let(:fixtures) { FINDERS_FIXTURES.join('users', 'author_sitemap') } + + describe '#aggressive' do + before do + allow(target).to receive(:sub_dir).and_return(false) + + stub_request(:get, finder.sitemap_url).to_return(body: body) + end + + context 'when not an XML response' do + let(:body) { '' } + + its(:aggressive) { should eql([]) } + end + + context 'when an XML response' do + context 'when no usernames disclosed' do + let(:body) { File.read(fixtures.join('no_usernames.xml')) } + + its(:aggressive) { should eql([]) } + end + + context 'when usernames disclosed' do + let(:body) { File.read(fixtures.join('usernames.xml')) } + + it 'returns the expected array of users' do + users = finder.aggressive + + expect(users.size).to eql 2 + + expect(users.first.username).to eql 'admin' + expect(users.first.confidence).to eql 100 + expect(users.first.interesting_entries).to eql ['http://wp.lab/wp-sitemap-users-1.xml'] + + expect(users.last.username).to eql 'author' + expect(users.last.confidence).to eql 100 + expect(users.last.interesting_entries).to eql ['http://wp.lab/wp-sitemap-users-1.xml'] + end + end + end + end +end diff --git a/spec/app/finders/users_spec.rb b/spec/app/finders/users_spec.rb index b23b7f40..230b426b 100644 --- a/spec/app/finders/users_spec.rb +++ b/spec/app/finders/users_spec.rb @@ -8,7 +8,7 @@ describe WPScan::Finders::Users::Base do describe '#finders' do it 'contains the expected finders' do expect(user.finders.map { |f| f.class.to_s.demodulize }) - .to eq %w[AuthorPosts WpJsonApi OembedApi RSSGenerator YoastSeoAuthorSitemap + .to eq %w[AuthorPosts WpJsonApi OembedApi RSSGenerator AuthorSitemap YoastSeoAuthorSitemap AuthorIdBruteForcing LoginErrorMessages] end end diff --git a/spec/fixtures/finders/users/author_sitemap/no_usernames.xml b/spec/fixtures/finders/users/author_sitemap/no_usernames.xml new file mode 100644 index 00000000..a52a2402 --- /dev/null +++ b/spec/fixtures/finders/users/author_sitemap/no_usernames.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spec/fixtures/finders/users/author_sitemap/usernames.xml b/spec/fixtures/finders/users/author_sitemap/usernames.xml new file mode 100644 index 00000000..853c82cb --- /dev/null +++ b/spec/fixtures/finders/users/author_sitemap/usernames.xml @@ -0,0 +1,6 @@ + + + + http://wp.lab/author/admin/ + http://wp.lab//author/author/ +