Files
metasploit-gs/spec/lib/rex/powershell/parser_spec.rb
T
Luke Imhoff 4870909afc .should -> expect().to
MSP-13484
2015-12-10 21:47:22 -06:00

160 lines
5.5 KiB
Ruby

# -*- coding:binary -*-
require 'spec_helper'
require 'rex/powershell'
RSpec.describe Rex::Powershell::Parser do
let(:example_script) do
"""
function Find-4624Logons
{
$some_literal = @\"
using System;
using System.Runtime.InteropServices;
namespace $kernel32 {
public class func {
[Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 }
[Flags] public enum MemoryProtection { ExecuteReadWrite = 0x40 }
[Flags] public enum Time : uint { Infinite = 0xFFFFFFFF }
[DllImport(\"kernel32.dll\")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport(\"kernel32.dll\")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport(\"kernel32.dll\")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds);
}
}
\"@
if (-not ($NewLogonAccountDomain -cmatch \"NT\\sAUTHORITY\" -or $NewLogonAccountDomain -cmatch \"Window\\sManager\"))
{
$Key = $AccountName + $AccountDomain + $NewLogonAccountName + $NewLogonAccountDomain + $LogonType + $WorkstationName + $SourceNetworkAddress + $SourcePort
if (-not $ReturnInfo.ContainsKey($Key))
{
$Properties = @{
LogType = 4624
LogSource = \"Security\"
SourceAccountName = $AccountName
SourceDomainName = $AccountDomain
NewLogonAccountName = $NewLogonAccountName
NewLogonAccountDomain = $NewLogonAccountDomain
LogonType = $LogonType
WorkstationName = $WorkstationName
SourceNetworkAddress = $SourceNetworkAddress
SourcePort = $SourcePort
Count = 1
Times = @($Logon.TimeGenerated)
}
$literal2 = @\"parp\"@
$ResultObj = New-Object PSObject -Property $Properties
$ReturnInfo.Add($Key, $ResultObj)
}
else
{
$ReturnInfo[$Key].Count++
$ReturnInfo[$Key].Times += ,$Logon.TimeGenerated
}
}
}
}"""
end
let(:subject) do
Rex::Powershell::Script.new(example_script)
end
describe "::get_var_names" do
it 'should return some variable names' do
vars = subject.get_var_names
expect(vars).to be
expect(vars).to be_kind_of Array
expect(vars.length).to be > 0
expect(vars.include?('$ResultObj')).to be_truthy
end
it 'should not match upper or lowercase reserved names' do
initial_vars = subject.get_var_names
subject.code << "\r\n$SHELLID"
subject.code << "\r\n$ShellId"
subject.code << "\r\n$shellid"
after_vars = subject.get_var_names
expect(initial_vars).to eq after_vars
end
end
describe "::get_func_names" do
it 'should return some function names' do
funcs = subject.get_func_names
expect(funcs).to be
expect(funcs).to be_kind_of Array
expect(funcs.length).to be > 0
expect(funcs.include?('Find-4624Logons')).to be_truthy
end
end
describe "::get_string_literals" do
it 'should return some string literals' do
literals = subject.get_string_literals
expect(literals).to be
expect(literals).to be_kind_of Array
expect(literals.length).to be > 0
expect(literals[0].include?('parp')).to be_falsey
end
end
describe "::scan_with_index" do
it 'should scan code and return the items with an index' do
scan = subject.scan_with_index('DllImport')
expect(scan).to be
expect(scan).to be_kind_of Array
expect(scan.length).to be > 0
expect(scan[0]).to be_kind_of Array
expect(scan[0][0]).to be_kind_of String
expect(scan[0][1]).to be_kind_of Integer
end
end
describe "::match_start" do
it 'should match the correct brackets' do
expect(subject.match_start('{')).to eq '}'
expect(subject.match_start('(')).to eq ')'
expect(subject.match_start('[')).to eq ']'
expect(subject.match_start('<')).to eq '>'
expect { subject.match_start('p') }.to raise_exception(ArgumentError)
end
end
describe "::block_extract" do
it 'should extract a block between brackets given an index' do
idx = subject.code.index('{')
block = subject.block_extract(idx)
expect(block).to be
expect(block).to be_kind_of String
end
it 'should raise a runtime error if given an invalid index' do
expect { subject.block_extract(nil) }.to raise_error(ArgumentError)
expect { subject.block_extract(-1) }.to raise_error(ArgumentError)
expect { subject.block_extract(subject.code.length) }.to raise_error(ArgumentError)
expect { subject.block_extract(59) }.to raise_error(ArgumentError)
end
end
describe "::get_func" do
it 'should extract a function from the code' do
function = subject.get_func('Find-4624Logons')
expect(function).to be
expect(function).to be_kind_of Rex::Powershell::Function
end
it 'should return nil if function doesnt exist' do
function = subject.get_func(Rex::Text.rand_text_alpha(5))
expect(function).to be_nil
end
it 'should delete the function if delete is true' do
function = subject.get_func('Find-4624Logons', true)
expect(subject.code.include?('DllImport')).to be_falsey
end
end
end