Land #14458, Add auxiliary support to autocheck mixin
This commit is contained in:
@@ -16,10 +16,24 @@ module Exploit::Remote::AutoCheck
|
||||
])
|
||||
end
|
||||
|
||||
def run
|
||||
with_prepended_auto_check do
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
with_prepended_auto_check do
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def with_prepended_auto_check
|
||||
unless datastore['AutoCheck']
|
||||
print_warning('AutoCheck is disabled, proceeding with exploitation')
|
||||
return super
|
||||
return yield
|
||||
end
|
||||
|
||||
print_status('Executing automatic check (disable AutoCheck to override)')
|
||||
@@ -30,14 +44,14 @@ module Exploit::Remote::AutoCheck
|
||||
case (checkcode = check)
|
||||
when Exploit::CheckCode::Vulnerable, Exploit::CheckCode::Appears
|
||||
print_good(checkcode.message)
|
||||
super
|
||||
yield
|
||||
when Exploit::CheckCode::Detected
|
||||
print_warning(checkcode.message)
|
||||
super
|
||||
yield
|
||||
when Exploit::CheckCode::Safe
|
||||
if datastore['ForceExploit']
|
||||
print_warning("#{checkcode.message} #{warning_msg}")
|
||||
return super
|
||||
return yield
|
||||
end
|
||||
|
||||
fail_with(Module::Failure::NotVulnerable,
|
||||
@@ -45,19 +59,18 @@ module Exploit::Remote::AutoCheck
|
||||
when Exploit::CheckCode::Unsupported
|
||||
if datastore['ForceExploit']
|
||||
print_warning("#{checkcode.message} #{warning_msg}")
|
||||
return super
|
||||
return yield
|
||||
end
|
||||
|
||||
fail_with(Module::Failure::BadConfig, "#{checkcode.message} #{error_msg}")
|
||||
else
|
||||
if datastore['ForceExploit']
|
||||
print_warning("#{checkcode.message} #{warning_msg}")
|
||||
return super
|
||||
return yield
|
||||
end
|
||||
|
||||
fail_with(Module::Failure::Unknown, "#{checkcode.message} #{error_msg}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
prepend Msf::Exploit::Remote::AutoCheck
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
@@ -42,8 +43,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
])
|
||||
|
||||
register_advanced_options([
|
||||
OptBool.new('DefangedMode', [true, 'Run in defanged mode', true]),
|
||||
OptBool.new('ForceExploit', [true, 'Override check result', false])
|
||||
OptBool.new('DefangedMode', [true, 'Run in defanged mode', true])
|
||||
])
|
||||
end
|
||||
|
||||
@@ -72,15 +72,6 @@ class MetasploitModule < Msf::Auxiliary
|
||||
return
|
||||
end
|
||||
|
||||
checkcode = check
|
||||
|
||||
unless datastore['ForceExploit']
|
||||
unless checkcode == Exploit::CheckCode::Appears
|
||||
print_error("#{checkcode[1]}. Set ForceExploit to override.")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
case action.name
|
||||
when 'Cook'
|
||||
print_status("Cooking on #{datastore['TEMP']} for #{datastore['TIME']}m")
|
||||
|
||||
@@ -9,15 +9,15 @@ RSpec.shared_examples "An AutoCheck module which can be overridden" do |opts|
|
||||
context "when ForceExploit is enabled" do
|
||||
before(:each) do
|
||||
subject.datastore['ForceExploit'] = true
|
||||
subject.exploit
|
||||
subject.send(opts[:method])
|
||||
end
|
||||
|
||||
it "calls the check method" do
|
||||
expect(subject).to have_received(:check)
|
||||
end
|
||||
|
||||
it 'calls the original exploit' do
|
||||
expect(subject).to have_received(:original_exploit_call)
|
||||
it "calls the original #{opts[:method ]} method" do
|
||||
expect(subject).to have_received(:"original_#{opts[:method]}_call")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -27,15 +27,94 @@ RSpec.shared_examples "An AutoCheck module which can be overridden" do |opts|
|
||||
subject.datastore['ForceExploit'] = false
|
||||
end
|
||||
|
||||
it "it doesn't call the original exploit" do
|
||||
expect { subject.exploit }.to raise_error(opts[:expected_error]) do
|
||||
expect(subject).to_not have_received(:original_exploit_call)
|
||||
it "it doesn't call the original #{opts[:method ]} method" do
|
||||
expect { subject.send(opts[:method]) }.to raise_error(opts[:expected_error]) do
|
||||
expect(subject).to_not have_received(:"original_#{opts[:method]}_call")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples "An AutoChecked method" do |opts|
|
||||
subject { mock_module_with_prepend_autocheck.new }
|
||||
|
||||
before(:each) do
|
||||
allow(subject).to receive(:check).and_return(check_result)
|
||||
allow(subject).to receive(:"original_#{opts[:method]}_call").and_call_original
|
||||
end
|
||||
|
||||
context 'when AutoCheck is disabled' do
|
||||
let(:check_result) { ::Msf::Exploit::CheckCode::Vulnerable }
|
||||
|
||||
before(:each) do
|
||||
subject.datastore['AutoCheck'] = false
|
||||
subject.send(opts[:method])
|
||||
end
|
||||
|
||||
it "doesn't call the check method" do
|
||||
expect(subject).to_not have_received(:check)
|
||||
end
|
||||
|
||||
it "correctly calls the #{opts[:method]} method" do
|
||||
expect(subject).to have_received(:"original_#{opts[:method]}_call")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when AutoCheck is enabled' do
|
||||
before(:each) do
|
||||
subject.datastore['AutoCheck'] = true
|
||||
end
|
||||
|
||||
context 'when the check method returns vulnerable' do
|
||||
let(:check_result) { ::Msf::Exploit::CheckCode::Vulnerable }
|
||||
|
||||
before(:each) do
|
||||
subject.send(opts[:method])
|
||||
end
|
||||
|
||||
it "calls the check method" do
|
||||
expect(subject).to have_received(:check)
|
||||
end
|
||||
|
||||
it "calls the original #{opts[:method]} method" do
|
||||
expect(subject).to have_received(:"original_#{opts[:method]}_call")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the check method returns appears' do
|
||||
let(:check_result) { ::Msf::Exploit::CheckCode::Appears }
|
||||
|
||||
before(:each) do
|
||||
subject.send(opts[:method])
|
||||
end
|
||||
|
||||
it "calls the check method" do
|
||||
expect(subject).to have_received(:check)
|
||||
end
|
||||
|
||||
it "calls the original #{opts[:method]} method" do
|
||||
expect(subject).to have_received(:"original_#{opts[:method]}_call")
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "An AutoCheck module which can be overridden",
|
||||
method: opts[:method],
|
||||
check_code: ::Msf::Exploit::CheckCode::Safe,
|
||||
expected_error: "The target is not exploitable. Enable ForceExploit to override check result."
|
||||
|
||||
it_behaves_like "An AutoCheck module which can be overridden",
|
||||
method: opts[:method],
|
||||
check_code: ::Msf::Exploit::CheckCode::Unsupported,
|
||||
expected_error: "This module does not support check. Enable ForceExploit to override check result."
|
||||
|
||||
it_behaves_like "An AutoCheck module which can be overridden",
|
||||
method: opts[:method],
|
||||
check_code: ::Msf::Exploit::CheckCode::Unknown,
|
||||
expected_error: "Cannot reliably check exploitability. Enable ForceExploit to override check result."
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Msf::Exploit::Remote::AutoCheck do
|
||||
let(:mock_module_with_prepend_autocheck) do
|
||||
context_described_class = described_class
|
||||
@@ -46,6 +125,14 @@ RSpec.describe Msf::Exploit::Remote::AutoCheck do
|
||||
# mocked
|
||||
end
|
||||
|
||||
def run
|
||||
original_run_call
|
||||
end
|
||||
|
||||
def original_run_call
|
||||
# Helper for verifying the original run function was called
|
||||
end
|
||||
|
||||
def exploit
|
||||
original_exploit_call
|
||||
end
|
||||
@@ -69,80 +156,12 @@ RSpec.describe Msf::Exploit::Remote::AutoCheck do
|
||||
end
|
||||
|
||||
context 'when the mixin is prepended' do
|
||||
describe '#run' do
|
||||
it_behaves_like 'An AutoChecked method', method: :run
|
||||
end
|
||||
|
||||
describe '#exploit' do
|
||||
subject { mock_module_with_prepend_autocheck.new }
|
||||
|
||||
before(:each) do
|
||||
allow(subject).to receive(:check).and_return(check_result)
|
||||
allow(subject).to receive(:original_exploit_call).and_call_original
|
||||
end
|
||||
|
||||
context 'when AutoCheck is disabled' do
|
||||
let(:check_result) { ::Msf::Exploit::CheckCode::Vulnerable }
|
||||
|
||||
before(:each) do
|
||||
subject.datastore['AutoCheck'] = false
|
||||
subject.exploit
|
||||
end
|
||||
|
||||
it "doesn't call the check method" do
|
||||
expect(subject).to_not have_received(:check)
|
||||
end
|
||||
|
||||
it "correctly calls the exploit method" do
|
||||
expect(subject).to have_received(:original_exploit_call)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when AutoCheck is enabled' do
|
||||
before(:each) do
|
||||
subject.datastore['AutoCheck'] = true
|
||||
end
|
||||
|
||||
context 'when the check method returns vulnerable' do
|
||||
let(:check_result) { ::Msf::Exploit::CheckCode::Vulnerable }
|
||||
|
||||
before(:each) do
|
||||
subject.exploit
|
||||
end
|
||||
|
||||
it "calls the check method" do
|
||||
expect(subject).to have_received(:check)
|
||||
end
|
||||
|
||||
it 'calls the original exploit' do
|
||||
expect(subject).to have_received(:original_exploit_call)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the check method returns appears' do
|
||||
let(:check_result) { ::Msf::Exploit::CheckCode::Appears }
|
||||
|
||||
before(:each) do
|
||||
subject.exploit
|
||||
end
|
||||
|
||||
it "calls the check method" do
|
||||
expect(subject).to have_received(:check)
|
||||
end
|
||||
|
||||
it 'calls the original exploit' do
|
||||
expect(subject).to have_received(:original_exploit_call)
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "An AutoCheck module which can be overridden",
|
||||
check_code: ::Msf::Exploit::CheckCode::Safe,
|
||||
expected_error: "The target is not exploitable. Enable ForceExploit to override check result."
|
||||
|
||||
it_behaves_like "An AutoCheck module which can be overridden",
|
||||
check_code: ::Msf::Exploit::CheckCode::Unsupported,
|
||||
expected_error: "This module does not support check. Enable ForceExploit to override check result."
|
||||
|
||||
it_behaves_like "An AutoCheck module which can be overridden",
|
||||
check_code: ::Msf::Exploit::CheckCode::Unknown,
|
||||
expected_error: "Cannot reliably check exploitability. Enable ForceExploit to override check result."
|
||||
end
|
||||
it_behaves_like 'An AutoChecked method', method: :exploit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user