Add rspec and update about secure admin
parent
f097ef96e0
commit
954475c0bf
|
@ -41,9 +41,9 @@ module Metasploit
|
|||
|
||||
|
||||
#
|
||||
# Starting Glassfish 4, by default bruteforce doesn't work because Secure Admin is disabled,
|
||||
# which means nobody can login remotely. You will only find out about this when you try to
|
||||
# login, so this should be called during the login process
|
||||
# As of Sep 2014, if Secure Admin is disabled, it simply means the admin isn't allowed
|
||||
# to login remotely. However, the authentication will still run and hint whether the
|
||||
# password is correct or not.
|
||||
#
|
||||
def is_secure_admin_disabled?(res)
|
||||
return (res.body =~ /Secure Admin must be enabled/i) ? true : false
|
||||
|
@ -68,15 +68,7 @@ module Metasploit
|
|||
}
|
||||
}
|
||||
|
||||
res = send_request(opts)
|
||||
|
||||
if is_secure_admin_disabled?(res)
|
||||
# Using the exact error message Glassfish says, that way the user can google what
|
||||
# it's about.
|
||||
raise GlassfishError, "Secure Admin must be enabled to access the DAS remotely."
|
||||
end
|
||||
|
||||
res
|
||||
send_request(opts)
|
||||
end
|
||||
|
||||
|
||||
|
@ -123,6 +115,8 @@ module Metasploit
|
|||
if (res && res.code.to_i == 200 && res.body.match(p) != nil)
|
||||
return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.body}
|
||||
end
|
||||
elsif res && is_secure_admin_disabled?(res)
|
||||
return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.body}
|
||||
elsif res && res.code == 400
|
||||
raise GlassfishError, "400: Bad HTTP request from try_login"
|
||||
end
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
|
||||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/glassfish'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Glassfish do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
||||
subject(:http_scanner) { described_class.new }
|
||||
|
||||
context 'Instance Methods' do
|
||||
let(:good_version) do
|
||||
'4.0'
|
||||
end
|
||||
|
||||
let(:bad_version) do
|
||||
'Unknown'
|
||||
end
|
||||
|
||||
let(:username) do
|
||||
'admin'
|
||||
end
|
||||
|
||||
let(:password) do
|
||||
'password'
|
||||
end
|
||||
|
||||
let(:cred) do
|
||||
Metasploit::Framework::Credential.new(
|
||||
paired: true,
|
||||
public: username,
|
||||
private: password
|
||||
)
|
||||
end
|
||||
|
||||
let(:res_code) do
|
||||
200
|
||||
end
|
||||
|
||||
before do
|
||||
http_scanner.version = good_version
|
||||
end
|
||||
|
||||
context '#send_request' do
|
||||
let(:req_opts) do
|
||||
{'uri'=>'/', 'method'=>'GET'}
|
||||
end
|
||||
|
||||
it 'should return a Rex::Proto::Http::Response' do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv).and_return(Rex::Proto::Http::Response.new(res_code))
|
||||
http_scanner.send_request(req_opts).code.should eq(res_code)
|
||||
end
|
||||
end
|
||||
|
||||
context '#is_secure_admin_disabled?' do
|
||||
it 'should return true when Secure Admin is disabled' do
|
||||
res = Rex::Proto::Http::Response.new(res_code)
|
||||
res.stub(:body).and_return('Secure Admin must be enabled')
|
||||
http_scanner.is_secure_admin_disabled?(res).should eq(true)
|
||||
end
|
||||
|
||||
it 'should return false when Secure Admin is enabled' do
|
||||
res = Rex::Proto::Http::Response.new(res_code)
|
||||
res.stub(:body).and_return('')
|
||||
http_scanner.is_secure_admin_disabled?(res).should eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context '#try_login' do
|
||||
it 'should send a login request to /j_security_check' do
|
||||
http_scanner.should_receive(:send_request).with(hash_including('uri'=>'/j_security_check'))
|
||||
http_scanner.try_login(cred)
|
||||
end
|
||||
|
||||
it 'should send a login request containing the username and password' do
|
||||
http_scanner.should_receive(:send_request).with(hash_including('data'=>"j_username=#{username}&j_password=#{password}&loginButton=Login"))
|
||||
http_scanner.try_login(cred)
|
||||
end
|
||||
end
|
||||
|
||||
context '#try_glassfish_2' do
|
||||
it 'should return status Metasploit::Model::Login::Status::SUCCESSFUL for a valid credential' do
|
||||
good_auth_res = Rex::Proto::Http::Response.new(302)
|
||||
good_res = Rex::Proto::Http::Response.new(200)
|
||||
good_res.stub(:body).and_return('<title>Deploy Enterprise Applications/Modules</title>')
|
||||
http_scanner.should_receive(:try_login).with(cred).and_return(good_auth_res)
|
||||
http_scanner.should_receive(:send_request).with(kind_of(Hash)).and_return(good_res)
|
||||
http_scanner.try_glassfish_2(cred)[:status].should eq(Metasploit::Model::Login::Status::SUCCESSFUL)
|
||||
end
|
||||
|
||||
it 'should return Metasploit::Model::Login::Status::INCORRECT for an invalid credential' do
|
||||
bad_auth_res = Rex::Proto::Http::Response.new(200)
|
||||
http_scanner.should_receive(:try_login).with(cred).and_return(bad_auth_res)
|
||||
http_scanner.try_glassfish_2(cred)[:status].should eq(Metasploit::Model::Login::Status::INCORRECT)
|
||||
end
|
||||
end
|
||||
|
||||
context '#try_glassfish_3' do
|
||||
it 'should return status Metasploit::Model::Login::Status::SUCCESSFUL for a valid credential' do
|
||||
good_auth_res = Rex::Proto::Http::Response.new(302)
|
||||
good_res = Rex::Proto::Http::Response.new(200)
|
||||
good_res.stub(:body).and_return('<title>Deploy Applications or Modules</title>')
|
||||
http_scanner.should_receive(:try_login).with(cred).and_return(good_auth_res)
|
||||
http_scanner.should_receive(:send_request).with(kind_of(Hash)).and_return(good_res)
|
||||
http_scanner.try_glassfish_3(cred)[:status].should eq(Metasploit::Model::Login::Status::SUCCESSFUL)
|
||||
end
|
||||
|
||||
it 'should return status Metasploit::Model::Login::Status::SUCCESSFUL based on a disabled remote admin message' do
|
||||
good_auth_res = Rex::Proto::Http::Response.new(200)
|
||||
good_auth_res.stub(:body).and_return('Secure Admin must be enabled')
|
||||
http_scanner.should_receive(:try_login).with(cred).and_return(good_auth_res)
|
||||
http_scanner.try_glassfish_3(cred)[:status].should eq(Metasploit::Model::Login::Status::SUCCESSFUL)
|
||||
end
|
||||
|
||||
it 'should return status Metasploit::Model::Login::Status::INCORRECT for an invalid credential' do
|
||||
bad_auth_res = Rex::Proto::Http::Response.new(200)
|
||||
http_scanner.should_receive(:try_login).with(cred).and_return(bad_auth_res)
|
||||
http_scanner.try_glassfish_3(cred)[:status].should eq(Metasploit::Model::Login::Status::INCORRECT)
|
||||
end
|
||||
end
|
||||
|
||||
context '#attempt_login' do
|
||||
it 'Rex::ConnectionError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Rex::ConnectionError)
|
||||
|
||||
expect(http_scanner.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
|
||||
end
|
||||
|
||||
it 'Timeout::Error should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Timeout::Error)
|
||||
|
||||
expect(http_scanner.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
|
||||
end
|
||||
|
||||
it 'EOFError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(EOFError)
|
||||
|
||||
expect(http_scanner.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
|
||||
end
|
||||
|
||||
it 'Unsupported Glassfish version should result in a GlassfishError exception' do
|
||||
http_scanner.version = bad_version
|
||||
expect { http_scanner.attempt_login(cred) }.to raise_exception(Metasploit::Framework::LoginScanner::GlassfishError)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue