PowerSploit/Tests/Recon.tests.ps1

584 lines
21 KiB
PowerShell

$TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$ModuleRoot = Resolve-Path "$TestScriptRoot\.."
$ModuleManifest = "$ModuleRoot\Recon\Recon.psd1"
Remove-Module [R]econ
Import-Module $ModuleManifest -Force -ErrorAction Stop
# import PowerView.ps1 manually so we expose the helper functions for testing
$PowerViewFile = "$ModuleRoot\Recon\PowerView.ps1"
Import-Module $PowerViewFile -Force -ErrorAction Stop
# Get the local IP address for later testing
$IPregex = "(?<Address>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
$LocalIP = (gwmi Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -match $IPregex}).ipaddress[0]
########################################################
#
# PowerView functions.
#
########################################################
Describe 'Export-PowerViewCSV' {
It 'Should Not Throw and should produce .csv output.' {
{Get-Process | Export-PowerViewCSV -OutFile process_test.csv} | Should Not Throw
'.\process_test.csv' | Should Exist
Remove-Item -Force .\process_test.csv
}
}
Describe 'Get-IPAddress' {
$IPregex = "(?<Address>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
It 'Should return local IP address' {
if( $(Get-IPAddress) -notmatch $IPRegex ) {
Throw 'Invalid local IP address returned'
}
}
It 'Should accept -ComputerName argument' {
if( $(Get-IPAddress -ComputerName $env:COMPUTERNAME) -notmatch $IPRegex ) {
Throw 'Invalid -ComputerName IP address returned'
}
}
}
Describe 'Convert-SidToName' {
It 'Should resolve built in SIDs' {
Convert-SidToName -SID 'S-1-5-32-545' | Should Be 'BUILTIN\Users'
}
It 'Should accept pipeline input' {
'S-1-5-32-552' | Convert-SidToName | Should Be 'BUILTIN\Replicators'
}
It 'Should return a unresolvable SID' {
Convert-SidToName -SID 'S-1-5-32-1337' | Should Be 'S-1-5-32-1337'
}
}
Describe 'Get-Proxy' {
It 'Should Not Throw' {
{Get-Proxy} | Should Not Throw
}
It 'Should accept -ComputerName argument' {
{Get-Proxy -ComputerName $env:COMPUTERNAME} | Should Not Throw
}
}
Describe 'Get-PathAcl' {
It 'Should Not Throw' {
{Get-PathAcl C:\} | Should Not Throw
}
It 'Should return correct ACLs' {
$Output = Get-PathAcl -Path C:\Windows | ?{$_.IdentityReference -eq "Creator Owner"}
if(-not $Output) {
Throw "Output Not returned"
}
if($Output.FileSystemRights -ne 'GenericAll') {
Throw "Incorrect FileSystemRights returned"
}
}
}
Describe 'Get-NameField' {
It 'Should extract dnshostname field from custom object' {
$Object = New-Object -TypeName PSObject -Property @{'dnshostname' = 'testing1'}
if ( (Get-NameField -Object $Object) -ne 'testing1') {
Throw "'dnshostname' field Not parsed correctly"
}
}
It 'Should extract name field from custom object' {
$Object = New-Object -TypeName PSObject -Property @{'name' = 'testing2'}
if ( (Get-NameField -Object $Object) -ne 'testing2') {
Throw "'name' field Not parsed correctly"
}
}
It 'Should handle plaintext strings' {
if ( (Get-NameField -Object 'testing3') -ne 'testing3') {
Throw 'Plaintext string Not parsed correctly'
}
}
It 'Should accept pipeline input' {
$Object = New-Object -TypeName PSObject -Property @{'dnshostname' = 'testing4'}
if ( ($Object | Get-NameField) -ne 'testing4') {
Throw 'Pipeline input Not processed correctly'
}
}
}
Describe "Get-NetLocalGroup" {
It "Should return results for local machine administrators" {
if ( (Get-NetLocalGroup | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should return results for listing local groups" {
if ( (Get-NetLocalGroup -ListGroups | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
# TODO: -ComputerList
It "Should accept -GroupName argument" {
{Get-NetLocalGroup -GroupName "Remote Desktop Users"} | Should Not Throw
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetLocalGroup -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetLocalGroup -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should accept pipeline input" {
if ( ( "$env:computername" | Get-NetLocalGroup | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
}
Describe "Get-NetShare" {
It "Should return results for the local host" {
if ( (Get-NetShare | Measure-Object).count -lt 1) {
Throw "Incorrect share results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetShare -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetShare -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect share results returned"
}
}
It "Should accept pipeline input" {
if ( ( "$env:computername" | Get-NetShare | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
}
Describe "Get-NetLoggedon" {
It "Should return results for the local host" {
if ( (Get-NetLoggedon | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetLoggedon -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetLoggedon -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept pipeline input" {
if ( ( "$env:computername" | Get-NetLoggedon | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
}
Describe "Get-NetSession" {
It "Should return results for the local host" {
if ( (Get-NetSession | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetSession -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetSession -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept the -UserName argument" {
{Get-NetSession -UserName 'Administrator'} | Should Not Throw
}
It "Should accept pipeline input" {
{"$env:computername" | Get-NetSession} | Should Not Throw
}
}
Describe "Get-NetRDPSession" {
It "Should return results for the local host" {
if ( (Get-NetRDPSession | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetRDPSession -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetRDPSession -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept pipeline input" {
{"$env:computername" | Get-NetRDPSession} | Should Not Throw
}
}
Describe "Invoke-CheckLocalAdminAccess" {
It "Should Not Throw for localhost" {
{Invoke-CheckLocalAdminAccess} | Should Not Throw
}
It "Should accept NETBIOS -ComputerName argument" {
{Invoke-CheckLocalAdminAccess -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept IP -ComputerName argument" {
{Invoke-CheckLocalAdminAccess -ComputerName $LocalIP} | Should Not Throw
}
It "Should accept pipeline input" {
{"$env:computername" | Invoke-CheckLocalAdminAccess} | Should Not Throw
}
}
Describe "Get-LastLoggedOn" {
It "Should return results for the local host" {
if ( (Get-LastLoggedOn | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-LastLoggedOn -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-LastLoggedOn -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept pipeline input" {
{"$env:computername" | Get-LastLoggedOn} | Should Not Throw
}
}
Describe "Get-CachedRDPConnection" {
It "Should Not Throw" {
{Get-CachedRDPConnection} | Should Not Throw
}
It "Should accept NETBIOS -ComputerName argument" {
{Get-CachedRDPConnection -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept IP -ComputerName argument" {
{Get-CachedRDPConnection -ComputerName $LocalIP} | Should Not Throw
}
It "Should accept pipeline input" {
{"$env:computername" | Get-CachedRDPConnection} | Should Not Throw
}
}
Describe "Get-NetProcess" {
It "Should return results for the local host" {
if ( (Get-NetProcess | Measure-Object).count -lt 1) {
Throw "Incorrect process results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetProcess -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect process results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetProcess -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect process results returned"
}
}
# TODO: RemoteUserName/RemotePassword
It "Should accept pipeline input" {
{"$env:computername" | Get-NetProcess} | Should Not Throw
}
}
Describe "Find-InterestingFile" {
#TODO: implement
}
Describe "Invoke-UserHunter" {
It "Should accept -ComputerName argument" {
if ( (Invoke-UserHunter -ShowAll -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-UserHunter -ComputerFile ".\targets.txt" -ShowAll | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -NoPing flag" {
if ( (Invoke-UserHunter -ComputerName "$env:computername" -UserName $env:USERNAME -NoPing | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-UserHunter -ShowAll -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername", "$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-StealthUserHunter" {
# simple test of the splatting
It "Should accept splatting for Invoke-UserHunter" {
{Invoke-StealthUserHunter -ShowAll -ComputerName "$env:computername"} | Should Not Throw
}
}
Describe "Invoke-ProcessHunter" {
It "Should accept -ComputerName and -UserName arguments" {
if ( (Invoke-ProcessHunter -UserName $env:USERNAME -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-ProcessHunter -ComputerFile ".\targets.txt" -UserName $env:USERNAME | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -ProcessName argument" {
if ( (Invoke-ProcessHunter -ComputerName "$env:computername" -ProcessName powershell | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -UserFile argument" {
"$env:USERNAME" | Out-File -Encoding ASCII target_users.txt
if ( (Invoke-ProcessHunter -ComputerName "$env:computername" -UserFile ".\target_users.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\target_users.txt"
}
It "Should accept -NoPing flag" {
if ( (Invoke-ProcessHunter -ComputerName "$env:computername" -UserName $env:USERNAME -NoPing | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-ProcessHunter -UserName $env:USERNAME -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername", "$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-ShareFinder" {
It "Should accept -ComputerName argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-ShareFinder -ComputerFile ".\targets.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -ExcludeStandard argument" {
{Invoke-ShareFinder -ComputerName "$env:computername" -ExcludeStandard} | Should Not Throw
}
It "Should accept -ExcludePrint argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -ExcludePrint | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -ExcludeIPC argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -ExcludeIPC | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -CheckShareAccess argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -CheckShareAccess | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -CheckAdmin argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -CheckAdmin | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -NoPing argument" {
if ( (Invoke-ShareFinder -NoPing -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-ShareFinder -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername", "$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-FileFinder" {
It "Should accept -ComputerName argument" {
{Invoke-FileFinder -ComputerName "$env:computername"} | Should Not Throw
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
{Invoke-FileFinder -ComputerFile ".\targets.txt"} | Should Not Throw
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
try {
It "Should accept -ShareList argument" {
"\\$($env:computername)\\IPC$" | Out-File -Encoding ASCII shares.txt
{Invoke-FileFinder -ShareList ".\shares.txt"} | Should Not Throw
}
}
finally {
Remove-Item -Force ".\shares.txt"
}
It "Should accept -Terms argument" {
{Invoke-FileFinder -Terms secret,testing -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -OfficeDocs argument" {
{Invoke-FileFinder -OfficeDocs -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -FreshEXEs argument" {
{Invoke-FileFinder -FreshEXEs -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -LastAccessTime argument" {
{Invoke-FileFinder -LastAccessTime "01/01/2000" -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -LastWriteTime argument" {
{Invoke-FileFinder -LastWriteTime "01/01/2000" -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -ExcludeFolders argument" {
{Invoke-FileFinder -ExcludeFolders -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -ExcludeHidden argument" {
{Invoke-FileFinder -ExcludeHidden -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -CreationTime argument" {
{Invoke-FileFinder -CreationTime "01/01/2000" -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -OutFile argument" {
{Invoke-FileFinder -ComputerName "$env:computername" -OutFile "found_files.csv"} | Should Not Throw
if(Test-Path -Path .\found_files.csv) {
$Null = Remove-Item -Force .\found_files.csv
}
}
It "Should accept -NoPing argument" {
{Invoke-FileFinder -NoPing -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -Delay and -Jitter arguments" {
{Invoke-FileFinder -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername","$env:computername")} | Should Not Throw
}
}
Describe "Find-LocalAdminAccess" {
It "Should accept -ComputerName argument" {
if ( (Find-LocalAdminAccess -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Find-LocalAdminAccess -ComputerFile ".\targets.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -NoPing argument" {
if ( (Find-LocalAdminAccess -NoPing -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Find-LocalAdminAccess -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername","$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-EnumerateLocalAdmin" {
It "Should accept -ComputerName argument" {
if ( (Invoke-EnumerateLocalAdmin -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-EnumerateLocalAdmin -ComputerFile ".\targets.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -NoPing argument" {
if ( (Invoke-EnumerateLocalAdmin -NoPing -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-EnumerateLocalAdmin -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername","$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Outfile argument" {
Invoke-EnumerateLocalAdmin -ComputerName "$env:computername" -OutFile "local_admins.csv"
".\local_admins.csv" | Should Exist
Remove-Item -Force .\local_admins.csv
}
}