diff --git a/lib/wpscan/wp_target.rb b/lib/wpscan/wp_target.rb index c8c48a1e..94b2c648 100644 --- a/lib/wpscan/wp_target.rb +++ b/lib/wpscan/wp_target.rb @@ -98,19 +98,30 @@ class WpTarget < WebSite def wp_content_dir unless @wp_content_dir index_body = Browser.instance.get(@uri.to_s).body - # Only use the path because domain can be text or an ip - uri_path = @uri.path + uri_path = @uri.path # Only use the path because domain can be text or an IP - if index_body[/\/wp-content\/(?:themes|plugins)\//i] + if index_body[/\/wp-content\/(?:themes|plugins)\//i] || default_wp_content_dir_exists? @wp_content_dir = 'wp-content' else domains_excluded = '(?:www\.)?(facebook|twitter)\.com' @wp_content_dir = index_body[/(?:href|src)\s*=\s*(?:"|').+#{Regexp.escape(uri_path)}((?!#{domains_excluded})[^"']+)\/(?:themes|plugins)\/.*(?:"|')/i, 1] end end + @wp_content_dir end + def default_wp_content_dir_exists? + response = Browser.instance.get(@uri.merge('wp-content').to_s) + hash = Digest::MD5.hexdigest(response.body) + + if WpTarget.valid_response_codes.include?(response.code) + return true if hash != error_404_hash and hash != homepage_hash + end + + false + end + def wp_plugins_dir unless @wp_plugins_dir @wp_plugins_dir = "#{wp_content_dir}/plugins" diff --git a/spec/lib/wpscan/wp_target_spec.rb b/spec/lib/wpscan/wp_target_spec.rb index 6d0e141f..1584f845 100644 --- a/spec/lib/wpscan/wp_target_spec.rb +++ b/spec/lib/wpscan/wp_target_spec.rb @@ -160,7 +160,10 @@ describe WpTarget do after :each do @wp_target = WpTarget.new(@target_url) if @target_url + stub_request_to_fixture(url: @wp_target.url, fixture: @fixture) if @fixture + stub_request(:any, /.*\/wp-content\/?$/).to_return(:status => 200, :body => '') # default dir request + stub_request(:any, /.*\.html$/).to_return(:status => 200, :body => '') # 404 hash request @wp_target.wp_content_dir.should === @expected end @@ -170,7 +173,6 @@ describe WpTarget do @expected = 'hello-world' end - it "should return 'wp-content'" do @target_url = 'http://lamp/wordpress-3.4.1' @fixture = fixtures_dir + '/wordpress-3.4.1.htm' @@ -226,6 +228,48 @@ describe WpTarget do end end + describe '#default_wp_content_dir_exists?' do + after :each do + @wp_target = WpTarget.new(@target_url) if @target_url + stub_request(:any, @wp_target.url).to_return(:status => 200, :body => 'homepage') # homepage request + + @wp_target.default_wp_content_dir_exists?.should === @expected + end + + it 'returns false if wp-content returns an invalid response code' do + stub_request(:any, /.*\/wp-content\/?$/).to_return(:status => 404, :body => '') # default dir request + stub_request(:any, /.*\.html$/).to_return(:status => 404, :body => '') # 404 hash request + + @target_url = 'http://lamp.localhost/' + @expected = false + end + + it 'returns false if wp-content and homepage have same bodies' do + stub_request(:any, /.*\/wp-content\/?$/).to_return(:status => 200, :body => 'homepage') # default dir request + stub_request(:any, /.*\.html$/).to_return(:status => 404, :body => '404!') # 404 hash request + + @target_url = 'http://lamp.localhost/' + @expected = false + end + + it 'returns false if wp-content and 404 page have same bodies' do + stub_request(:any, /.*\/wp-content\/?$/).to_return(:status => 200, :body => '404!') # default dir request + stub_request(:any, /.*\.html$/).to_return(:status => 404, :body => '404!') # 404 hash request + + @target_url = 'http://lamp.localhost/' + @expected = false + end + + it 'returns true if wp-content, 404 page and hoempage return different bodies' do + stub_request(:any, /.*\/wp-content\/?$/).to_return(:status => 200, :body => '') # default dir request + stub_request(:any, /.*\.html$/).to_return(:status => 200, :body => '404!') # 404 hash request + + @target_url = 'http://lamp.localhost/' + @expected = true + end + + end + describe '#wp_plugins_dir' do after :each do @wp_target.stub(wp_plugins_dir: @stub_value) if @stub_value