Redo BES rspec
parent
6eb25743e3
commit
ed69e5f902
|
@ -1,53 +1,84 @@
|
||||||
require 'spec_helper'
|
#require 'spec_helper'
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
|
|
||||||
describe Msf::Exploit::Remote::BrowserExploitServer do
|
describe Msf::Exploit::Remote::BrowserExploitServer do
|
||||||
|
|
||||||
|
# When unpacked, this gives us:
|
||||||
|
# {
|
||||||
|
# "BAP.1433806920.Client.blLGFIlwYrxfvcY" =>
|
||||||
|
# {
|
||||||
|
# "source" => "script",
|
||||||
|
# "os_name" => "Windows 8.1",
|
||||||
|
# "os_vendor" => "undefined",
|
||||||
|
# "os_device" => "undefined",
|
||||||
|
# "ua_name" => "Firefox",
|
||||||
|
# "ua_ver" => "35.0",
|
||||||
|
# "arch" => "x86",
|
||||||
|
# "java" => "1.7",
|
||||||
|
# "silverlight" => "false",
|
||||||
|
# "flash" => "14.0",
|
||||||
|
# "vuln_test" => "true",
|
||||||
|
# "proxy" => false,
|
||||||
|
# "language" => "en-US,en;q=0.5",
|
||||||
|
# "tried" => true,
|
||||||
|
# "activex" => [{"clsid"=>"{D27CDB6E-AE6D-11cf-96B8-444553540000}", "method"=>"LoadMovie"}]
|
||||||
|
# }}
|
||||||
|
let(:first_packed_profile) do
|
||||||
|
"\x81\xD9%BAP.1433806920.Client.blLGFIlwYrxfvcY\x8F\xA6source\xA6script\xA7os_name\xABWindows 8.1\xA9os_vendor\xA9undefined\xA9os_device\xA9undefined\xA7ua_name\xA7Firefox\xA6ua_ver\xA435.0\xA4arch\xA3x86\xA4java\xA31.7\xABsilverlight\xA5false\xA5flash\xA414.0\xA9vuln_test\xA4true\xA5proxy\xC2\xA8language\xC4\x0Een-US,en;q=0.5\xA5tried\xC3\xA7activex\x91\x82\xA5clsid\xD9&{D27CDB6E-AE6D-11cf-96B8-444553540000}\xA6method\xA9LoadMovie"
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:default_note_type_prefix) do
|
||||||
|
MessagePack.unpack(first_packed_profile).keys.first.split('.')[0,3] * "."
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:first_profile_tag) do
|
||||||
|
MessagePack.unpack(first_packed_profile).keys.first.split('.')[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:first_profile_info) do
|
||||||
|
MessagePack.unpack(first_packed_profile).values.first
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:cli) do
|
||||||
|
sock = Rex::Socket::Tcp
|
||||||
|
allow(sock).to receive(:peerhost).and_return('0.0.0.0')
|
||||||
|
allow(sock).to receive(:peerport).and_return(4444)
|
||||||
|
sock
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_fake_note(tag, data)
|
||||||
|
note = double('note')
|
||||||
|
allow(note).to receive(:ntype).and_return(tag)
|
||||||
|
allow(note).to receive(:data).and_return(data)
|
||||||
|
|
||||||
|
note
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
allow_any_instance_of(described_class).to receive(:vprint_status)
|
||||||
|
@notes = [create_fake_note(first_profile_tag, first_packed_profile)]
|
||||||
|
end
|
||||||
|
|
||||||
subject(:server) do
|
subject(:server) do
|
||||||
mod = Msf::Exploit::Remote.allocate
|
mod = Msf::Exploit::Remote.allocate
|
||||||
mod.extend described_class
|
mod.extend described_class
|
||||||
mod.send(:initialize, {})
|
mod.send(:initialize)
|
||||||
|
mod.send(:datastore=, {'NoteTypePrefix' => default_note_type_prefix})
|
||||||
mod
|
mod
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:service_double) do
|
let(:service_double) do
|
||||||
service = double('service')
|
service = double('service')
|
||||||
service.stub(:server_name=)
|
allow(service).to receive(:server_name=)
|
||||||
service.stub(:add_resource)
|
allow(service).to receive(:add_resource)
|
||||||
service
|
service
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:expected_user_agent) do
|
|
||||||
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:profile_name) do
|
|
||||||
'random'
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:expected_os_name) do
|
|
||||||
'linux'
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:exploit_page) do
|
let(:exploit_page) do
|
||||||
server.instance_variable_get(:@exploit_receiver_page)
|
server.instance_variable_get(:@exploit_receiver_page)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:expected_profile) do
|
|
||||||
{
|
|
||||||
:source =>'script',
|
|
||||||
:os_name =>'Windows XP',
|
|
||||||
:ua_name =>'MSIE',
|
|
||||||
:ua_ver =>'8.0',
|
|
||||||
:arch =>'x86',
|
|
||||||
:office =>'null',
|
|
||||||
:activex => [ {clsid: '{D27CDB6E-AE6D-11cf-96B8-444553540000}', method: 'LoadMovie'} ],
|
|
||||||
:proxy => false,
|
|
||||||
:language => 'en-us',
|
|
||||||
:tried => true
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Rex::ServiceManager.stub(:start => service_double)
|
Rex::ServiceManager.stub(:start => service_double)
|
||||||
end
|
end
|
||||||
|
@ -58,7 +89,8 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
||||||
|
|
||||||
it_should_behave_like 'Msf::Exploit::JSObfu'
|
it_should_behave_like 'Msf::Exploit::JSObfu'
|
||||||
|
|
||||||
describe "#get_module_resource" do
|
|
||||||
|
describe '#get_module_resource' do
|
||||||
it "should give me a URI to access the exploit page" do
|
it "should give me a URI to access the exploit page" do
|
||||||
module_resource = server.get_module_resource
|
module_resource = server.get_module_resource
|
||||||
expect(module_resource).to include(exploit_page)
|
expect(module_resource).to include(exploit_page)
|
||||||
|
@ -67,127 +99,68 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
||||||
|
|
||||||
describe '#has_bad_activex?' do
|
describe '#has_bad_activex?' do
|
||||||
context 'when there is a bad activex' do
|
context 'when there is a bad activex' do
|
||||||
let(:js_ax_value) { "#{expected_profile[:activex][0][:clsid]}=>#{expected_profile[:activex][0][:method]}=>false" }
|
let(:js_ax_value) { "#{first_profile_info['activex'][0][:clsid]}=>#{first_profile_info['activex'][0][:method]}=>false" }
|
||||||
it 'returns false' do
|
it 'returns false' do
|
||||||
expect(server.has_bad_activex?(js_ax_value)).to be_truthy
|
expect(server.has_bad_activex?(js_ax_value)).to be_truthy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when there is no bad activex' do
|
context 'when there is no bad activex' do
|
||||||
let(:js_ax_value) { "#{expected_profile[:activex][0][:clsid]}=>#{expected_profile[:activex][0][:method]}=>true" }
|
let(:js_ax_value) { "#{first_profile_info['activex'][0][:clsid]}=>#{first_profile_info['activex'][0][:method]}=>true" }
|
||||||
it 'returns true' do
|
it 'returns true' do
|
||||||
expect(server.has_bad_activex?(js_ax_value)).to be_falsey
|
expect(server.has_bad_activex?(js_ax_value)).to be_falsey
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#get_bad_requirements" do
|
describe '#get_bad_requirements' do
|
||||||
let(:rejected_requirements) do
|
let(:this_profile) do
|
||||||
server.get_bad_requirements(fake_profile)
|
MessagePack.unpack(first_packed_profile)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when given the expected profile' do
|
let(:requirements) { {} }
|
||||||
it "should not contain any bad requirements" do
|
|
||||||
expect(server.get_bad_requirements(expected_profile)).to eq([])
|
before(:each) do
|
||||||
|
r = server.instance_variable_get(:@requirements)
|
||||||
|
requirements.each_pair do |key, value|
|
||||||
|
r[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
server.instance_variable_set(:@requirements, r)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when all requirements are met' do
|
||||||
|
let(:requirements) { first_profile_info }
|
||||||
|
it 'returns an empty bad requirement array' do
|
||||||
|
expect(server.get_bad_requirements(this_profile)).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when attempting to match :os_name' do
|
context 'when the os_name requirement is not met' do
|
||||||
let(:fake_profile) do
|
let(:requirements) { {'os_name'=>'Linux'} }
|
||||||
{ :os_name => expected_os_name }
|
it 'returns os_name in the array as a bad requirement' do
|
||||||
end
|
expect(server.get_bad_requirements(this_profile)).to eq(['os_name'])
|
||||||
|
|
||||||
before do
|
|
||||||
server.instance_variable_set(:@requirements, {:os_name => /win/i})
|
|
||||||
end
|
|
||||||
|
|
||||||
it "identifies :os_name as a requirement not met" do
|
|
||||||
expect(rejected_requirements).to eq([:os_name])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when attempting to match :ua_ver' do
|
context 'when a Linux regex cannot match a Winodws os_name' do
|
||||||
context 'against version 25.0' do
|
let(:requirements) { {'os_name'=>/Linux/} }
|
||||||
let(:expected_ua_ver) { '25.0' }
|
it 'returns os_name in the array as a bad requirement' do
|
||||||
let(:fake_profile) do
|
expect(server.get_bad_requirements(this_profile)).to eq(['os_name'])
|
||||||
{ :ua_ver => expected_ua_ver }
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
|
||||||
server.instance_variable_set(:@requirements, {:ua_ver => ua_ver})
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with the regex /26\.0$/" do
|
|
||||||
let(:ua_ver) { /26\.0$/ }
|
|
||||||
it "should reject :ua_ver" do
|
|
||||||
expect(rejected_requirements).to include(:ua_ver)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with the regex /25\.0$/" do
|
|
||||||
let(:ua_ver) { /25\.0$/ }
|
|
||||||
it "should accept :ua_ver" do
|
|
||||||
expect(rejected_requirements).not_to include(:ua_ver)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with a Proc that checks if version is between 1-5" do
|
|
||||||
let(:ua_ver) { lambda{ |ver| ver.to_i.between?(1, 5) } }
|
|
||||||
it "should reject :ua_ver" do
|
|
||||||
expect(rejected_requirements).to include(:ua_ver)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with a Proc that checks if version is between 20-26" do
|
|
||||||
let(:ua_ver) { lambda{ |ver| ver.to_i.between?(20, 26) } }
|
|
||||||
it "should accept :ua_ver" do
|
|
||||||
expect(rejected_requirements).not_to include(:ua_ver)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#init_profile" do
|
describe '#get_detection_html' do
|
||||||
it "should initialize an empety profile for tag 'random'" do
|
|
||||||
server.init_profile(profile_name)
|
|
||||||
ivar_target_profile = server.instance_variable_get(:@target_profiles)
|
|
||||||
expect(ivar_target_profile).to eq({profile_name=>{}})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#get_profile" do
|
|
||||||
it "should return nil when a profile isn't found" do
|
|
||||||
server.init_profile(profile_name)
|
|
||||||
p = server.get_profile("non_existent_profile")
|
|
||||||
expect(p).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns a profile if found" do
|
|
||||||
server.init_profile(profile_name)
|
|
||||||
p = server.get_profile(profile_name)
|
|
||||||
expect(p).to eq({})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#update_profile" do
|
|
||||||
it "updates my target profile's :os_name information" do
|
|
||||||
server.init_profile(profile_name)
|
|
||||||
profile = server.get_profile(profile_name)
|
|
||||||
server.update_profile(profile, :os_name, expected_os_name)
|
|
||||||
profile = server.get_profile(profile_name)
|
|
||||||
expect(profile[:os_name]).to eq(expected_os_name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#get_detection_html" do
|
|
||||||
it "returns the detection code that the client will get" do
|
it "returns the detection code that the client will get" do
|
||||||
|
expected_user_agent = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'
|
||||||
html = server.get_detection_html(expected_user_agent)
|
html = server.get_detection_html(expected_user_agent)
|
||||||
expect(html).not_to eq('')
|
expect(html).not_to eq('')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#on_request_exploit" do
|
|
||||||
|
describe '#on_request_exploit' do
|
||||||
it "raises a NoMethodError if called" do
|
it "raises a NoMethodError if called" do
|
||||||
fake_cli = nil
|
fake_cli = nil
|
||||||
fake_request = nil
|
fake_request = nil
|
||||||
|
@ -198,130 +171,148 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#get_target" do
|
describe '#get_target' do
|
||||||
it "returns a target" do
|
it "returns a target" do
|
||||||
#
|
expected_object = double('Msf::Module::Target')
|
||||||
# Using Object for Msf::Module::Target
|
|
||||||
#
|
|
||||||
expected_object = Object
|
|
||||||
server.instance_variable_set(:@target, expected_object)
|
server.instance_variable_set(:@target, expected_object)
|
||||||
server.get_target.should eq(expected_object)
|
server.get_target.should eq(expected_object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#try_set_target" do
|
describe '#try_set_target' do
|
||||||
it "Sets a target based on requirements" do
|
let(:fake_targets) do
|
||||||
#
|
target = double('Msf::Module::Target')
|
||||||
# This testcase needs to be better somehow, but not sure how to actually create
|
allow(target).to receive(:opts) { first_profile_info }
|
||||||
# a Msf::Module::Target. All we're able to test here is making sure the method
|
[target]
|
||||||
# doesn't raise anything by exercising the code.
|
end
|
||||||
#
|
|
||||||
server.instance_variable_set(:@requirements, {:os_name => /win/i})
|
before(:each) do
|
||||||
server.instance_variable_set(:@target, Object)
|
allow_any_instance_of(described_class).to receive(:targets) { fake_targets }
|
||||||
server.try_set_target(expected_profile)
|
end
|
||||||
server.get_target.should eq(Object)
|
|
||||||
|
context 'when requirements match a target' do
|
||||||
|
it 'sets @target' do
|
||||||
|
expect(server.get_target).to be_nil
|
||||||
|
server.try_set_target(MessagePack.unpack(first_packed_profile))
|
||||||
|
expect(server.get_target).to eq(fake_targets.first)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#extract_requirements" do
|
describe 'extract_requirements' do
|
||||||
it "finds all the recognizable keys" do
|
context 'when a recognizable requirement is given' do
|
||||||
requirements = {:os_name=>"Windows XP", :ua_name=>"MSIE", :ua_ver=>"8.0"}
|
it 'returns a hash that contains the recognizable requirement' do
|
||||||
matches = server.extract_requirements(requirements)
|
expected_hash = {'os_name'=>'Linux'}
|
||||||
expect(matches).to eq(requirements)
|
expect(server.extract_requirements(expected_hash)).to eq(expected_hash)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "makes sure the keys are always symbols" do
|
context 'when a unrecognizable requirement is given' do
|
||||||
requirements = {'os_name'=>"Windows XP", 'ua_name'=>"MSIE"}
|
it 'returns a hash that does not have the unrecognizable requirement' do
|
||||||
matches = server.extract_requirements(requirements)
|
bad_hash = {'UNKNOWN_KEY'=>'VALUE'}
|
||||||
matches.each do |k,v|
|
expect(server.extract_requirements(bad_hash)).to be_empty
|
||||||
expect(k.class).to eq(Symbol)
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#retrieve_tag' do
|
||||||
|
context 'when the browser has a cookie that contains our tag' do
|
||||||
|
let(:tag) do
|
||||||
|
'tag'
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:cookie) do
|
||||||
|
"__ua=#{tag};"
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:cli_request) do
|
||||||
|
req = Rex::Proto::Http::Request.new
|
||||||
|
req.headers['Cookie'] = cookie
|
||||||
|
req
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the tag from the cookie' do
|
||||||
|
expect(server.retrieve_tag(cli, cli_request)).to eq(tag)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the browser does not have a tag' do
|
||||||
|
|
||||||
|
let(:cli_request) do
|
||||||
|
Rex::Proto::Http::Request.new
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns a new one in MD5' do
|
||||||
|
expect(server.retrieve_tag(cli, cli_request)).to match(/^[0-9a-f]{32}$/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#on_request_uri' do
|
describe '#on_request_uri' do
|
||||||
let(:cli) { double(:peerhost => '0.0.0.0') }
|
before(:each) do
|
||||||
let(:cookie) { '' }
|
allow(server).to receive(:get_profile_info) { MessagePack.unpack(first_packed_profile) }
|
||||||
let(:headers) { {'Cookie' => cookie, 'User-Agent' => ''} }
|
allow(server).to receive(:init_profile).with(kind_of(String))
|
||||||
let(:body) { '' }
|
allow(server).to receive(:update_profile)
|
||||||
let(:cookie_name) { Msf::Exploit::Remote::BrowserExploitServer::DEFAULT_COOKIE_NAME }
|
allow(server).to receive(:process_browser_info)
|
||||||
let(:request) do
|
allow(server).to receive(:send_response) { @send_response_called = true }
|
||||||
double(:body => body, :headers => headers, :uri => server.get_resource )
|
allow(server).to receive(:send_redirect) { @send_redirect_called = true }
|
||||||
|
allow(server).to receive(:send_not_found) { @send_not_found_called = true}
|
||||||
|
allow(server).to receive(:on_request_exploit) { @on_request_exploit_called = true }
|
||||||
|
allow(server).to receive(:on_request_exploit) { @on_request_exploit_called = true }
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
after(:each) do
|
||||||
server.stub(:send_redirect)
|
@send_response_called = false
|
||||||
server.stub(:send_response)
|
@send_redirect_called = false
|
||||||
server.stub(:send_not_found)
|
@on_request_exploit_called = false
|
||||||
|
@send_not_found_called = false
|
||||||
|
@on_request_exploit_called = false
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a new visitor requests the exploit' do
|
context 'when / is requested' do
|
||||||
before { JSObfu.disabled = true }
|
it 'sends the information gathering page' do
|
||||||
after { JSObfu.disabled = false }
|
cli_request = Rex::Proto::Http::Request.new
|
||||||
|
server.on_request_uri(cli, cli_request)
|
||||||
it 'calls send_response once' do
|
expect(@send_redirect_called).to be_truthy
|
||||||
server.should_receive(:send_response).once
|
|
||||||
server.on_request_uri(cli, request)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'serves the os.js detection script' do
|
|
||||||
server.should_receive(:send_response) do |cli, html, headers|
|
|
||||||
expect(html).to include('os_detect')
|
|
||||||
end
|
|
||||||
server.on_request_uri(cli, request)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a returning visitor requests the exploit' do
|
context 'when info_receiver_page is requested' do
|
||||||
let(:body) { '' }
|
it 'sends an empty page' do
|
||||||
let(:tag) { 'joe' }
|
info_receiver_page_var = server.instance_variable_get(:@info_receiver_page)
|
||||||
let(:cookie) { "#{cookie_name}=#{tag}" }
|
cli_request = Rex::Proto::Http::Request.new
|
||||||
|
cli_request.uri = info_receiver_page_var
|
||||||
before { server.init_profile(tag) }
|
server.on_request_uri(cli, cli_request)
|
||||||
|
expect(@send_response_called).to be_truthy
|
||||||
it 'calls send_redirect once' do
|
|
||||||
server.should_receive(:send_redirect).once
|
|
||||||
server.on_request_uri(cli, request)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'redirects to the exploit URL' do
|
|
||||||
server.should_receive(:send_redirect) do |cli, url|
|
|
||||||
expect(url).to end_with("#{exploit_page}/")
|
|
||||||
end
|
|
||||||
server.on_request_uri(cli, request)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a returning visitor from a previous msf run requests the exploit' do
|
context 'when noscript_receiver_page is requested' do
|
||||||
let(:body) { '' }
|
it 'sends a not-found' do
|
||||||
let(:tag) { 'joe' }
|
noscript_receiver_page_var = server.instance_variable_get(:@noscript_receiver_page)
|
||||||
let(:cookie) { "#{cookie_name}=#{tag}" }
|
cli_request = Rex::Proto::Http::Request.new
|
||||||
|
cli_request.uri = noscript_receiver_page_var
|
||||||
before { JSObfu.disabled = true }
|
server.on_request_uri(cli, cli_request)
|
||||||
after { JSObfu.disabled = false }
|
expect(@send_not_found_called).to be_truthy
|
||||||
|
|
||||||
it 'calls send_response once' do
|
|
||||||
server.should_receive(:send_response).once
|
|
||||||
server.on_request_uri(cli, request)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'serves the os.js detection script' do
|
|
||||||
server.should_receive(:send_response) do |cli, html, headers|
|
|
||||||
expect(html).to include('os_detect')
|
|
||||||
end
|
|
||||||
server.on_request_uri(cli, request)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when exploit_receiver_page is requested' do
|
||||||
|
it 'calls on_request_exploit' do
|
||||||
|
exploit_receiver_page_var = server.instance_variable_get(:@exploit_receiver_page)
|
||||||
|
cli_request = Rex::Proto::Http::Request.new
|
||||||
|
cli_request.uri = exploit_receiver_page_var
|
||||||
|
server.on_request_uri(cli, cli_request)
|
||||||
|
expect(@on_request_exploit_called).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#get_payload' do
|
describe '#get_payload' do
|
||||||
let(:cli) {
|
|
||||||
Rex::Socket::Tcp
|
|
||||||
}
|
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
allow(cli).to receive(:peerhost).and_return('0.0.0.0')
|
target = double('Msf::Module::Target')
|
||||||
allow(cli).to receive(:peerport).and_return(4444)
|
allow(target).to receive(:arch).and_return(nil)
|
||||||
|
allow(server).to receive(:get_target).and_return(target)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:encoded) { '@EXE@' }
|
let(:encoded) { '@EXE@' }
|
||||||
|
@ -330,25 +321,15 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
||||||
double(:encoded => encoded, :arch => ['x86'])
|
double(:encoded => encoded, :arch => ['x86'])
|
||||||
}
|
}
|
||||||
|
|
||||||
let(:x86_64_payload) {
|
let(:normalized_profile_info) {
|
||||||
double(:encoded => encoded, :arch => ['x86_64'])
|
first_profile_info.inject({}){|data,(k,v)| data[k.to_sym] = v; data}
|
||||||
}
|
}
|
||||||
|
|
||||||
context 'when the payload supports the visitor\'s browser architecture' do
|
context 'when the payload supports the visitor\'s browser architecture' do
|
||||||
it 'returns a payload' do
|
it 'returns a payload' do
|
||||||
allow(server).to receive(:regenerate_payload).and_return(x86_payload)
|
allow(server).to receive(:regenerate_payload).and_return(x86_payload)
|
||||||
expect(server.get_payload(cli, expected_profile)).to eq(encoded)
|
expect(server.get_payload(cli, normalized_profile_info)).to eq(encoded)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the payload does not support the visitor\'s browser architecture' do
|
|
||||||
it 'raises a BESException' do
|
|
||||||
allow(server).to receive(:regenerate_payload).and_return(x86_64_payload)
|
|
||||||
expect{server.get_payload(cli, expected_profile)}.to raise_error(Msf::Exploit::Remote::BrowserExploitServer::BESException)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue