PowerShell Event Collection

다음은 파워쉘 이벤트들을 컬렉션 할 수 있는 여러 방법에 대한 설명입니다. 이러한 이벤트들을 활성화하고 수집하는 방법으로 악성 파워쉘을 사용하는 윈도우즈 말웨어들에 대한 디텍션을 강화할 수 있습니다. 또한 이러한 텔레메트리는 머신 러닝을 위한 좋은 데이타로 활용될 수 있습니다.

PowerShell Event Collection

1. PowerShell Profile

  • PowerShell Profile
    • Customize environment and to add session-specific elements to every PowerShell session that you start

About Profiles

Events Logging

Variable Description
$LogCommandLifeCycleEvent Logs the starting and completion of commands
$LogCommandHealthEvent Logs command errors

About Eventlogs

Modules/Snap-Ins Events Logging

  • Profile $LogPipelineExecutionDetails variable
  • PowerShell 3.0 and above
    • Record execution events for the cmdlets and functions in Windows PowerShell modules and snap-ins
    • LogPipelineExecutionDetails property of modules and snap-ins to TRUE
  • PowerShell 2.0
    • Only for for snap-ins

About Eventlogs

Profile Example

  • Create %SystemRoot%\System32\WindowsPowerShell\v1.0\profile.ps1 and put the contents below
    • $LogCommandHealthEvent: Logs command errors
    • LogCommandLifecycleEvent: Logs start/completion of commands
    • LogPipelineExecutionDetails: logs cmdlets/functions events
$LogCommandHealthEvent = $true
$LogCommandLifecycleEvent = $true
$LogPipelineExecutionDetails = $true

2. Command Line Logging

  • PowerShell v2 ~

  • Audit event ID 4688: Command Line Logging

    • The pre-existing process creation
      • Audit information for command line processes


  • Computer Configuration > Policies > Windows Settings > Security Settings > Advanced Audit Configuration > Detailed Tracking
    • Audit Process Creation
  • Windows 7 and above

  • Command line process auditing

3. Microsoft-Windows-PowerShell/Operational

Provider Details

  • Get-WinEvent can be used to show provider events
    • Gets events from event logs and event tracing log files on local and remote computers.
Get-WinEvent -ListProvider Microsoft-Windows-PowerShell | Format-List -Property *

Provider Details - Output

ProviderName      : Microsoft-Windows-PowerShell
Name              : Microsoft-Windows-PowerShell
Id                : a0c1853b-5c40-4b15-8766-3cf1c58f985a
MessageFilePath   : C:\WINDOWS\system32\WindowsPowerShell\v1.0\PSEvents.dll
ResourceFilePath  : C:\WINDOWS\system32\WindowsPowerShell\v1.0\PSEvents.dll
ParameterFilePath :
HelpLink          : https://go.microsoft.com/fwlink/events.asp?CoName=Microsoft Corporation&ProdName=Microsoft®
                    Windows® Operating System&ProdVer=10.0.17763.1&FileName=PSEvents.dll&FileVer=10.0.17763.1
DisplayName       :
LogLinks          : {Microsoft-Windows-PowerShell/Operational, Microsoft-Windows-PowerShell/Analytic,
                    Microsoft-Windows-PowerShell/Debug, Microsoft-Windows-PowerShell/Admin}
Levels            : {win:Error, win:Warning, win:Informational, win:Verbose...}
Opcodes           : {win:Start, win:Stop, Open, Close...}
Keywords          : {Runspace, Pipeline, Protocol, Transport...}
Tasks             : {CreateRunspace, ExecuteCommand, Serialization, Powershell-Console-Startup...}
Events            : {4097, 4098, 4099, 4100...}

List Events

(Get-WinEvent -ListProvider Microsoft-Windows-PowerShell).Events

List Events - Formatted

(Get-WinEvent -ListProvider Microsoft-Windows-PowerShell).Events | ForEach-Object {
    [PSCustomObject]@{Id = $_.Id; Level = $_.Level.Name; Opcode = $_.Opcode.Name; Task = $_.Task.Name; Keywords = $_.Keywords.Name; Template = $_.Template; Description = $_.Description }
} | Format-List 

List Events - wevtutil

wevtutil gp Microsoft-Windows-PowerShell /ge /gm:true

{gp | get-publisher} [/ge:] [/gm:] [/f:]]

  • Displays the configuration information for the specified event publisher


Group Policy

  • Windows Components -> Administrative Templates -> Windows PowerShell
Name Matching Registry Key Registry Values
Turn on Module Logging HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging EnableModuleLogging, ModuleNames
Turn on PowerShell Script Block Logging HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging EnableScriptBlockLogging
Turn on Script Execution    
Turn on PowerShell Transcription HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription EnableTranscripting, EnableInvocationHeader, OutputDirectory
Set the default source path for Update-Help    

Log Size

  • It is recommended that you increase default log size for the “Microsoft-Windows-PowerShell%4Operational.evtx” around 1GB.


  • A unique record of every PowerShell session
    • All input and output


  • PowerShell v4 transcription is limited
    • Need to include the command in the system startup profile of every system, and also need to add significant amounts of auditing to flag attackers that attempt to disable transcription
    • Transcription was only supported in the interactive PowerShell console


  • PowerShell v5 / KB3000850
    • Start-Transcript
    • Creates a record of all or part of a Windows PowerShell session to a text file.
    • Emits structured objects when you start a transcript

Module Logging

  • PowerShell v4, v5
  • Records pipeline execution details as PowerShell executes
    • Variable initialization
    • Command invocations.

Event ID: 4103

Name Description
EventId 4103 (0x1007)
Channel Microsoft-Windows-PowerShell/Operational

Event ID: 4103 - Query

(Get-WinEvent -ListProvider Microsoft-Windows-PowerShell).Events | Where-Object {$_.Id -eq 4103} | ForEach-Object {
    [PSCustomObject]@{Id = $_.Id; Level = $_.Level.Name; Opcode = $_.Opcode.Name; Task = $_.Task.Name; Keywords = $_.Keywords.Name; Template = $_.Template; Description = $_.Description }
} | Format-List 

Event ID: 4103 - Details

Id          : 4103
Level       : win:Informational
Opcode      : Exception
Task        : win:None
Keywords    : {$null, Cmdlets}
Template    : <template xmlns="http://schemas.microsoft.com/win/2004/08/events">
                <data name="ContextInfo" inType="win:UnicodeString" outType="xs:string"/>
                <data name="UserData" inType="win:UnicodeString" outType="xs:string"/>
                <data name="Payload" inType="win:UnicodeString" outType="xs:string"/>

Description : %3


              User Data:

Script Block Logging

  • PowerShell v5 and KB 3000850
    • Script Content
    • Dynamic Code Generation: for example, the logging can dump the dynamic command used in the following ocde.
$command = “‘Hello World'”; Invoke-Expression $command

Script Block Logging

  • Records de-obfuscated code as it is executed.

Suspicious Script Logging

  • PowerShell v5
  • Automatically logs script blocks when they have content often used by malicious scripts (warning level)
    • This feature is by default ON
    • To disable:
      • “Turn on Script Block Logging” in Group Policy -> “Disabled”
      • Specify “0” for the EnableScriptBlockLogging registry key

Event ID: 4104

Name Description
EventId 4104 (0x1008)
Channel Microsoft-Windows-PowerShell/Operational
Message Creating Scriptblock text (%1 of %2): %3 ScriptBlock ID: %4

Event ID: 4104 - Query

(Get-WinEvent -ListProvider Microsoft-Windows-PowerShell).Events | Where-Object {$_.Id -eq 4104} | ForEach-Object {
    [PSCustomObject]@{Id = $_.Id; Level = $_.Level.Name; Opcode = $_.Opcode.Name; Task = $_.Task.Name; Keywords = $_.Keywords.Name; Template = $_.Template; Description = $_.Description }
} | Format-List 

Event ID: 4104 - Details

Id          : 4104
Level       : win:Verbose
Opcode      : Create
Task        : CommandStart
Keywords    : {$null, Runspace}
Template    : <template xmlns="http://schemas.microsoft.com/win/2004/08/events">
                <data name="MessageNumber" inType="win:Int32" outType="xs:int"/>
                <data name="MessageTotal" inType="win:Int32" outType="xs:int"/>
                <data name="ScriptBlockText" inType="win:UnicodeString" outType="xs:string"/>
                <data name="ScriptBlockId" inType="win:UnicodeString" outType="xs:string"/>
                <data name="Path" inType="win:UnicodeString" outType="xs:string"/>

Description : Creating Scriptblock text (%1 of %2):

              ScriptBlock ID: %4
              Path: %5

Event ID: 4104 - Querying Events using PowerShell

Get-WinEvent -FilterHashTable @{LogName='Microsoft-Windows-PowerShell/Operational';ID='4104'; } | Format-List  TimeCreated, Id, LevelDisplayName, Message | Out-Host -Paging

Creating Get-WinEvent queries with FilterHashtable

Event ID: 4104 - Querying Events using PowerShell

Get-WinEvent -FilterHashTable @{LogName='Microsoft-Windows-PowerShell/Operational';ID='4104'} | Format-List  TimeCreated, Id, LevelDisplayName, Message | Out-Host -Paging

Event ID: 4104 - Hunting Events

  • Find any events that has “Invoke-Expression” in it’s message
Get-WinEvent -FilterHashTable @{LogName='Microsoft-Windows-PowerShell/Operational';ID='4104'} | Where-Object { $_.Message -Match 'Invoke-Expression' } | Format-List  TimeCreated, Id, LevelDisplayName, Message | Out-Host -Paging

Event ID: 4104 - Querying Events Using wevutil

WevtUtil qe "Microsoft-Windows-PowerShell/Operational" /q:"*[System[(EventID=4104)]]" /c:1000 /rd:true /f:text


Parser for Windows PowerShell script block logs

Parser for Windows PowerShell script block logs

Legacy PowerShell

  • Sometimes attackers intentionally use older version of PowerShell
    • Removing legacy PowerShell installation can be a good idea
  • Control Panel -> Programs -> Programs and Features
    • Remove “Windows PowerShell” or “Windows PowerShell(TM) V2”

Uninstall Previous Versions of Windows PowerShell and Windows Remote Management

PowerShell Remoting

  • Windows Remote Management (WinRM)
    • Logs PowerShell remoting connections
      • Source (inbound connections)/destination (outbound connections)
      • Username


DarunGrim Solutions

  • 다른 그림에서는 “PowerShell” 공격등을 비롯한 네트워크, 엔드포인트에 대한 방어 전략과 제품 선정에 대한 컨설팅 서비스를 제공할 예정입니다. 관심 있으신 분은 jeongoh@darungrim.com으로 문의 주시면 됩니다.

  • “PowerShell” 공격 기법에 대해서 실습을 통해서 학습하고 분석하는 내용은 Advanced Windows Malware Analysis 코스를 통해서 수강하실 수 있습니다.