From 4bff22f0b6d150d561ad28543df348106ac50df9 Mon Sep 17 00:00:00 2001 From: last-byte Date: Sun, 31 Mar 2024 21:40:04 +0200 Subject: [PATCH] implemented two new persistences; fixed suborner FP --- CHANGELOG.md | 7 ++ PersistenceSniper/PersistenceSniper.psd1 | Bin 24834 -> 24838 bytes PersistenceSniper/PersistenceSniper.psm1 | 93 +++++++++++++++++------ README.md | 4 +- 4 files changed, 79 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb6d3f2..5694fcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ # Changelog +## 1.16.0 +Features: + - Detection for the BootVerificationProgram hijacking + - Detection for the AppInit DLLs injection +Fixes: + - Fixed a false positive in the detection of the Suborner Attack caused by a faulty implementation of the Parse-NetUser internal function + ## 1.15.1 Fixes: - Fixed a gap in the detection of the techniques which relied on Get-IfSafeExecutable function which would prevent Powershell persistences from showing up diff --git a/PersistenceSniper/PersistenceSniper.psd1 b/PersistenceSniper/PersistenceSniper.psd1 index 73af2991793eccecf5bc57aa76541548cb6142eb..2baecff3e881570903ed951f259491982dcad6e0 100755 GIT binary patch delta 1635 zcmYk6OK;Oq5QV1|Y!EDfKTuS$s)U_1k9JX^x=EUc^K#NAg$<4CIBp(Iou|FP5)1x7 zB{u9?BX!HF{4u`kDiyNqT;Dl!&Y79(e0$jX{;>7?>-O`Ed=UNa^~<;SKeqqu+}C!0 zZ5?H#A-aquE3TBekL5}(#1~JJV#_C45+BQ@ti_Rn+{i0=A-l388L-Lw#QR11s4PX` zU9lu5BWcN*bfhW?)@$iQP?1wso5V+qOT0~VdiOK&?(W&=H_@>yWJ0bl8YZ$xo=Z(a zMC)R}ZDD6F`{dL?2H-jKfzNdw_y7eq*GE$rbMPhbd=L_jf#!8I^`8* z6(M#4Sp$ehCo;gY$lXYaVhqV+#E}D@n(UF%pyUCOQ;=06MKB?xn=;pM*+d;~pZztx z)DY{%S?8c9Tp=b#aCanHND1g18;dv?B2p$HFS9u5LQG;Vb_|FY*z6%;Nt3QOs4_&N zK&>ve8{}<_xF9kZcc|J%@|41qiUGgR6k6!oqDMRepc9fSK&J@%RBA(4AgK><#Cyny zYLKJACLp{ZYs=bD= zhkT8Q&mq;}Z(;HpmLb1I?0B&G5h4y`o0im&)<|AqWlbx`fD~DqTUFGd9}{Ft{N7Og zCDiI;OvJ;Qf*I4LB)JLB!Xf4?n3k+ZAOmV%#|i-*>A)JD0&*bgAY&r7F%nYs60Z%O z`%sLi(q@uV>Nl~_g=j`r9jgIWOorycrG~R$T_z(#yvn=9&K{jD@uf{b&2AD=7>3`Pm>8oAHSRTy8=KhjGte$v@GHLpg;HkRNT+2Oq(CVY=)y@{cmpJE zO}qk=Ze4jDUX0Hfg%FtY^L_94eD68K*WWu|e((JJeDA)cH;SyEJbHHb?cT2!ckSID zJ8v_JYfmGsbgdh`S6x?1=vFD^)zg&qPiktS6INQP>aiYbS1&YFUwe1ftGV^IPDok> zk{orE)P-sq%TrW7=_67 z^H`vB0Mc>^_9zplzYYLHR!0ORXmAQb2hmevD%vO7_;balO2cDW%52-broV(gA`+Ig|K~|E}upC+a`Y)!lW}4T5(BTzcfd6};7FG2S5;j%cAu~Re0=>ET@Vvv diff --git a/PersistenceSniper/PersistenceSniper.psm1 b/PersistenceSniper/PersistenceSniper.psm1 index 46f6bf5..a52611c 100755 --- a/PersistenceSniper/PersistenceSniper.psm1 +++ b/PersistenceSniper/PersistenceSniper.psm1 @@ -1,6 +1,6 @@ <#PSScriptInfo - .VERSION 1.15.1 + .VERSION 1.16.0 .GUID 3ce01128-01f1-4503-8f7f-2e50deb56ebc @@ -154,7 +154,9 @@ function Find-AllPersistence { 'RIDHijacking', 'SubornerAttack', 'DSRMBackdoor', - 'GhostTask' + 'GhostTask', + 'BootVerificationProgram', + 'AppInitDLLs' )] $PersistenceMethod = 'All', @@ -430,11 +432,10 @@ function Find-AllPersistence { } $contentArray = @() - foreach ($line in $item) { - while ($line.Contains(" ")) { - $line = $line -replace ' ', ' ' + foreach ($line in $item -split '\s{2,}') { + if ($line -ne '') { + $contentArray += $line } - $contentArray += $line.Split(' ') } foreach ($content in $contentArray) { @@ -1820,6 +1821,7 @@ function Find-AllPersistence { } Write-Verbose -Message '' } + function Get-DotNetStartupHooks { Write-Verbose -Message "$hostname - Getting DotNet Startup Hooks..." foreach ($hive in $systemAndUsersHives) { @@ -1848,7 +1850,7 @@ function Find-AllPersistence { } Write-Verbose -Message '' } - + function Get-SubornerAttack { $netUsers = net.exe users | Parse-NetUser $poshUsers = Get-LocalUser | Select-Object Name @@ -1860,6 +1862,7 @@ function Find-AllPersistence { } Write-Verbose -Message '' } + function Get-RidHijacking { Write-Verbose -Message "$hostname - Checking for RID Hijacking" @@ -1938,6 +1941,37 @@ function Find-AllPersistence { } Write-Verbose -Message '' } + + function Get-BootVerificationProgram { + Write-Verbose -Message "$hostname - Checking for Boot Verification Program hijacking..." + $bootVerificationProgram = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\BootVerificationProgram").ImagePath + if ($bootVerificationProgram) { + Write-Verbose -Message "$hostname - [!] Found custom Boot Verification Program at ImagePath property of the HKLM:\SYSTEM\CurrentControlSet\Control\BootVerificationProgram key!" + $PersistenceObject = New-PersistenceObject -Hostname $hostname -Technique 'Boot Verification Program Hijacking' -Classification 'Uncatalogued Technique N.19' -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\BootVerificationProgram\ImagePath' -Value $bootVerificationProgram -AccessGained 'System' -Note "The executable pointed to by the ImagePath property of the HKLM:\SYSTEM\CurrentControlSet\Control\BootVerificationProgram key is run by the Windows Service Manager at boot time in place of the legitimate Bootvrfy.exe" -Reference 'https://persistence-info.github.io/Data/bootverificationprogram.html' + $null = $persistenceObjectArray.Add($PersistenceObject) + } + Write-Verbose -Message '' + } + + function Get-AppInitDLLs { + Write-Verbose -Message "$hostname - Getting AppInit DLLs..." + $appInitDLL = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows").AppInit_DLLs + if ($appInitDLL) { + Write-Verbose -Message "$hostname - [!] AppInit_DLLs property under the HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows key is populated!" + $PersistenceObject = New-PersistenceObject -Hostname $hostname -Technique 'AppInit DLL injection' -Classification 'MITRE ATT&CK T1546.010' -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows' -Value $appInitDLL -AccessGained 'System/User' -Note "The DLLs specified in the AppInit_DLLs property of the HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows key are loaded by user32.dll whenever a new process starts." -Reference 'https://attack.mitre.org/techniques/T1546/010/' + $null = $persistenceObjectArray.Add($PersistenceObject) + } + + $appInitDLL = (Get-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows").AppInit_DLLs + if ($appInitDLL) { + Write-Verbose -Message "$hostname - [!] AppInit_DLLs property under the HKLM:\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows key is populated!" + $PersistenceObject = New-PersistenceObject -Hostname $hostname -Technique 'AppInit DLL injection' -Classification 'MITRE ATT&CK T1546.010' -Path 'HKLM:\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows' -Value $appInitDLL -AccessGained 'System/User' -Note "The DLLs specified in the AppInit_DLLs property of the HKLM:\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows key are loaded by user32.dll whenever a new process starts." -Reference 'https://attack.mitre.org/techniques/T1546/010/' + $null = $persistenceObjectArray.Add($PersistenceObject) + } + + Write-Verbose -Message '' + } + function Out-EventLog { Param ( @@ -2004,6 +2038,8 @@ function Find-AllPersistence { 'Suborner Attack' = $null 'DSRM Backdoor' = $null 'GhostTask' = $null + 'BootVerificationProgram' = $null + 'AppInitDLLs' = $null } # Collect the keys in a separate list @@ -2089,6 +2125,8 @@ function Find-AllPersistence { Get-RidHijacking Get-DSRMBackdoor Get-GhostTask + Get-BootVerificationProgram + Get-AppInitDLLs if ($IncludeHighFalsePositivesChecks.IsPresent) { Write-Verbose -Message "$hostname - You have used the -IncludeHighFalsePositivesChecks switch, this may generate a lot of false positives since it includes checks with results which are difficult to filter programmatically..." @@ -2318,6 +2356,16 @@ function Find-AllPersistence { Get-GhostTask break } + 'BootVerificationProgram' + { + Get-BootVerificationProgram + break + } + 'AppInitDLLs' + { + Get-AppInitDLLs + break + } } } @@ -2375,12 +2423,11 @@ function Find-AllPersistence { Write-Verbose -Message 'Module execution finished.' } - # SIG # Begin signature block # MIIVlQYJKoZIhvcNAQcCoIIVhjCCFYICAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR -# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU9SiTa0xD0GnMf2t+M6qW2lGJ -# H4KgghH1MIIFbzCCBFegAwIBAgIQSPyTtGBVlI02p8mKidaUFjANBgkqhkiG9w0B +# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUiPjkk6OPIYFuG1J6aiCVyWL0 +# h+egghH1MIIFbzCCBFegAwIBAgIQSPyTtGBVlI02p8mKidaUFjANBgkqhkiG9w0B # AQwFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVy # MRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEh # MB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTIxMDUyNTAwMDAw @@ -2480,17 +2527,17 @@ function Find-AllPersistence { # ZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNgIR # ANqGcyslm0jf1LAmu7gf13AwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI # oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB -# CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFK607bYv/sX0YdRQRuZR -# j+OLOdmBMA0GCSqGSIb3DQEBAQUABIICAIYW6zYeHFFW1XA66hhxQpxhdNZiczwK -# zEosiMtuOnmnwsLZ3oQcObdIQMCVXjV+HLDdDXI/L+qJJMhaF9fileo3hjGS+AWs -# aG0g5/K5d61BB6ypgHlb/dkrqzhoDbTosZDCK9WWoo37RcvZv+jNuls3IJ9r4E7+ -# 24lPxb7TROkBq/C2zkhYT2+OqVLRpKpaai8cKWvNPyJRM/rsZjbuJsD0Qkr8NbCM -# Ki718QLkGHA1dOn3tuGTY5zBCGSkeTGnqaSxK2fDa3zW/c+5ZxxmZOs4tmHrcWVV -# 0N/BP+wQ6ejKlQtZZEyPtEwguLM2EioRipW7wfzUY6T3QYZRjgJvhIRAfCVCJfPJ -# dSjzOMwDekI2hCVfg4f4wQOghtXnzcU3rWgfjfUWg+pfWSDYnEMufI7UcKmkMetz -# fHJB1bLySttljorCRb8voVFcax5EpYPyexoUYnSxkwNwlsKIW+1Vgoj93SmLfnpm -# KnfavplaC6C14cqo3E7NgVjSu1dpkLBKGZ6cEUJt1KI2ubc2ZObB3uy1/gq5JJZk -# jYHPZcGvNqLR000K+sV4T23kKOsR5LjtGzIPmsRUc/7hpKmAKnKjKptmbOGr3iX/ -# UDqG6zSaks1fUmpmLkrvsXqHZcimeetIBA8H9fnTIlY3H0iKfAV9CcIjXXDpGgWf -# ykCKkIwijJZg +# CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFPS/pEkn0cXGewvPHFBm +# 9PsnKwXDMA0GCSqGSIb3DQEBAQUABIICAFsAtmXr8hNrs+uIdkjiSaUqbRqaE8Ng +# RFTX8kSUi3f2DCEgjtBU+nS+50t5Owubdc+zkEVXzFSrJ1A3SrEOzil/yI1JzLNs +# 9UWQqbgkXTs1feb+bqeI9tvK2INDMYqqPZD1IaXmqAIgaXqprVdj2z69c1px4wYF +# wjhoyMn6qbCztumhzdsk/xbZ7HWQ1oZoI7ji9RDrJfXna6vSsCAbEmH7kLEDkbw1 +# 4RUpyHS+7wc1NO9fkeg+oEYD3mK8eWfhk7PhSlw94mI4F6L9v8UFUOEnKJWxtGh8 +# q/F19YgIBTrQQAokng8Nq+ikzNKcl4jIUDiIv229eZSNct7ia54jYwtphEmxdG8f +# OvxPlpkG8cBnpbjNXVkWDPMh8jFEDoAMctnBbDutsUmUXew9n+gRUNubk9U2GpzD +# D19KCeKaroUNp2pe8Gq9wYIrHHajiaPUedzuGXcN4sr0pWiXQynTBuIYk1yIqBfB +# BVH5tZBhvUYEAOx8f66f+L25JwEE1fyjNI9ti+YfzfrqOgS4mKzvBkRiimjGeWpL +# tYHF6kBCa021bBXwUoHgdXcpGTgAWNbIBhpg6OJ5JhKGVdgisc//Bc/PGRXMWNm4 +# 5p+G7iraTsbyo4lrHVg2hE00ynARid6MMs39PpyCqPvItCRoKu3p6ep0a6fyHIG5 +# NaCLSEJs0RYu # SIG # End signature block diff --git a/README.md b/README.md index 731132a..77ceae5 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@

-

language version shield logo number of techniques implemented workflow gallery downloads twitter twitter twitter_rick buy me a coffee

-

PersistenceSniper is a Powershell module that can be used by Blue Teams, Incident Responders and System Administrators to hunt persistences implanted in Windows machines. It is also available on Powershell Gallery and it is digitally signed with a valid code signing certificate. The tool is under active development with new releases coming out by the week, so make sure to use the up-to-date version. Official Twitter/X account @PersistSniper.

+

language version shield logo number of techniques implemented workflow gallery downloads twitter twitter twitter_rick buy me a coffee

+

PersistenceSniper is a Powershell module that can be used by Blue Teams, Incident Responders and System Administrators to hunt persistences implanted in Windows machines. It is also available on Powershell Gallery and it is digitally signed with a valid code signing certificate. The tool is under active development with new releases coming out by the week, so make sure to use the up-to-date version. Official Twitter/X account @PersistSniper.