Skip to content

AMSI logging implemented on Linux #21492

Closed

Description

@rhubarb-geek-nz

Prerequisites

Steps to reproduce

The AMSI logging is still being performed on Linux even though there are no AMSI modules installed.

As demonstrated in #21473 this can lead to excessive heap usage

Expected behavior

#!/usr/bin/env pwsh
$env:__PSDumpAMSILogContent='1'
$bytes = new-object byte[] -ArgumentList @(,200554320)
$random = new-object Random
$random.NextBytes($bytes)

Should not print anything

Actual behavior

#!/usr/bin/env pwsh
$env:__PSDumpAMSILogContent='1'
$bytes = new-object byte[] -ArgumentList @(,200554320)
$random = new-object Random
$random.NextBytes($bytes)

Prints the following log

=== Amsi notification report content ===
<System.Random>.NextBytes(<System.Byte[]>)
=== Amsi notification report success: False ===

Error details

No actual error other than incorrect behaviour

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.2
PSEdition                      Core
GitCommitId                    7.4.2
OS                             Debian GNU/Linux 11 (bullseye)
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

Activity

  1. iSazonov commented on Apr 18, 2024

    @iSazonov
    Collaborator

    AMSI is called in internal static bool ReportContent() and only on Windows.
    What you see is a debug code. It's not worth the effort to mask it on Unix. (Maybe it can even be useful there for MSFT developers who approved the code.)

  2. mklement0 commented on Apr 18, 2024

    @mklement0
    Contributor

    Ilya (@iSazonov), I agree with rhubarb-geek-nz that there's no good reason to saddle user on Unix-like platform not only with unnecessary runtime overhead, but - as noted - in the case of passing large strings also with significant memory overhead.

    It would be simple to execute the code in question only if env var. DumpLogAMSIContent is set to 1 on Unix, which would preserve the ability to debug on demand, while not burdening regular method calls:

    That is, the following code:

    // Expression block runs two expressions in order:
    // - Log method invocation to AMSI Notifications (can throw PSSecurityException)
    // - Invoke method
    string targetName = methodInfo.ReflectedType?.FullName ?? string.Empty;
    expr = Expression.Block(
    Expression.Call(
    CachedReflectionInfo.MemberInvocationLoggingOps_LogMemberInvocation,
    Expression.Constant(targetName),
    Expression.Constant(name),
    Expression.NewArrayInit(
    typeof(object),
    args.Select(static e => e.Expression.Cast(typeof(object))))),
    expr);

    could be guarded by a preceding #if UNIX directive that sets a Boolean to determine whether the code should be invoked, along the lines of:

    #if UNIX
      bool callAMSI = Environment.GetEnvironmentVariable("__PSDumpAMSILogContent")?.Trim() == "1";
    #else
      bool callAMSI = true;
    #endif
    if (callAMSI)
    {
       // ... code above
    }

    Note: The above illustrates the concept, but the value of callAMSI can and should be determined only once per session, during session initialization, and then cached.

  3. iSazonov commented on Apr 18, 2024

    @iSazonov
    Collaborator

    For performance there is another issue. You can ask MSFT team today on monthly community call if you want to get answer quickly about #21473 performance.

  4. mklement0 commented on Apr 18, 2024

    @mklement0
    Contributor

    Ilya (@iSazonov):

    • The memory usage problem and the - much worse - runtime penalty discussed in [System.Convert]::FromBase64String causes memory leak with large strings #21473 is in the context of Windows, where actual AMSI API calls are currently performed unconditionally.

      • As long as an AMSI call must be made for every .NET method call made from PowerShell code, these memory + performance issues are unavoidable, although the only really pathological cases are .NET method calls involving arguments that are very large strings.

      • Possibly providing an opt-out of these AMSI calls on Windows - something that obviously has security implications - is the subject of yet another issue, How can I disable PSAMSIMethodInvocationLogging #21491

    • The issue at hand is purely about Unix-like platforms, where no security considerations apply, due to the absence of an API analogous to the Windows-only AMSI, so the issue at hand can and should be decided separately.

  5. mklement0 commented on Apr 19, 2024

    @mklement0
    Contributor

    Ilya (@iSazonov), in light of the above:

    • The Resolution-Answered label is inappropriate.

    • While it is appropriate to make the security WG review this, let me summarize what I think the net effect of this proposal is:

      • It will result in no functional change, and therefore doesn't affect security.
      • It will generally improve performance of all .NET method calls on all Unix-like platforms.
  6. SteveL-MSFT commented on Apr 22, 2024

    @SteveL-MSFT
    Member

    WG reviewed this and agreed that the .NET method invocation logging for AMSI should only apply to Windows. The change should be separate and not dependent on the env var.

  7. added
    WG-ReviewedA Working Group has reviewed this and made a recommendation
    and removed
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    WG-NeedsReviewNeeds a review by the labeled Working Group
    on Apr 22, 2024
  8. jborean93 commented on Oct 16, 2024

    @jborean93
    Collaborator

    Opened #24451 which no-ops the member invocation logging for non-Windows on a release build. Keep in mind the extra overhead added by serialising the args is pretty minimal but always good to avoid it when possible.

  9. microsoft-github-policy-service commented on Dec 9, 2024

    @microsoft-github-policy-service
    Contributor

    📣 Hey rhubarb-geek-nz, how did we do? We would love to hear your feedback with the link below! 🗣️

    🔗 https://aka.ms/PSRepoFeedback

  10. iSazonov commented on Dec 10, 2024

    @iSazonov
    Collaborator

    There is a bug in #24451.

  11. jborean93 commented on Dec 15, 2024

    @jborean93
    Collaborator

    Ilya (@iSazonov) bug has been fixed with #24652

  12. microsoft-github-policy-service commented on Dec 16, 2024

    @microsoft-github-policy-service
    Contributor

    📣 Hey rhubarb-geek-nz, how did we do? We would love to hear your feedback with the link below! 🗣️

    🔗 https://aka.ms/PSRepoFeedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    In-PRIndicates that a PR is out for the issueResolution-FixedThe issue is fixed.WG-ReviewedA Working Group has reviewed this and made a recommendationWG-Securitysecurity related areas such as JEA

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions