From 9c3947a7b108acb4eb3074aeede49ced2a60d18d Mon Sep 17 00:00:00 2001 From: erwanlr Date: Wed, 5 Feb 2014 21:52:55 +0100 Subject: [PATCH] Fix #404 - Brute forcing issue over https --- lib/common/models/wp_user.rb | 27 ++++++++++++++++++- spec/lib/common/models/wp_user_spec.rb | 4 --- .../shared_examples/wp_user/brute_forcable.rb | 25 ++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/lib/common/models/wp_user.rb b/lib/common/models/wp_user.rb index 13efcf96..eb3ef5cf 100755 --- a/lib/common/models/wp_user.rb +++ b/lib/common/models/wp_user.rb @@ -23,7 +23,32 @@ class WpUser < WpItem # @return [ String ] def login_url - @uri.merge('wp-login.php').to_s + unless @login_url + @login_url = @uri.merge('wp-login.php').to_s + + # Let's check if the login url is redirected (to https url for example) + if redirection = redirection(@login_url) + @login_url = redirection + end + end + + @login_url + end + + def redirection(url) + redirection = nil + response = Browser.get(url) + + if response.code == 301 || response.code == 302 + redirection = response.headers_hash['location'] + + # Let's check if there is a redirection in the redirection + if other_redirection = redirection(redirection) + redirection = other_redirection + end + end + + redirection end # @return [ String ] diff --git a/spec/lib/common/models/wp_user_spec.rb b/spec/lib/common/models/wp_user_spec.rb index d144b5dc..ce5c6e14 100644 --- a/spec/lib/common/models/wp_user_spec.rb +++ b/spec/lib/common/models/wp_user_spec.rb @@ -34,10 +34,6 @@ describe WpUser do end end - describe '#login_url' do - its(:login_url) { should == 'http://example.com/wp-login.php' } - end - describe '#to_s' do after do subject.id = 1 diff --git a/spec/shared_examples/wp_user/brute_forcable.rb b/spec/shared_examples/wp_user/brute_forcable.rb index c3985b5b..96f92165 100644 --- a/spec/shared_examples/wp_user/brute_forcable.rb +++ b/spec/shared_examples/wp_user/brute_forcable.rb @@ -66,7 +66,8 @@ shared_examples 'WpUser::BruteForcable' do end describe '#brute_force' do - let(:login) { 'someuser' } + let(:login) { 'someuser' } + let(:login_url) { uri.merge('wp-login.php').to_s } after do [wordlist_utf8, wordlist_iso].each do |wordlist| @@ -78,6 +79,7 @@ shared_examples 'WpUser::BruteForcable' do context 'when no password is valid' do before do + stub_request(:get, login_url).to_return(status: 200) stub_request(:post, wp_user.login_url). # with(body: { log: login }). # produces an error : undefined method `split' for {:log=>"someuser", :pwd=>"password1"}:Hash # Fixed in WebMock 1.17.2, TODO: Modify the specs @@ -93,7 +95,8 @@ shared_examples 'WpUser::BruteForcable' do let(:redirect_url) { nil } before do - stub_request(:post, wp_user.login_url).to_return(status: 302, headers: { 'Location' => 'wrong-location' } ) + stub_request(:get, login_url).to_return(status: 200) + stub_request(:post, wp_user.login_url).to_return(status: 302, headers: { 'Location' => 'wrong-location' }) end it 'does not set the @password' do @@ -108,13 +111,29 @@ shared_examples 'WpUser::BruteForcable' do # Fixed in WebMock 1.17.2, TODO: Modify the specs before do - stub_request(:post, wp_user.login_url).to_return(status: 302, headers: { 'Location' => redirect_url } ) + stub_request(:get, login_url).to_return(status: 200) + stub_request(:post, wp_user.login_url).to_return(status: 302, headers: { 'Location' => redirect_url }) end it 'sets the @password' do @expected = 'password1' end end + + context 'when the login url is redirected to https' do + let(:https_login_url) { 'https://example.com/wp-login.php' } + + before do + stub_request(:any, uri.merge('wp-login.php').to_s).to_return(status: 302, headers: { 'Location' => https_login_url}) + stub_request(:get, https_login_url).to_return(status: 200) + stub_request(:post, https_login_url).with(body: hash_including({ log: 'someuser', pwd: 'root'})).to_return(status: 302, headers: { 'Location' => redirect_url }) + stub_request(:post, https_login_url).with(body: /pwd=(?!root)/).to_return(body: 'login_error') + end + + it 'does not raise any error' do + @expected = 'root' + end + end end end