如何使用應用程控來保護 PowerShell

本文說明如何設定 商務應用程式控制 原則。 您可以設定原則來執行或稽核其規則。 在稽核模式中,PowerShell 行為不會變更,但會將事件標識碼 16387 訊息記錄到 PowerShellCore/Analytic 事件記錄檔。 在強制模式中,PowerShell 會套用原則的限制。

您使用的假設情境是一台測試用的電腦,這樣您便可以在整台電腦的應用程式控制政策下測試 PowerShell 的行為,然後再將該政策部署在您的環境中。

應用程式控制政策

App Control 政策以 XML 檔案描述,包含政策選項、允許的檔案,以及政策認可的簽署憑證等資訊。 套用原則時,只允許已核准的檔案載入和執行。 根據原則選項,PowerShell 會封鎖未核准的腳本檔案執行或以 ConstrainedLanguage 模式執行。

您可以使用 ConfigCI 模組來建立及操作應用程控原則,此模組適用於所有支援的 Windows 版本。 你可以在 Windows PowerShell 5.1 或 PowerShell 7 中,透過 Windows 相容性層使用這個 Windows PowerShell 模組。 在 Windows PowerShell 中使用此課程模組會更容易。 您所建立的原則可以套用至任何版本的 PowerShell。

建立應用程控原則的步驟

若要進行測試,您只需要建立默認原則和自我簽署的程式代碼簽署憑證。

  1. 建立默認原則

    New-CIPolicy -Level PcaCertificate -FilePath .\SystemCIPolicy.xml -UserPEs
    

    此命令會建立稱為 SystemCIPolicy.xml 的默認原則檔案,允許所有Microsoft程式代碼簽署的檔案執行。

    注意

    執行此命令最多可能需要兩個小時,因為它必須掃描整個測試計算機。

  2. 在默認原則中停用稽核模式

    新的政策一律會在Audit模式下建立。 若要測試原則強制執行,您必須在套用原則時停用稽核模式。 使用SystemCIPolicy.xml或 Visual Studio Code (VS Code) 等文字編輯器編輯檔案。 將選項批註化 Audit mode 。

    <!--
    <Rule>
      <Option>Enabled:Audit Mode</Option>
    </Rule>
    -->
    
  3. 建立自我簽署的程式代碼簽署憑證

    您需要程式代碼簽署憑證,才能簽署您想要在測試計算機上執行的任何測試二進位檔或腳本檔案。 New-SelfSignedCertificate由 PKI 模組提供 。 為了獲得最佳結果,您應該在 Windows PowerShell 5.1 中執行此命令。

    $newSelfSignedCertificateSplat = @{
        DnsName = $Env:COMPUTERNAME
        CertStoreLocation = "Cert:\CurrentUser\My\"
        Type = 'CodeSigningCert'
    }
    $cert = New-SelfSignedCertificate @newSelfSignedCertificateSplat
    Export-Certificate -Cert $cert -FilePath C:\certs\signing.cer
    Import-Certificate -FilePath C:\certs\signing.cer -CertStoreLocation "Cert:\CurrentUser\Root\"
    $cert = Get-ChildItem Cert:\CurrentUser\My\ -CodeSigningCert
    
    dir C:\bin\PowerShell\pwsh.exe | Set-AuthenticodeSignature -Certificate $cert
    
  4. 將程式代碼簽署憑證新增至原則

    使用下列命令,將新的程式代碼簽署憑證新增至原則。

    Add-SignerRule -FilePath .\SystemCIPolicy.xml -CertificatePath C:\certs\signing.cer -User
    
  5. 將 XML 原則檔案轉換為原則強制執行二進位檔

    最後,您必須將 XML 檔案轉換成應用程控用來套用原則的二進位檔。

    ConvertFrom-CIPolicy -XmlFilePath .\SystemCIPolicy.xml -BinaryFilePath .\SIPolicy.p7b
    
  6. 套用應用程控原則

    若要將原則套用至您的測試電腦,請將檔案複製到SIPolicy.p7b所需的系統位置 C:\Windows\System32\CodeIntegrity

    注意

    你必須將一些政策定義複製到子資料夾,例如 C:\Windows\System32\CodeIntegrity\CiPolicies。 欲了解更多資訊,請參閱[App Control Admin Tips and Known Issues][01]。

  7. 停用應用程式控制政策

    若要停用原則,請重新命名 SIPolicy.p7b 檔案。 如果您需要進行更多測試,可以變更名稱回來以重新啟用該原則。

    Rename-Item -Path .\SIPolicy.p7b -NewName .\SIPolicy.p7b.off
    

使用應用程控原則稽核進行測試

PowerShell 7.4 新增了新功能,以支援稽核模式中的應用程控原則。 在審核模式中,PowerShell 會以 ConstrainedLanguage 模式執行不受信任的腳本,不會發生錯誤,而是將訊息記錄到事件記錄檔。 記錄訊息描述如果原則處於 強制 模式,將會套用哪些限制。

檢視稽核事件

PowerShell 會將稽核事件記錄到 PowerShellCore/Analytic 事件記錄檔。 預設不會啟用日誌記錄檔。 若要啟用記錄檔,請開啟 Windows 事件檢視器,以滑鼠右鍵按兩下 PowerShellCore/Analytic 記錄,然後選取 [啟用記錄]。

或者,您可以在高階 PowerShell 工作階段中執行下列命令。

wevtutil.exe sl PowerShellCore/Analytic /enabled:true /quiet

您可以在 Windows 事件檢視器 中檢視事件,或使用 Get-WinEvent Cmdlet 來擷取事件。

Get-WinEvent -LogName PowerShellCore/Analytic -Oldest |
    Where-Object Id -EQ 16387 | Format-List
TimeCreated  : 4/19/2023 10:11:07 AM
ProviderName : PowerShellCore
Id           : 16387
Message      : App Control Audit.

    Title: Method or Property Invocation
    Message: Method or Property 'WriteLine' on type 'System.Console' invocation will not
        be allowed in ConstrainedLanguage mode.
        At C:\scripts\Test1.ps1:3 char:1
        + [System.Console]::WriteLine("pwnd!")
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    FullyQualifiedId: MethodOrPropertyInvocationNotAllowed

事件訊息包含套用限制的腳本位置。 此資訊可協助您了解變更腳本的位置,使其可在應用程控原則下執行。

重要

在你檢視稽核事件後,應該關閉分析日誌。 分析記錄會快速成長,並耗用大量的磁碟空間。

在PowerShell調試程式中檢視稽核事件

當您將互動 PowerShell 會話的 $DebugPreference 變數設置為 Break 時,PowerShell 會在腳本中稽核事件發生的目前位置進入命令列腳本除錯工具。 斷點可讓您對程式代碼進行偵錯,並即時檢查腳本的目前狀態。

PowerShell 的額外設定

App Control 支援 PowerShell 的額外設定。

  • BlockScriptOnPolicyFailure此設定會阻止執行未符合 App Control 政策要求的腳本。 啟用後,App Control 會阻擋任何政策未明確允許的腳本,而不是以 ConstrainedLanguage 模式執行。

    注意

    此設定由 App Control 強制執行,適用於所有版本的 PowerShell(powershell.exe 和 pwsh.exe)。

  • FileOnlyEntry:此設定可防止 PowerShell 使用不會導致執行指定檔案的引數來執行。 啟用後,App Control 會封鎖下列情況中的 PowerShell 命令執行:透過管線傳遞的命令、傳遞給 -Command 或 -EncodedCommand 參數的命令,以及允許直接執行命令的互動式工作階段。 啟用後,PowerShell 只會執行包含參數 -File 的腳本。

    被封鎖的執行範例:

    pwsh
    pwsh -NoExit -File ./file.ps1
    pwsh -Command Get-ChildItem
    "Get-ChildItem" | pwsh -File -
    pwsh -EncodedCommand <base64-string>
    

    允許的執行範例:

    pwsh -File ./file.ps1
    pwsh -NoProfile -NonInteractive -File ./file.ps1 arg1 arg2
    

    注意

    此設定僅適用於 PowerShell 7.6.6 及更新版本。 如果你在早期版本設定了這個設定, AppSetting 會被靜默忽略。

要使用這些設定,您必須將它們加入 App Control 政策的 XML 檔案(SystemCIPolicy.xml)。 在文字編輯器中開啟 XML 檔案,並新增該政策的相關 <AppSettings> 章節。 以下範例展示了啟用兩種設定後的 <AppSettings> XML。

<?xml version="1.0" encoding="utf-8"?>
<SiPolicy xmlns="urn:schemas-microsoft-com:sipolicy">

    <!-- Existing policy content -->

    <AppSettings>
        <AppSetting
            AppManifest="Powershell"
            Name="BlockScriptOnPolicyFailure"
            Value="true" />

        <AppSetting
            AppManifest="Powershell"
            Name="FileOnlyEntry"
            Value="true" />
    </AppSettings>

</SiPolicy>

進一步閱讀