Add some spec mockery

bug/bundler_fix
Meatballs 2015-03-18 23:43:46 +00:00
parent 81fa509b50
commit 975ddc9092
No known key found for this signature in database
GPG Key ID: 5380EAF01F2F8B38
2 changed files with 222 additions and 5 deletions

View File

@ -42,7 +42,7 @@ module Msf::Post::Windows::Runas
end end
# #
# Create a STARTUP_INFO struct for use with CreateProcessa # Create a STARTUP_INFO struct for use with CreateProcessA
# #
# This struct will cause the process to be hidden # This struct will cause the process to be hidden
# #
@ -192,6 +192,9 @@ module Msf::Post::Windows::Runas
# @return [Hash] The values from the process_information struct # @return [Hash] The values from the process_information struct
# #
def parse_process_information(process_information) def parse_process_information(process_information)
fail ArgumentError, 'process_information is nil' if process_information.nil?
fail ArgumentError, 'process_information is empty string' if process_information.empty?
pi = process_information.unpack('LLLL') pi = process_information.unpack('LLLL')
{ :process_handle => pi[0], :thread_handle => pi[1], :process_id => pi[2], :thread_id => pi[3] } { :process_handle => pi[0], :thread_handle => pi[1], :process_id => pi[2], :thread_id => pi[3] }
end end
@ -208,6 +211,8 @@ module Msf::Post::Windows::Runas
# @return [True] True if username is in the correct format # @return [True] True if username is in the correct format
# #
def check_user_format(username, domain) def check_user_format(username, domain)
fail ArgumentError, 'username is nil' if username.nil?
if domain && username.include?('@') if domain && username.include?('@')
raise ArgumentError, 'Username is in UPN format (user@domain) so the domain parameter must be nil' raise ArgumentError, 'Username is in UPN format (user@domain) so the domain parameter must be nil'
end end
@ -230,12 +235,17 @@ module Msf::Post::Windows::Runas
# @return [True] True if the command_line is within the correct bounds # @return [True] True if the command_line is within the correct bounds
# #
def check_command_length(application_name, command_line, max_length) def check_command_length(application_name, command_line, max_length)
fail ArgumentError, 'max_length is nil' if max_length.nil?
if application_name.nil? && command_line.nil? if application_name.nil? && command_line.nil?
raise ArgumentError, 'Both application_name and command_line are nil' raise ArgumentError, 'Both application_name and command_line are nil'
elsif application_name.nil? && command_line && command_line.length > MAX_PATH elsif command_line && command_line.length > max_length
raise ArgumentError, "When application_name is nil the command line must be less than MAX_PATH #{MAX_PATH} characters (Currently #{command_line.length})" raise ArgumentError, "Command line must be less than #{max_length} characters (Currently #{command_line.length})"
elsif application_name && command_line && command_line.length > max_length elsif application_name.nil? && command_line
raise ArgumentError, "When application_name is set, command line must be less than #{max_length} characters (Currently #{command_line.length})" cl = command_line.split(' ')
if cl[0] && cl[0].length > MAX_PATH
raise ArgumentError, "When application_name is nil the command line module must be less than MAX_PATH #{MAX_PATH} characters (Currently #{cl[0].length})"
end
end end
true true

View File

@ -0,0 +1,207 @@
# -*- coding: binary -*-
require 'spec_helper'
require 'msf/core/post/windows/runas'
describe Msf::Post::Windows::Runas do
let(:process_info) do
"\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00"
end
let(:phToken) do
"testPhToken"
end
let(:advapi32) do
advapi32 = double('advapi32')
advapi32.stub(:CreateProcessWithLogonW).and_return(
'return' => true,
'lpProcessInformation' => process_info
)
advapi32.stub(:CreateProcessAsUserA).and_return ({
'return' => true,
'lpProcessInformation' => process_info
})
advapi32.stub(:LogonUserA).and_return ({
'return' => true,
'phToken' => phToken
})
advapi32
end
let(:kernel32) do
double('kernel32', CloseHandle: nil)
end
subject do
mod = Module.new
mod.extend described_class
stubs = [ :vprint_status, :print_status, :vprint_good, :print_good, :print_error ]
stubs.each { |meth| mod.stub(meth) }
mod.stub_chain("session.railgun.kernel32").and_return(kernel32)
mod.stub_chain("session.railgun.advapi32").and_return(advapi32)
mod
end
context "#create_process_with_logon" do
it "should return a process_info hash" do
expect(advapi32).to receive(:CreateProcessWithLogonW)
expect(kernel32).not_to receive(:CloseHandle)
pi = subject.create_process_with_logon(nil, 'bob', 'pass', nil, 'cmd.exe')
pi.should be_kind_of(Hash)
pi.should eq(process_handle: 1, thread_handle: 2, process_id: 3, thread_id: 4)
end
it "should return a nil on failure" do
expect(advapi32).to receive(:CreateProcessWithLogonW)
expect(kernel32).not_to receive(:CloseHandle)
advapi32.stub(:CreateProcessWithLogonW).and_return('return' => false, 'GetLastError' => 1783, 'ErrorMessage' => 'parp')
subject.create_process_with_logon(nil, 'bob', 'pass', nil, 'cmd.exe').should be nil
end
end
context "#create_process_as_user" do
it "should return a process_info hash" do
expect(advapi32).to receive(:LogonUserA)
expect(advapi32).to receive(:CreateProcessAsUserA)
expect(kernel32).to receive(:CloseHandle).with(phToken)
expect(kernel32).to receive(:CloseHandle).with(1)
expect(kernel32).to receive(:CloseHandle).with(2)
pi = subject.create_process_as_user(nil, 'bob', 'pass', nil, 'cmd.exe')
pi.should be_kind_of(Hash)
pi.should eq(process_handle: 1, thread_handle: 2, process_id: 3, thread_id: 4)
end
it "should return a nil on failure of create process" do
expect(advapi32).to receive(:LogonUserA)
expect(advapi32).to receive(:CreateProcessAsUserA)
expect(kernel32).to receive(:CloseHandle).with(phToken)
expect(kernel32).not_to receive(:CloseHandle).with(1)
expect(kernel32).not_to receive(:CloseHandle).with(2)
advapi32.stub(:CreateProcessAsUserA).and_return('return' => false, 'GetLastError' => 1783, 'ErrorMessage' => 'parp')
subject.create_process_as_user(nil, 'bob', 'pass', nil, 'cmd.exe').should be nil
end
it "should return a nil on failure of logon user" do
expect(advapi32).to receive(:LogonUserA)
expect(advapi32).not_to receive(:CreateProcessAsUserA)
expect(kernel32).not_to receive(:CloseHandle).with(phToken)
expect(kernel32).not_to receive(:CloseHandle).with(1)
expect(kernel32).not_to receive(:CloseHandle).with(2)
advapi32.stub(:LogonUserA).and_return('return' => false, 'GetLastError' => 1783, 'ErrorMessage' => 'parp')
subject.create_process_as_user(nil, 'bob', 'pass', nil, 'cmd.exe').should be nil
end
end
context "#startup_info" do
it "should be 68 bytes" do
subject.startup_info.size.should eq(68)
end
it "should return SW_HIDE=0 and STARTF_USESHOWWINDOW=1" do
si = subject.startup_info.unpack('VVVVVVVVVVVVvvVVVV')
si[11].should eq(1)
si[12].should eq(0)
end
end
context "#parse_process_information" do
it "should return a hash when given valid data" do
pi = subject.parse_process_information(process_info)
pi.should be_kind_of(Hash)
pi.should eq(process_handle: 1, thread_handle: 2, process_id: 3, thread_id: 4)
end
it "should return an exception when given an empty string" do
expect { subject.parse_process_information("") }.to raise_error
end
it "should return an exception when given an nil value" do
expect { subject.parse_process_information(nil) }.to raise_error
end
end
context "#check_user_format" do
let(:upn_username) do
"bob@flob.com"
end
let(:domain_username) do
"flob\\bob"
end
let(:domain) do
"flob"
end
it "should return an exception when username is nil" do
expect { subject.check_user_format(nil, domain) }.to raise_error
end
it "should return an exception when UPN format and domain supplied" do
expect { subject.check_user_format(upn_username, domain) }.to raise_error
end
it "should return true when UPN format and domain is nil" do
subject.check_user_format(upn_username, nil).should be true
end
it "should return true when domain format and domain is nil" do
subject.check_user_format(domain_username, nil).should be true
end
it "should return true when domain format and domain supplied" do
subject.check_user_format(domain_username, domain).should be true
end
end
context "#check_command_length" do
let(:max_length) do
1024
end
let(:max_path) do
256
end
let(:large_command_module) do
("A" * max_path + 1) + " arg1 arg2"
end
let(:normal_command_module) do
("A" * max_path) + " arg1 arg2"
end
let(:large_command_line) do
"A" * max_length + 1
end
let(:normal_command_line) do
"A" * max_length
end
let(:application_name) do
"c:\\windows\\system32\\calc.exe"
end
it "should raise an exception when max_length is nil" do
expect { subject.check_command_length(nil, nil, nil) }.to raise_error
end
it "should raise an exception when application_name and command_line are nil" do
expect { subject.check_command_length(nil, nil, max_length) }.to raise_error
end
it "should return true when application_name is set and command_line is nil" do
subject.check_command_length(application_name, nil, max_length).should be true
end
it "should return true when application_name is set and command_line is max_length" do
subject.check_command_length(application_name, normal_command_line, max_length).should be true
end
it "should raise an exception when command_line is larger than max_length" do
expect { subject.check_command_length(nil, large_command_line, max_length) }.to raise_error
end
it "should raise an exception when application_name is nil command_line module is larger than MAX_PATH" do
expect { subject.check_command_length(nil, large_command_module, max_length) }.to raise_error
end
it "should return true when application_name is nil and command_module is less than MAX_PATH" do
subject.check_command_length(nil, normal_command_module, max_length).should be true
end
end
end