From c143dc68859a0dbee91ad61d209b4ea918ad12f8 Mon Sep 17 00:00:00 2001 From: Harmj0y Date: Thu, 3 Dec 2015 21:57:26 -0500 Subject: Privesc/PowerUp Pester tests --- Tests/Privesc.tests.ps1 | 485 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 Tests/Privesc.tests.ps1 (limited to 'Tests/Privesc.tests.ps1') diff --git a/Tests/Privesc.tests.ps1 b/Tests/Privesc.tests.ps1 new file mode 100644 index 0000000..d1461d5 --- /dev/null +++ b/Tests/Privesc.tests.ps1 @@ -0,0 +1,485 @@ +Set-StrictMode -Version Latest + +$TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent +$ModuleRoot = Resolve-Path "$TestScriptRoot\.." + +$ModuleManifest = "$ModuleRoot\Privesc\Privesc.psd1" +Remove-Module [P]rivesc +Import-Module $ModuleManifest -Force -ErrorAction Stop + +# import PowerUp.ps1 manually so we expose the helper functions for testing +$PowerUpFile = "$ModuleRoot\Privesc\PowerUp.ps1" +Import-Module $PowerUpFile -Force -ErrorAction Stop + + + +function Get-RandomName { + $r = 1..8 | ForEach-Object{Get-Random -max 26} + return ('abcdefghijklmnopqrstuvwxyz'[$r] -join '') +} + + +######################################################## +# +# PowerUp helpers functions. +# +######################################################## + +Describe 'Get-ModifiableFile' { + + It 'Should output a file path.' { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + $Null | Out-File -FilePath $FilePath -Force + + $Output = Get-ModifiableFile -Path $FilePath + $Output | Should Be $FilePath + + Remove-Item -Path $FilePath -Force + } + + It 'Should extract a modifiable file specified as an argument in a command string.' { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + $Null | Out-File -FilePath $FilePath -Force + + $CmdPath = "'C:\Windows\System32\nonexistent.exe' -i '$FilePath'" + + $Output = Get-ModifiableFile -Path $FilePath + $Output | Should Be $FilePath + + Remove-Item -Path $FilePath -Force + } + + It 'Should return no results for a non-existent path.' { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + + $Output = Get-ModifiableFile -Path $FilePath + $Output | Should BeNullOrEmpty + } + + It 'Should accept a Path over the pipeline.' { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + + $Output = Get-ModifiableFile -Path $FilePath + $Output | Should BeNullOrEmpty + } +} + + +######################################################## +# +# PowerUp service enumeration functions. +# +######################################################## + +Describe 'Get-ServiceUnquoted' { + + It "Should not throw." { + {Get-ServiceUnquoted} | Should Not Throw + } + + It 'Should return service with a space in an unquoted binPath.' { + $ServiceName = Get-RandomName + $ServicePath = "C:\Program Files\service.exe" + + sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS" + Start-Sleep -Seconds 1 + + $Output = Get-ServiceUnquoted | Where-Object { $_.ServiceName -eq $ServiceName } + sc.exe delete $ServiceName | Should Match "SUCCESS" + + $Output | Should Not BeNullOrEmpty + $Output.ServiceName | Should Be $ServiceName + $Output.Path | Should Be $ServicePath + } + + It 'Should not return services with a quoted binPath.' { + $ServiceName = Get-RandomName + $ServicePath = "'C:\Program Files\service.exe'" + + sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS" + Start-Sleep -Seconds 1 + + $Output = Get-ServiceUnquoted | Where-Object { $_.ServiceName -eq $ServiceName } + sc.exe delete $ServiceName | Should Match "SUCCESS" + + $Output | Should BeNullOrEmpty + } +} + + +Describe 'Get-ServiceFilePermission' { + + It 'Should not throw.' { + {Get-ServiceFilePermission} | Should Not Throw + } + + It 'Should return a service with a modifiable service binary.' { + $ServiceName = Get-RandomName + $ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe" + $Null | Out-File -FilePath $ServicePath -Force + + sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS" + + $Output = Get-ServiceFilePermission | Where-Object { $_.ServiceName -eq $ServiceName } + sc.exe delete $ServiceName | Should Match "SUCCESS" + Remove-Item -Path $ServicePath -Force + + $Output | Should Not BeNullOrEmpty + $Output.ServiceName | Should Be $ServiceName + $Output.Path | Should Be $ServicePath + } + + It 'Should not return a service with a non-existent service binary.' { + $ServiceName = Get-RandomName + $ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe" + + sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS" + + $Output = Get-ServiceFilePermission | Where-Object { $_.ServiceName -eq $ServiceName } + sc.exe delete $ServiceName | Should Match "SUCCESS" + + $Output | Should BeNullOrEmpty + } +} + + +Describe 'Get-ServicePermission' { + + It 'Should not throw.' { + {Get-ServicePermission} | Should Not Throw + } + + It 'Should return a modifiable service.' { + $Output = Get-ServicePermission | Where-Object { $_.ServiceName -eq 'Dhcp'} + $Output | Should Not BeNullOrEmpty + } +} + + +Describe 'Get-ServiceDetail' { + + It 'Should return results for a valid service.' { + $Output = Get-ServiceDetail -ServiceName Dhcp + $Output | Should Not BeNullOrEmpty + } + + It 'Should return not results for an invalid service.' { + $Output = Get-ServiceDetail -ServiceName NonExistent123 + $Output | Should BeNullOrEmpty + } +} + + + +######################################################## +# +# PowerUp service abuse functions. +# +######################################################## + +Describe 'Invoke-ServiceAbuse' { + + BeforeEach { + $ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe" + $Null = sc.exe create "PowerUpService" binPath= $ServicePath + } + + AfterEach { + $Null = sc.exe delete "PowerUpService" + $Null = $(net user john /delete >$Null 2>&1) + } + + It 'Should abuse a vulnerable service to add a local administrator with default options.' { + $Output = Invoke-ServiceAbuse -ServiceName "PowerUpService" + $Output.Command | Should Match "net" + + if( -not ($(net localgroup Administrators) -match "john")) { + Throw "Local user 'john' not created." + } + } + + It 'Should accept a service name on the pipeline.' { + $Output = "PowerUpService" | Invoke-ServiceAbuse + $Output.Command | Should Match "net" + + if( -not ($(net localgroup Administrators) -match "john")) { + Throw "Local user 'john' not created." + } + } + + It 'User should not be created for a non-existent service.' { + $Output = Invoke-ServiceAbuse -ServiceName "NonExistentService456" + $Output.Command | Should Match "Not found" + + if( ($(net localgroup Administrators) -match "john")) { + Throw "Local user 'john' should not have been created for non-existent service." + } + } + + It 'Should accept custom user/password arguments.' { + $Output = Invoke-ServiceAbuse -ServiceName "PowerUpService" -Username PowerUp -Password 'PASSword123!' + $Output.Command | Should Match "net" + + if( -not ($(net localgroup Administrators) -match "PowerUp")) { + Throw "Local user 'PowerUp' not created." + } + $Null = $(net user PowerUp /delete >$Null 2>&1) + } + + It 'Should accept a custom command.' { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + $Output = Invoke-ServiceAbuse -ServiceName "PowerUpService" -Command "net user testing Password123! /add" + + if( -not ($(net user) -match "testing")) { + Throw "Custom command failed." + } + $Null = $(net user testing /delete >$Null 2>&1) + } +} + + +Describe 'Install-ServiceBinary' { + + BeforeEach { + $ServicePath = "$(Get-Location)\powerup.exe" + $Null | Out-File -FilePath $ServicePath -Force + $Null = sc.exe create "PowerUpService" binPath= $ServicePath + } + + AfterEach { + $Null = Invoke-ServiceStop -ServiceName PowerUpService + $Null = sc.exe delete "PowerUpService" + $Null = $(net user john /delete >$Null 2>&1) + if(Test-Path "$(Get-Location)\powerup.exe") { + Remove-Item -Path "$(Get-Location)\powerup.exe" -Force + } + if(Test-Path "$(Get-Location)\powerup.exe.bak") { + Remove-Item -Path "$(Get-Location)\powerup.exe.bak" -Force + } + } + + It 'Should abuse a vulnerable service binary to add a local administrator with default options.' { + + $Output = Install-ServiceBinary -ServiceName "PowerUpService" + $Output.Command | Should Match "net" + + $Null = Invoke-ServiceStart -ServiceName PowerUpService + Start-Sleep -Seconds 3 + if( -not ($(net localgroup Administrators) -match "john")) { + Throw "Local user 'john' not created." + } + $Null = Invoke-ServiceStop -ServiceName PowerUpService + + $Output = Restore-ServiceBinary -ServiceName PowerUpService + "$(Get-Location)\powerup.exe.bak" | Should Not Exist + } + + It 'Should accept a service name on the pipeline.' { + + $Output = "PowerUpService" | Install-ServiceBinary + $Output.Command | Should Match "net" + + $Null = Invoke-ServiceStart -ServiceName PowerUpService + Start-Sleep -Seconds 3 + if( -not ($(net localgroup Administrators) -match "john")) { + Throw "Local user 'john' not created." + } + $Null = Invoke-ServiceStop -ServiceName PowerUpService + + $Output = Restore-ServiceBinary -ServiceName PowerUpService + "$(Get-Location)\powerup.exe.bak" | Should Not Exist + } + + It 'User should not be created for a non-existent service.' { + $Output = Install-ServiceBinary -ServiceName "NonExistentService456" + $Output.Command | Should Match "Not found" + } + + It 'Should accept custom user/password arguments.' { + $Output = Install-ServiceBinary -ServiceName "PowerUpService" -Username PowerUp -Password 'PASSword123!' + $Output.Command | Should Match "net" + + $Null = Invoke-ServiceStart -ServiceName PowerUpService + Start-Sleep -Seconds 3 + if( -not ($(net localgroup Administrators) -match "PowerUp")) { + Throw "Local user 'PowerUp' not created." + } + $Null = $(net user PowerUp /delete >$Null 2>&1) + + $Output = Restore-ServiceBinary -ServiceName PowerUpService + "$(Get-Location)\powerup.exe.bak" | Should Not Exist + } + + It 'Should accept a custom command.' { + + $Output = Install-ServiceBinary -ServiceName "PowerUpService" -Command "net user testing Password123! /add" + $Output.Command | Should Match "net" + + $Null = Invoke-ServiceStart -ServiceName PowerUpService + Start-Sleep -Seconds 3 + if( -not ($(net user) -match "testing")) { + Throw "Custom command failed." + } + $Null = $(net user testing /delete >$Null 2>&1) + + $Output = Restore-ServiceBinary -ServiceName PowerUpService + "$(Get-Location)\powerup.exe.bak" | Should Not Exist + } +} + + +######################################################## +# +# PowerUp .dll hijacking functions. +# +######################################################## + +Describe 'Find-DLLHijack' { + It 'Should return results.' { + $Output = Find-DLLHijack + $Output | Should Not BeNullOrEmpty + } +} + + +Describe 'Find-PathHijack' { + + It 'Should find a hijackable %PATH% folder.' { + + New-Item -Path C:\PowerUpTest\ -ItemType directory -Force + + $OldPath = $Env:PATH + $Env:PATH += ';C:\PowerUpTest\' + + $Output = Find-PathHijack | Where-Object {$_.HijackablePath -like "*PowerUpTest*"} + $Env:PATH = $OldPath + $Output.HijackablePath | Should Be 'C:\PowerUpTest\' + } +} + +# won't actually execute on Win8+ with the wlbsctrl.dll method +Describe 'Write-HijackDll' { + + It 'Should write a .dll that executes a custom command.' { + + Write-HijackDll -OutputFile "$(Get-Location)\powerup.dll" -Command "net user testing Password123! /add" + + "$(Get-Location)\powerup.dll" | Should Exist + "$(Get-Location)\debug.bat" | Should Exist + Remove-Item -Path "$(Get-Location)\powerup.dll" -Force + Remove-Item -Path "$(Get-Location)\debug.bat" -Force + } +} + + +######################################################## +# +# PowerUp registry checks. +# +######################################################## + +Describe 'Get-RegAlwaysInstallElevated' { + It 'Should not throw.' { + {Get-ServicePermission} | Should Not Throw + } +} + + +Describe 'Get-RegAutoLogon' { + It 'Should not throw.' { + {Get-ServicePermission} | Should Not Throw + } +} + + +Describe 'Get-VulnAutoRun' { + It 'Should not throw.' { + {Get-VulnAutoRun} | Should Not Throw + } + It 'Should find a vulnerable autorun.' { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + $Null | Out-File -FilePath $FilePath -Force + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp -Value "vuln.exe -i '$FilePath'" + + $Output = Get-VulnAutoRun | ?{$_.Path -like "*$FilePath*"} + + Remove-Item -Path $FilePath -Force + $Null = Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp + + $Output.ModifiableFile | Should Be $FilePath + } +} + + +######################################################## +# +# PowerUp misc. checks. +# +######################################################## + +Describe 'Get-VulnSchTask' { + It 'Should not throw.' { + {Get-VulnSchTask} | Should Not Throw + } + + It 'Should find a vulnerable config file for a binary specified in a schtask.' { + + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + $Null | Out-File -FilePath $FilePath -Force + + $Null = schtasks.exe /create /tn PowerUp /tr "vuln.exe -i '$FilePath'" /sc onstart /ru System /f + + $Output = Get-VulnSchTask | Where-Object {$_.TaskName -eq 'PowerUp'} + $Null = schtasks.exe /delete /tn PowerUp /f + Remove-Item -Path $FilePath -Force + + $Output.TaskFilePath | Should Be $FilePath + } +} + + +Describe 'Get-UnattendedInstallFile' { + It 'Should not throw.' { + {Get-UnattendedInstallFile} | Should Not Throw + } + It 'Should return a leftover autorun' { + $FilePath = Join-Path $Env:WinDir "\System32\Sysprep\unattend.xml" + + $Null | Out-File -FilePath $FilePath -Force + $Output = Get-UnattendedInstallFile + $Output | Should Not BeNullOrEmpty + + Remove-Item -Path $FilePath -Force + } +} + + +Describe 'Get-Webconfig' { + It 'Should not throw.' { + {Get-Webconfig} | Should Not Throw + } +} + + +Describe 'Get-ApplicationHost' { + It 'Should not throw.' { + {Get-ApplicationHost} | Should Not Throw + } +} + + +Describe 'Invoke-AllChecks' { + It 'Should return results to stdout.' { + $Output = Invoke-AllChecks + $Output | Should Not BeNullOrEmpty + } + It 'Should produce a HTML report with -HTMLReport.' { + $Output = Invoke-AllChecks -HTMLReport + $Output | Should Not BeNullOrEmpty + + $HtmlReportFile = "$($Env:ComputerName).$($Env:UserName).html" + + $HtmlReportFile | Should Exist + Remove-Item -Path $HtmlReportFile -Force + } +} -- cgit v1.2.3 From e2993b63aaf09026a11dc3ba2f0ae4a364f27113 Mon Sep 17 00:00:00 2001 From: Harmj0y Date: Mon, 14 Dec 2015 18:19:17 -0500 Subject: Modified Tests/Privesc.tests.ps1 to ensure file artifacts are not left on disk. --- Tests/Privesc.tests.ps1 | 165 ++++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 62 deletions(-) (limited to 'Tests/Privesc.tests.ps1') diff --git a/Tests/Privesc.tests.ps1 b/Tests/Privesc.tests.ps1 index d1461d5..6593c84 100644 --- a/Tests/Privesc.tests.ps1 +++ b/Tests/Privesc.tests.ps1 @@ -31,10 +31,13 @@ Describe 'Get-ModifiableFile' { $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" $Null | Out-File -FilePath $FilePath -Force - $Output = Get-ModifiableFile -Path $FilePath - $Output | Should Be $FilePath - - Remove-Item -Path $FilePath -Force + try { + $Output = Get-ModifiableFile -Path $FilePath + $Output | Should Be $FilePath + } + finally { + $Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue + } } It 'Should extract a modifiable file specified as an argument in a command string.' { @@ -43,10 +46,13 @@ Describe 'Get-ModifiableFile' { $CmdPath = "'C:\Windows\System32\nonexistent.exe' -i '$FilePath'" - $Output = Get-ModifiableFile -Path $FilePath - $Output | Should Be $FilePath - - Remove-Item -Path $FilePath -Force + try { + $Output = Get-ModifiableFile -Path $FilePath + $Output | Should Be $FilePath + } + finally { + $Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue + } } It 'Should return no results for a non-existent path.' { @@ -59,7 +65,7 @@ Describe 'Get-ModifiableFile' { It 'Should accept a Path over the pipeline.' { $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" - $Output = Get-ModifiableFile -Path $FilePath + $Output = $FilePath | Get-ModifiableFile $Output | Should BeNullOrEmpty } } @@ -114,19 +120,23 @@ Describe 'Get-ServiceFilePermission' { } It 'Should return a service with a modifiable service binary.' { - $ServiceName = Get-RandomName - $ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe" - $Null | Out-File -FilePath $ServicePath -Force - - sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS" - - $Output = Get-ServiceFilePermission | Where-Object { $_.ServiceName -eq $ServiceName } - sc.exe delete $ServiceName | Should Match "SUCCESS" - Remove-Item -Path $ServicePath -Force - - $Output | Should Not BeNullOrEmpty - $Output.ServiceName | Should Be $ServiceName - $Output.Path | Should Be $ServicePath + try { + $ServiceName = Get-RandomName + $ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe" + $Null | Out-File -FilePath $ServicePath -Force + + sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS" + + $Output = Get-ServiceFilePermission | Where-Object { $_.ServiceName -eq $ServiceName } + sc.exe delete $ServiceName | Should Match "SUCCESS" + + $Output | Should Not BeNullOrEmpty + $Output.ServiceName | Should Be $ServiceName + $Output.Path | Should Be $ServicePath + } + finally { + $Null = Remove-Item -Path $ServicePath -Force + } } It 'Should not return a service with a non-existent service binary.' { @@ -138,7 +148,7 @@ Describe 'Get-ServiceFilePermission' { $Output = Get-ServiceFilePermission | Where-Object { $_.ServiceName -eq $ServiceName } sc.exe delete $ServiceName | Should Match "SUCCESS" - $Output | Should BeNullOrEmpty + $Output | Should BeNullOrEmpty } } @@ -167,6 +177,11 @@ Describe 'Get-ServiceDetail' { $Output = Get-ServiceDetail -ServiceName NonExistent123 $Output | Should BeNullOrEmpty } + + It 'Should accept a service name on the pipeline.' { + $Output = "Dhcp" | Get-ServiceDetail + $Output | Should Not BeNullOrEmpty + } } @@ -247,14 +262,18 @@ Describe 'Install-ServiceBinary' { } AfterEach { - $Null = Invoke-ServiceStop -ServiceName PowerUpService - $Null = sc.exe delete "PowerUpService" - $Null = $(net user john /delete >$Null 2>&1) - if(Test-Path "$(Get-Location)\powerup.exe") { - Remove-Item -Path "$(Get-Location)\powerup.exe" -Force + try { + $Null = Invoke-ServiceStop -ServiceName PowerUpService + $Null = sc.exe delete "PowerUpService" + $Null = $(net user john /delete >$Null 2>&1) } - if(Test-Path "$(Get-Location)\powerup.exe.bak") { - Remove-Item -Path "$(Get-Location)\powerup.exe.bak" -Force + finally { + if(Test-Path "$(Get-Location)\powerup.exe") { + $Null = Remove-Item -Path "$(Get-Location)\powerup.exe" -Force -ErrorAction SilentlyContinue + } + if(Test-Path "$(Get-Location)\powerup.exe.bak") { + $Null = Remove-Item -Path "$(Get-Location)\powerup.exe.bak" -Force -ErrorAction SilentlyContinue + } } } @@ -348,12 +367,18 @@ Describe 'Find-PathHijack' { New-Item -Path C:\PowerUpTest\ -ItemType directory -Force - $OldPath = $Env:PATH - $Env:PATH += ';C:\PowerUpTest\' + try { + $OldPath = $Env:PATH + $Env:PATH += ';C:\PowerUpTest\' + + $Output = Find-PathHijack | Where-Object {$_.HijackablePath -like "*PowerUpTest*"} - $Output = Find-PathHijack | Where-Object {$_.HijackablePath -like "*PowerUpTest*"} - $Env:PATH = $OldPath - $Output.HijackablePath | Should Be 'C:\PowerUpTest\' + $Env:PATH = $OldPath + $Output.HijackablePath | Should Be 'C:\PowerUpTest\' + } + catch { + $Null = Remove-Item -Recurse -Force 'C:\PowerUpTest\' -ErrorAction SilentlyContinue + } } } @@ -362,12 +387,16 @@ Describe 'Write-HijackDll' { It 'Should write a .dll that executes a custom command.' { - Write-HijackDll -OutputFile "$(Get-Location)\powerup.dll" -Command "net user testing Password123! /add" - - "$(Get-Location)\powerup.dll" | Should Exist - "$(Get-Location)\debug.bat" | Should Exist - Remove-Item -Path "$(Get-Location)\powerup.dll" -Force - Remove-Item -Path "$(Get-Location)\debug.bat" -Force + try { + Write-HijackDll -OutputFile "$(Get-Location)\powerup.dll" -Command "net user testing Password123! /add" + + "$(Get-Location)\powerup.dll" | Should Exist + "$(Get-Location)\debug.bat" | Should Exist + } + finally { + $Null = Remove-Item -Path "$(Get-Location)\powerup.dll" -Force -ErrorAction SilentlyContinue + $Null = Remove-Item -Path "$(Get-Location)\debug.bat" -Force -ErrorAction SilentlyContinue + } } } @@ -397,16 +426,20 @@ Describe 'Get-VulnAutoRun' { {Get-VulnAutoRun} | Should Not Throw } It 'Should find a vulnerable autorun.' { - $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" - $Null | Out-File -FilePath $FilePath -Force - Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp -Value "vuln.exe -i '$FilePath'" + try { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + $Null | Out-File -FilePath $FilePath -Force + $Null = Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp -Value "vuln.exe -i '$FilePath'" - $Output = Get-VulnAutoRun | ?{$_.Path -like "*$FilePath*"} + $Output = Get-VulnAutoRun | ?{$_.Path -like "*$FilePath*"} - Remove-Item -Path $FilePath -Force - $Null = Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp - - $Output.ModifiableFile | Should Be $FilePath + $Null = Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp + + $Output.ModifiableFile | Should Be $FilePath + } + finally { + $Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue + } } } @@ -424,16 +457,20 @@ Describe 'Get-VulnSchTask' { It 'Should find a vulnerable config file for a binary specified in a schtask.' { - $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" - $Null | Out-File -FilePath $FilePath -Force - - $Null = schtasks.exe /create /tn PowerUp /tr "vuln.exe -i '$FilePath'" /sc onstart /ru System /f + try { + $FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + $Null | Out-File -FilePath $FilePath -Force - $Output = Get-VulnSchTask | Where-Object {$_.TaskName -eq 'PowerUp'} - $Null = schtasks.exe /delete /tn PowerUp /f - Remove-Item -Path $FilePath -Force + $Null = schtasks.exe /create /tn PowerUp /tr "vuln.exe -i '$FilePath'" /sc onstart /ru System /f - $Output.TaskFilePath | Should Be $FilePath + $Output = Get-VulnSchTask | Where-Object {$_.TaskName -eq 'PowerUp'} + $Null = schtasks.exe /delete /tn PowerUp /f + + $Output.TaskFilePath | Should Be $FilePath + } + finally { + $Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue + } } } @@ -445,11 +482,15 @@ Describe 'Get-UnattendedInstallFile' { It 'Should return a leftover autorun' { $FilePath = Join-Path $Env:WinDir "\System32\Sysprep\unattend.xml" - $Null | Out-File -FilePath $FilePath -Force - $Output = Get-UnattendedInstallFile - $Output | Should Not BeNullOrEmpty + try { + $Null | Out-File -FilePath $FilePath -Force + $Output = Get-UnattendedInstallFile - Remove-Item -Path $FilePath -Force + $Output | Should Not BeNullOrEmpty + } + finally { + $Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue + } } } @@ -480,6 +521,6 @@ Describe 'Invoke-AllChecks' { $HtmlReportFile = "$($Env:ComputerName).$($Env:UserName).html" $HtmlReportFile | Should Exist - Remove-Item -Path $HtmlReportFile -Force + $Null = Remove-Item -Path $HtmlReportFile -Force -ErrorAction SilentlyContinue } } -- cgit v1.2.3 From 9ffc26af70ae089405a5c5e8df40ad557818c103 Mon Sep 17 00:00:00 2001 From: Harmj0y Date: Mon, 14 Dec 2015 19:33:15 -0500 Subject: Added admin rights check for existing Privesc Pester tests --- Tests/Privesc.tests.ps1 | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'Tests/Privesc.tests.ps1') diff --git a/Tests/Privesc.tests.ps1 b/Tests/Privesc.tests.ps1 index 6593c84..095c946 100644 --- a/Tests/Privesc.tests.ps1 +++ b/Tests/Privesc.tests.ps1 @@ -18,6 +18,10 @@ function Get-RandomName { return ('abcdefghijklmnopqrstuvwxyz'[$r] -join '') } +function Test-IsAdmin { + return ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") +} + ######################################################## # @@ -79,11 +83,16 @@ Describe 'Get-ModifiableFile' { Describe 'Get-ServiceUnquoted' { + if(-not $(Test-IsAdmin)) { + Throw "'Get-ServicePermission' Pester test needs local administrator privileges." + } + It "Should not throw." { {Get-ServiceUnquoted} | Should Not Throw } It 'Should return service with a space in an unquoted binPath.' { + $ServiceName = Get-RandomName $ServicePath = "C:\Program Files\service.exe" @@ -115,6 +124,10 @@ Describe 'Get-ServiceUnquoted' { Describe 'Get-ServiceFilePermission' { + if(-not $(Test-IsAdmin)) { + Throw "'Get-ServiceFilePermission' Pester test needs local administrator privileges." + } + It 'Should not throw.' { {Get-ServiceFilePermission} | Should Not Throw } @@ -155,6 +168,10 @@ Describe 'Get-ServiceFilePermission' { Describe 'Get-ServicePermission' { + if(-not $(Test-IsAdmin)) { + Throw "'Get-ServicePermission' Pester test needs local administrator privileges." + } + It 'Should not throw.' { {Get-ServicePermission} | Should Not Throw } @@ -193,7 +210,11 @@ Describe 'Get-ServiceDetail' { ######################################################## Describe 'Invoke-ServiceAbuse' { - + + if(-not $(Test-IsAdmin)) { + Throw "'Invoke-ServiceAbuse' Pester test needs local administrator privileges." + } + BeforeEach { $ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe" $Null = sc.exe create "PowerUpService" binPath= $ServicePath @@ -255,6 +276,10 @@ Describe 'Invoke-ServiceAbuse' { Describe 'Install-ServiceBinary' { + if(-not $(Test-IsAdmin)) { + Throw "'Install-ServiceBinary' Pester test needs local administrator privileges." + } + BeforeEach { $ServicePath = "$(Get-Location)\powerup.exe" $Null | Out-File -FilePath $ServicePath -Force @@ -363,6 +388,10 @@ Describe 'Find-DLLHijack' { Describe 'Find-PathHijack' { + if(-not $(Test-IsAdmin)) { + Throw "'Find-PathHijack' Pester test needs local administrator privileges." + } + It 'Should find a hijackable %PATH% folder.' { New-Item -Path C:\PowerUpTest\ -ItemType directory -Force @@ -422,6 +451,11 @@ Describe 'Get-RegAutoLogon' { Describe 'Get-VulnAutoRun' { + + if(-not $(Test-IsAdmin)) { + Throw "'Get-VulnAutoRun' Pester test needs local administrator privileges." + } + It 'Should not throw.' { {Get-VulnAutoRun} | Should Not Throw } @@ -451,6 +485,11 @@ Describe 'Get-VulnAutoRun' { ######################################################## Describe 'Get-VulnSchTask' { + + if(-not $(Test-IsAdmin)) { + Throw "'Get-VulnSchTask' Pester test needs local administrator privileges." + } + It 'Should not throw.' { {Get-VulnSchTask} | Should Not Throw } @@ -476,6 +515,11 @@ Describe 'Get-VulnSchTask' { Describe 'Get-UnattendedInstallFile' { + + if(-not $(Test-IsAdmin)) { + Throw "'Get-UnattendedInstallFile' Pester test needs local administrator privileges." + } + It 'Should not throw.' { {Get-UnattendedInstallFile} | Should Not Throw } -- cgit v1.2.3