PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
44.76k stars 7.24k forks source link

AMSI Logging should be optional when using PowerShell SDK in own project #24357

Open rhubarb-geek-nz opened 1 week ago

rhubarb-geek-nz commented 1 week ago

Summary of the new feature / enhancement

As a developer of an application I am responsible for its behaviour. When using PowerShell SDK there is no means of preventing the AMSI logging.

SignatureService.ps1

As a developer I do not want the AMSI logging behaviour as implemented. My web service is implemented in a PowerShell file, the logging is reporting usages that are already in that file. There are no "non-file-based scripts" being executed. The application does not execute any scripts passed to it. The are no "fileless threats".

Example logging

=== Amsi notification report content ===
<System.Management.Automation.SignatureStatus>.ToString()
=== Amsi notification report success: True ===

=== Amsi notification report content ===
<System.Security.Cryptography.PemEncoding>.Write(<CERTIFICATE>, <System.Byte[]>)
=== Amsi notification report success: True ===

=== Amsi notification report content ===
<System.Security.Cryptography.PemEncoding>.Write(<CERTIFICATE>, <System.Byte[]>)
=== Amsi notification report success: True ===

=== Amsi notification report content ===
<Microsoft.Extensions.Logging.LoggerExtensions>.LogInformation(<Microsoft.Extensions.Logging.Logger`1[[RhubarbGeekNz.AspNetForPowerShell.NewRequestDelegate, RhubarbGeekNz.AspNetForPowerShell.PSCmdlet, Version=7.4.2.0, Culture=neutral, PublicKeyToken=null]]>, <Sign "test.ps1" with "601A8B683F791E51F647D34AD102C38DA4DDB65F">, <null>)
=== Amsi notification report success: True ===
info: RhubarbGeekNz.AspNetForPowerShell.NewRequestDelegate[0]
      Sign "test.ps1" with "601A8B683F791E51F647D34AD102C38DA4DDB65F"

All of these method invocation are already in the script file.

Proposed technical implementation details (optional)

  1. Provide ability to disable/optout of AMSI logging when using SDK
  2. Do not log traces to calls that are being invoked from a known script file. ( they are not fileless threats)
R-Adrian commented 1 week ago

as a side note to AMSI... can you please check if your PowerShell is also sending telemetry data? (and if so, did you check what telemetry it sends?)

This is a concern especially if it was upgraded with WinGet from past versions, because (silent) upgrades will wipe the telemetry optout environment variable and thus will forcefully enable telemetry.

more details on issue https://github.com/PowerShell/PowerShell/issues/21467 and https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_telemetry

about_Telemetry - PowerShell
Describes the telemetry collected in PowerShell and how to opt-out.
rhubarb-geek-nz commented 1 week ago
POWERSHELL_TELEMETRY_OPTOUT=true
POWERSHELL_UPDATECHECK=Off

I don't use WinGet, I run PowerShell 7.2.23 on Windows out of choice.

It is not clear if the telemetry only applies to pwsh or also to the PowerShell SDK.

It also occurred to me that if a string was converted to a script with ScriptBlock.Create then that is where the AMSI scanning should occur. At that point the script should be just as validated as any file based script.

If you follow that argument then there would be no need for AMSI logging of method invocation from either scripts from files or scripts from strings.

Then you end up with the question of when would you ever need to use it?

SteveL-MSFT commented 6 hours ago

@rhubarb-geek-nz the telemetry check is in SMA.dll so would apply to both. As for this issue, if AMSI logging is optional with PS SDK apps, then wouldn't that be a way for attackers to workaround AMSI?

rhubarb-geek-nz commented 5 hours ago

@rhubarb-geek-nz the telemetry check is in SMA.dll so would apply to both. As for this issue, if AMSI logging is optional with PS SDK apps, then wouldn't that be a way for attackers to workaround AMSI?

As I have explained in detail, you can already do that with reflection.

The specific logging I am referring to is the logging of the method invocation which means you must already be running a validated PowerShell script. So it is just security theatre.

The AMSI logging that makes sense is when you go from string to PowerShell script, eg ScriptBlock.Create(). The targeting of method invocation is pointless.

Are you running every string passed to Invoke-Expression through AMSI?