ISSUE

CAUSE
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -version 2.
Then it repeats in an endless loop.
WORKAROUND
Since we cannot alter the internal PowerShell logic that attempts to restart the child process to overcome the failure we have to use the two scripts below to workaround the issue. The two policies below are also attached as XML for your convenience.


PowerShell -version 2.0
What is PowerShell Script Block logging?
it is available since PowerShell v5
allows you to log every command run on your host in PSH 5.x, 6.x or 7.x
events with ID 4104 are logged into the special
Microsoft-Windows-PowerShell/Operational(for Windows PowerShell) orPowerShellCore/Operational(for PowerShell Core) event logs and contain deobfuscated dataevents can be encrypted using a certificate, so you don’t have to worry about leaking sensitive data
TL;DR
CommonStuff CommonStuff
Retrieval of Script Block logging events
# for Windows PowerShell {logname = ; id = } | message# for PowerShell Core {logname = ; id = } | messageAnd the result can be like 👇

As you can see the returned result contains nothing more than invoked commands. The commands text is split into several events and contains not just the command text itself, but also some additional data that has to be cut off.
| 

Run commands are grouped by PSH console ProcessId and a lot of additional data are shown.
What event logs are used to get the context
Microsoft-Windows-PowerShell/Operational (for Windows PowerShell) and PowerShellCore/Operational (for PowerShell Core)
- contain content of the invoked commands
- contain start time of the invoked PSH session
- contain start time of the session, by who and from which host it was started
Windows PowerShell (data only for Windows PowerShell)
- contain details about how the session was invoked and by whom (is logged a few milliseconds (or seconds :D) after the 40961 event)
- contain when the session ended and can be found through (correlates with 400 event through HostId value)
What obstacles had to be solved?
There is no unique identifier that can be used to correlate all PowerShell-related events!
4104 and 40961 events contain ProcessId, but start/stop events (400) don’t
To get the corresponding start event (400), you have to find the closest one (by comparing
CreateTimeproperty)- Sometimes these are created exactly at the same time
To get stop event (403), you need
HostIdproperty which is the same as for the start event (400)
The PowerShell start event (400) is sometimes not logged at all for some reason
ProcessId is surprisingly often reused which complicates the grouping of the events from one session
How Script Block logging can be bypassed?
And start a new PowerShell console (the old one will be still logged!)
Use PowerShell 2.0 if it is enabled in the system (by default it is)
Use PowerShell Core without registering “
Windows Event Logging Manifest” during the installation a.k.a. don’t create PowerShell Core event log

Windows PowerShell(cannot be disabled)
How certificate for Protected Event Logging (PEL) can be created?
You can edit
SubjectandValidityPeriodUnitsparts as you like[Version] Signature = "$Windows NT$" [Strings] szOID_ENHANCED_KEY_USAGE = "2.5.29.37" szOID_DOCUMENT_ENCRYPTION = "1.3.6.1.4.1.311.80.1" [NewRequest] Subject = "cn=PEL@contoso.com" MachineKeySet = false KeyLength = 4096 KeySpec = AT_KEYEXCHANGE HashAlgorithm = Sha256 Exportable = true RequestType = Cert KeyUsage = "CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE" ValidityPeriod = "Years" ValidityPeriodUnits = "1000" [Extensions] %szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_DOCUMENT_ENCRYPTION%"
certreq -new PEL.inf PEL.cerA new certificate
PEL.cerwill be created in the working directory and also in your Certificate Personal storeExport the newly created certificate from your certificate store (including the private key!) as
PEL.pfx
PEL.cercan be used for events content encrypting,PEL.pfxfor decryptingOfficial tutorial for enabling PEL
Why Disable PowerShell?
Step 1: Find the PowerShell.exe file path
By default PowerShell.exe is located in this folder -> C:\Windows\System32\WindowsPowerShell\v1.0
To verify this on your computer, open PowerShell, then open task manager, go to the details tab, scroll down to powershell.exe, right click and select “open file location”.

Windows explorer will open to the folder location of powershell.exe. Make a note of this location as it will be needed in a later step.

Step 2: Create GPO to block PowerShell.exe
1. Open the Group Policy Management Console

Give the new GPO a name. I like to be descriptive with names so it’s easy to understand it.

You have now created a new GPO, the next step will be to edit the settings.
Now right-click “Software Restriction Policies” and select “New Software Restriction Policies”

Select “Additional Rules”, then right-click and select “New Path Rule”

Now click the browse button and select the powershell.exe file from the path in step 1. Most common path is -> C:\Windows\System32\WindowsPowerShell\v1.0.
Set the security level to “Disallowed” Click OK.


Allow PowerShell for Administrators
1. Create a new Active Directory Security group.

2. Modify GPO Delegation
Now go back to the GPO you created in step 1 and click on the delegation tab.

In the permissions section make sure the group is selected and it has only these permissions
- Read is set to “allow”
- Apply group policy is set to “Deny”

PowerShell script block logging must be enabled.
Overview
| Finding ID | Version | Rule ID | IA Controls | Severity |
|---|---|---|---|---|
| V-224957 | WN16-CC-000490 | SV-224957r569186_rule | Medium |
| Description |
|---|
| Maintaining an audit trail of system activity logs can help identify configuration errors, troubleshoot service disruptions, and analyze compromises that have occurred, as well as detect attacks. Audit logs are necessary to provide a trail of evidence in case the system or network is compromised. Collecting this data is essential for analyzing the security of information assets and detecting signs of suspicious and unexpected behavior. Enabling PowerShell script block logging will record detailed information from the processing of PowerShell commands and scripts. This can provide additional detail when malware has run on a system. |
| STIG | Date |
|---|---|
| Microsoft Windows Server 2016 Security Technical Implementation Guide | 2023-08-22 |
Details
| Check Text ( C-26648r465773_chk ) |
|---|
| If the following registry value does not exist or is not configured as specified, this is a finding. Value Type: REG_DWORD |
| Fix Text (F-26636r465774_fix) |
|---|
| Configure the policy value for Computer Configuration >> Administrative Templates >> Windows Components >> Windows PowerShell >> “Turn on PowerShell Script Block Logging” to “Enabled”. |
2. **Create a New Policy:**
Navigate to the “Policies” section and create a new policy or modify an existing one.
a. In the policy settings, navigate to the “Application Control” section.
b. Look for options related to executable control or application management.
4. **Apply the Policy:**
Once you’ve configured the policy to disable CMD and PowerShell, apply the policy to the relevant group of managed computers.
5. **Deploy the Policy:**
The policy changes will need to be deployed to the managed computers. Depending on your Kaspersky Security Center configuration, this might happen automatically or require manual synchronization.
Please note that the steps provided are based on general principles and may vary slightly based on the specific interface and options available in Kaspersky Security Center version 14. Always refer to the official documentation or consult with your IT team for accurate instructions tailored to your setup.
Remember that disabling CMD and PowerShell can impact the functionality of your systems and applications. It’s important to thoroughly test this policy in a controlled environment before applying it to production systems. Additionally, ensure you have a reliable backup and recovery plan in place in case any issues arise.




