How to save PowerShell execution log. What you should do at first time.

Introduction

This time, I will explain the method of logging the command executed by PowerShell.
Most of recent malware is targeted for Windows.
Furthermore, the number of malware using PowerShell is also increasing.
PowerShell malware sharply increased. According to Symantec’s analysis, 95.4% turned out to be a malicious script.
Http://d.hatena.ne.jp/ripjyr/20161210/1481338727
In addition, there are an increasing number of cases using Windows servers even in companies.
Up to now, logging has been done as usual, such as logging commands executed using syslog on Linux and centralized management.
However, currently it is not possible to log on mainstream PowerShell 4.0.
Therefore, malware may be targeting Powershell which does not have logs.
Main logging impossible Old version PowerShell OS

・Windows Server 2012 R2
 ・Windows Server 2012
 ・Windows 2008 R2 SP1
 ・Windows 8.1
 ・Windows 7 SP1
 ・Windows 10 Version 1511以前

For detailed matrix of each version, please refer to the following.
 https://msdn.microsoft.com/ja-jp/powershell/wmf/readme

The function of logging is implemented from PowerShell 5.0 released on February 24, 2016.
Therefore, we will explain the method of logging with reference to the latest version of PowerShell 5.1.
Updates are required for older versions.

Postscript: PowerShell 4.0 can extend the logging function by applying the following patch(by @stknohg)
 8.1/2012 R2 → KB3000850
 2012 → KB3119938
 7/2008 R2 SP1 → KB3109118

Log type

In PowerShell 5.1, there are three kinds of logs that can be acquired.

· Module log
· Logging of PowerShell script blocks
· PowerShell transcription

We will explain the acquisition method of each log and the contents of the log.

Module log

When setting acquisition of module log, it is necessary to set group policy.
Open Group Policy User Configuration Administrative Templates Windows PowerShell.

Open “Enable module log” and change it to “Enable”.

It is stated that LogPipelineExecutionDetails will be changed in the explanation of the policy.

When this policy setting is enabled, the pipeline execution event of the specified module member is displayed in the Event Viewer
It is recorded in the Windows PowerShell log. To enable this policy setting for a module,
It has the same meaning as setting the LogPipelineExecutionDetails property of that module to True.

Click the module name in the left pane [Display] and enter the following.

Microsoft.PowerShell.*
 Microsoft.WSMan.Management

This completes the setting.
Execute gpupdate at the command prompt etc. to reflect the policy.

Execute -Module Azure with Get-Command as an argument and display Azure’s command as confirmation.

PS C:\Users\kudo> Get-Command -Module Azure

CommandType Name Version Source
----------- ---- ------- ------
Alias Add-WAPackEnvironment 2.0.1 Azure
Alias Confirm-SSLegacyVolumeContainerStatus 2.0.1 Azure
Alias Disable-WAPackWebsiteApplicationDiagnostic 2.0.1 Azure
Alias Enable-WAPackWebsiteApplicationDiagnositc 2.0.1 Azure
Alias Get-SSAccessControlRecord 2.0.1 Azure
Alias Get-SSDevice 2.0.1 Azure
Alias Get-SSDeviceBackup 2.0.1 Azure
Alias Get-SSDeviceBackupPolicy 2.0.1 Azure
Alias Get-SSDeviceConnectedInitiator 2.0.1 Azure
Alias Get-SSDeviceVolume 2.0.1 Azure
Alias Get-SSDeviceVolumeContainer 2.0.1 Azure
Alias Get-SSFailoverVolumeContainers 2.0.1 Azure
Alias Get-SSJob 2.0.1 Azure
Alias Get-SSLegacyVolumeContainerConfirmStatus 2.0.1 Azure
Alias Get-SSLegacyVolumeContainerMigrationPlan 2.0.1 Azure
Alias Get-SSLegacyVolumeContainerStatus 2.0.1 Azure
Alias Get-SSResource 2.0.1 Azure
Alias Get-SSResourceContext 2.0.1 Azure

Check the recorded log.
Open the event log.

The log is logged in [Applications and service logs> Microsoft> Windows> PowerShell> Operational].

It is stated that the detail of the log is that Get — Command is executed and the value Azure is entered in the parameter Module and executed.

CommandInvocation(Get-Command): "Get-Command"
パラメーター バインド(Get-Command): 名前="Module"; 値="Azure"


コンテキスト:
重要度 = Informational
ホスト名 = ConsoleHost
ホストのバージョン = 5.1.14393.693
ホスト ID = 8ee01dcc-0816-41d5-9a4e-a11740c598de
ホスト アプリケーション = C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
エンジンのバージョン = 5.1.14393.693
実行空間 ID = ba2f25ff-3cc4-4e20-9eda-e5493d041643
パイプライン ID = 25
コマンド名 = Get-Command
コマンドの種類 = Cmdlet
スクリプト名 =
コマンド パス =
シーケンス番号 = 64
ユーザー = xxxxx
接続されたユーザー =
シェル ID = Microsoft.PowerShell


ユーザー データ:

Also, when executing [Get-ChildItem] etc., it will be listed in the log as Out-Default value.

CommandInvocation(Out-Default): "Out-Default"
パラメーター バインド(Out-Default): 名前="InputObject"; 値=".azurefunctions"
パラメーター バインド(Out-Default): 名前="InputObject"; 値=".DataGrip2016.2"
パラメーター バインド(Out-Default): 名前="InputObject"; 値=".dnx"
パラメーター バインド(Out-Default): 名前="InputObject"; 値=".LSC"
パラメーター バインド(Out-Default): 名前="InputObject"; 値=".nuget"
パラメーター バインド(Out-Default): 名前="InputObject"; 値=".QtWebEngineProcess"
パラメーター バインド(Out-Default): 名前="InputObject"; 値=".vscode"
パラメーター バインド(Out-Default): 名前="InputObject"; 値="Contacts"
パラメーター バインド(Out-Default): 名前="InputObject"; 値="Desktop"
パラメーター バインド(Out-Default): 名前="InputObject"; 値="Documents"
~~~~~~

It is possible to acquire in the event log format such as the command executed as above and some output.
At the very least, I recommend you to enable this policy.

Logging of PowerShell script blocks

Open Group Policy [User Configuration> Administrative Templates> Windows PowerShell] as well as module logging.
Open “Enable logging of PowerShell script block” and change “Enable”.

You can use this policy setting to record all PowerShell script inputs in the Microsoft - Windows - PowerShell / Operation event log.
When this policy setting is enabled, Windows PowerShell command processing, script block, function, and script are recorded.
Everything that is called interactively or automatically invoked is recorded.

When [Get-Command-Module Azure] is executed, the command executed, the script used when the command was executed, etc. are all described.
Check the event log.

Command record

Scriptblock テキストを作成しています (1 個中 1 個目):
Get-Command -Module Azure

ScriptBlock ID: c96cd900-dc7a-4433-ada7-18992d64c57e
パス:

In addition, the module of the command is described (part).

Scriptblock テキストを作成しています (1 個中 1 個目):
#
# Module manifest for module 'Azure'
#
# Generated by: Microsoft Corporation
#
# Generated on: 5/23/2012
#

@{

# Version number of this module.
ModuleVersion = '2.0.1'

# ID used to uniquely identify this module
GUID = 'D48CF693-4125-4D2D-8790-1514F44CE325'

# Author of this module
Author = 'Microsoft Corporation'

# Company or vendor of this module
CompanyName = 'Microsoft Corporation'

# Copyright statement for this module
Copyright = 'Microsoft Corporation. All rights reserved.'

# Description of the functionality provided by this module
Description = 'Microsoft Azure PowerShell - Service Management'

# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '3.0'

# Name of the Windows PowerShell host required by this module
PowerShellHostName = ''

# Minimum version of the Windows PowerShell host required by this module
PowerShellHostVersion = ''

# Minimum version of the .NET Framework required by this module
DotNetFrameworkVersion = '4.0'

# Minimum version of the common language runtime (CLR) required by this module
CLRVersion='4.0'

# Processor architecture (None, X86, Amd64, IA64) required by this module
ProcessorArchitecture = 'None'

# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @( @{ ModuleName = 'Azure.Storage'; ModuleVersion = '2.0.1'})

# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = @()

# Script files (.ps1) that are run in the caller's environment prior to importing this module
ScriptsToProcess = @()

# Type files (.ps1xml) to be loaded when importing this module
TypesToProcess = @(
'.\Services\Microsoft.WindowsAzure.Commands.Websites.Types.ps1xml',
'.\Sql\Microsoft.WindowsAzure.Commands.SqlDatabase.Types.ps1xml',
'.\StorSimple\Microsoft.WindowsAzure.Commands.StorSimple.Types.ps1xml'
)


# Format files (.ps1xml) to be loaded when importing this module
FormatsToProcess = @(
'.\Services\Microsoft.WindowsAzure.Commands.Websites.format.ps1xml',
'.\Services\Microsoft.WindowsAzure.Commands.CloudService.format.ps1xml',
'.\Services\Microsoft.WindowsAzure.Commands.ServiceBus.format.ps1xml',
'.\Services\Microsoft.WindowsAzure.Commands.Store.format.ps1xml',
'.\Services\Microsoft.WindowsAzure.Commands.Scheduler.format.ps1xml',
'.\Compute\Microsoft.WindowsAzure.Commands.ServiceManagement.format.ps1xml',
'.\Services\Microsoft.WindowsAzure.Commands.Profile.format.ps1xml',
'.\Networking\Microsoft.WindowsAzure.Commands.ServiceManagement.Network.format.ps1xml',
'.\StorSimple\Microsoft.WindowsAzure.Commands.StorSimple.format.ps1xml'
)

# Modules to import as nested modules of the module specified in ModuleToProcess
NestedModules = '.\Automation\Microsoft.Azure.Commands.Automation.dll',
'.\Compute\Microsoft.WindowsAzure.Commands.ServiceManagement.dll',
'.\HDInsight\Microsoft.WindowsAzure.Commands.HDInsight.dll',
'.\ManagedCache\Microsoft.Azure.Commands.ManagedCache.dll',
'.\Networking\Microsoft.WindowsAzure.Commands.ServiceManagement.Network.dll',
'.\RecoveryServices\Microsoft.Azure.Commands.RecoveryServicesRdfe.dll',
'.\RemoteApp\Microsoft.WindowsAzure.Commands.RemoteApp.dll',
'.\Services\Microsoft.WindowsAzure.Commands.dll',
'.\Services\Microsoft.WindowsAzure.Commands.Profile.dll',
'.\Sql\Microsoft.WindowsAzure.Commands.SqlDatabase.dll',
'.\StorSimple\Microsoft.WindowsAzure.Commands.StorSimple.dll',
'.\TrafficManager\Microsoft.WindowsAzure.Commands.TrafficManager.dll'

# Functions to export from this module
FunctionsToExport = '*'

# Cmdlets to export from this module
CmdletsToExport = '*'

# Variables to export from this module
VariablesToExport = '*'

# Aliases to export from this module
AliasesToExport = @(
'Add-WAPackEnvironment',
'Disable-WAPackWebsiteApplicationDiagnostic'
'Enable-WAPackWebsiteApplicationDiagnositc'
'Get-WAPackEnvironment',
'Get-WAPackPublishSettingsFile',
'Get-WAPackSBLocation',
'Get-WAPackSBNamespace',
'Get-WAPackSubscription',
'Get-WAPackWebsite',
'Get-WAPackWebsiteDeployment',
'Get-WAPackWebsiteLocation',
'Get-WAPackWebsiteLog',
'Import-WAPackPublishSettingsFile',
'New-WAPackSBNamespace',
'New-WAPackWebsite',
'Remove-WAPackEnvironment',
'Remove-WAPackSBNamespace',
'Remove-WAPackSubscription',
'Remove-WAPackWebsite',
'Restart-WAPackWebsite',
'Restore-WAPackWebsiteDeployment',
'Save-WAPackWebsiteLog',
~~~~~~~

Logs can be retrieved as described above.
However, it is not possible to record the execution result (standard output etc.).

PowerShell transcription

Up to now, the function of Transcript was available in PowerShell 4.0.

Start-Transcript

The execution log can be output with the above command.
However, there is no malware that executes the command carefully (surely).

So, with PowerShell 5.0 and later, it will solve it when you set it with Group Policy.
Open Group Policy User Configuration Administrative Templates Windows PowerShell.
Open “Enable PowerShell Transcription” and change “Enable”.Also, input the output destination.
Although it is also described in the commentary, it will be output to the text, not the event log.

You can use this policy setting to capture the input and output of Windows PowerShell commands as text-based transcripts.
If you enable this policy setting, you can use Windows PowerShell, Windows PowerShell ISE, and any other Windows PowerShell engine
Creating transcripts is enabled for the application. By default, transcript output appears in each user's My Documents directory
It is recorded. The name of the file to be recorded will be in the form of 'PowerShell_transcript' with the computer name and start date and time added. This policy
Enabling is the same as calling the Start-Transcript cmdlet in each Windows PowerShell session.

The output log is saved in the format “PowerShell_transcript. Machine name.random alphanumeric.20170124132441”.

In the log, the contents executed are described as they are.

**********************
Windows PowerShell トランスクリプト開始
開始時刻: 20170124160909
ユーザー名: xxxxxxx
RunAs ユーザー: xxxxxxxxx
コンピューター: xxxxxxxxxx (Microsoft Windows NT 10.0.14393.0)
ホスト アプリケーション: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
プロセス ID: 2596
PSVersion: 5.1.14393.693
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.14393.693
BuildVersion: 10.0.14393.693
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
PS C:\Users\kudo> Get-Command -Module Azure

CommandType Name Version Source
----------- ---- ------- ------
Alias Add-WAPackEnvironment 2.0.1 Azure
Alias Confirm-SSLegacyVolumeContainerStatus 2.0.1 Azure
Alias Disable-WAPackWebsiteApplicationDiagnostic 2.0.1 Azure
Alias Enable-WAPackWebsiteApplicationDiagnositc 2.0.1 Azure
Alias Get-SSAccessControlRecord 2.0.1 Azure
Alias Get-SSDevice 2.0.1 Azure
Alias Get-SSDeviceBackup 2.0.1 Azure
Alias Get-SSDeviceBackupPolicy 2.0.1 Azure
Alias Get-SSDeviceConnectedInitiator 2.0.1 Azure
~~~~~~

As described above, it is output as text.
However, files are divided for each process (?).
Because it is text, I think whether it is easy to process and manage all at once.

Summary

I explained three points about PowerShell logging. I think that it is best to enable all three and obtain logs.
By acquiring the “module log” at the very least, you should acquire the audit log and prepare for in case of emergency. Everyone is doing it on Linux, so let’s do it on Windows.

Also, I think whether log management will be easier by collecting event logs collectively in Operations Management Suite and others. Since it can correspond to Linux, since it can collectively manage regardless of OS, how about using it?


Original Content (Japanese) : http://level69.net/archives/24861