Suporte de extensão para o gerenciamento da infraestrutura imposta pelo WDAC (Controle de Aplicativos do Windows Defender)
O Windows Admin Center dá suporte ao gerenciamento da infraestrutura imposta pelo WDAC (Controle de Aplicativos do Windows Defender) no nível da plataforma. Saiba mais sobre como gerenciar a infraestrutura imposta pelo WDAC no Windows Admin Center.
O suporte para esse gerenciamento no nível da plataforma não significa que as extensões criadas para o Windows Admin Center também dão suporte ao gerenciamento da infraestrutura imposta pelo WDAC por padrão. Este guia descreve os requisitos de uma extensão para dar suporte ao gerenciamento da infraestrutura imposta pelo WDAC.
Requisitos de estrutura de extensão
Para gerenciar a infraestrutura imposta pelo WDAC, o Windows Admin Center deve ingerir e executar scripts do PowerShell de uma forma específica para aderir às práticas recomendadas de segurança. Para garantir que os scripts da extensão sejam executados corretamente, verifique se a extensão está em conformidade com os requisitos a seguir.
Todos os scripts do PowerShell devem ser armazenados em um arquivo
Historicamente, os desenvolvedores de extensões WAC podem ter optado por incluir código personalizado do PowerShell como uma cadeia de caracteres em seu arquivo manifest.json de extensão. Por exemplo, pode-se optar por definir as condições para a visibilidade de uma extensão de ferramenta fornecendo um script do PowerShell na propriedade "script". Para que os scripts do PowerShell sejam compatíveis com o WDAC, eles devem ser assinados. As cadeias de caracteres não podem ser assinadas.
Para garantir que esse requisito seja atendido, siga estas etapas:
- Identifique todos os scripts do PowerShell no arquivo manifest.json.
- Depois de definir qualquer conteúdo de script no arquivo manifest.json, remova o conteúdo do script e armazene-o em um arquivo .ps1 no diretório
resources/scripts
da extensão. O código de script no manifesto de extensão agora segue as mesmas regras que outro PowerShell do Windows Admin Center. - Atualize a propriedade de condições no manifesto de extensão para o seguinte formato:
O nome do módulo do PowerShell já existe no manifesto da extensão. Seu valor no manifesto e no campo do PowerShell devem corresponder."conditions": [ { "powerShell": { "command": "Script-File-Name", "module": "powerShellModuleName", "script": "Your script text goes here." } } ]
- Identifique outros locais em que os scripts do PowerShell estão sendo criados dinamicamente. Criar um script do PowerShell dinamicamente usando a concatenação de cadeia de caracteres pode permitir que um invasor injete um script arbitrário do PowerShell a ser executado. Esse método pode ser usado para ignorar limitações impostas a um usuário remoto que está usando um espaço de execução restrito. Ele também pode ser usado para obter injeção de comando padrão em qualquer aplicativo que compila scripts do PowerShell com entrada do usuário e o executa.
Exemplo de bloco de script criado com concatenação de cadeia de caracteres:
param($UserInputVar)
$DynamicScript = "Get-ChildItem $UserInputVar"
$ScriptBlock = [ScriptBlock]::Create($DynamicScript)
Invoke-Command $ScriptBlock
Exemplo desse mesmo bloco de script construído sem concatenação de cadeia de caracteres:
param($UserInputVar)
[ScriptBlock]$ScriptBlock = {
Param($SafeUserInput)
Get-ChildItem $ SafeUserInput
}
Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList @($UserInputVar)
# OR, alternatively
param($UserInputVar)
Invoke-Command -ScriptBlock {
param(
[String] $SafeUserInput
)
Get-ChildItem $SafeUserInput
} -ArgumentList $UserInputVar
Os arquivos de script também não devem ser construídos usando a concatenação de cadeia de caracteres. Confira um exemplo de como não construir arquivos de script:
$Script=@'
Get-ChildItem $UserInputVar
'@
$Script = '$ UserInputVar =' + "'$ UserInputVar;"+$Script
$path = “C:\temp”
$Script | Out-File $path
Em vez disso, construa seus arquivos de script como este:
Function test {
param(
[String] $userInputVar
)
Get-ChildItem $UserInputVar
}
$path = “C:\temp”
(Get-Command test).ScriptBlock | Set-Content -path $path
Todo o código do PowerShell deve ser assinado e armazenado no local adequado
Como parte das alterações do Windows Admin Center feitas para dar suporte ao gerenciamento da infraestrutura imposta pelo WDAC, os scripts do PowerShell assinados para uma extensão agora são transferidos para o nó ao qual o Windows Admin Center está conectado no momento antes de serem executados. Além disso, conforme mencionado no requisito anterior, a infraestrutura imposta pelo WDAC executa apenas scripts assinados do PowerShell. Devido a esses requisitos, todo o código do PowerShell deve ser assinado. Todo o PowerShell também deve estar localizado em um local consistente para que a plataforma do Windows Admin Center possa localizar previsivelmente os módulos assinados de uma extensão.
Se o repositório de extensão não contiver um diretório powershell-module
que contenha módulos assinados do PowerShell, a plataforma do Windows Admin Center não poderá identificar o código transferível e as operações falharão em um ambiente imposto pelo WDAC.
O comando gulp build
Windows Admin Center atualiza a pasta /dist
dentro do repositório, gerando seus arquivos .psd1 e .psm1 sem sinal dentro de uma pasta de módulo. Esses arquivos precisam ser assinados com um certificado de assinatura que corresponda a um que esteja listado na política do WDAC.
Para fazer essa alteração, é altamente recomendável criar um pipeline de build que incorpore a assinatura do PowerShell.
Você pode validar se o PowerShell está no formato adequado de uma das duas maneiras:
- Quando a extensão estiver instalada, você poderá exibir o diretório
ProgramData\Server Management Experience\UX\modules
no computador do gateway (aquele no qual Windows Admin Center está em execução). Aqui você deve ver a pastapowershell-module
e os módulos assinados do PowerShell - Extraia o conteúdo do artefato .nupkg da sua extensão. A pasta
powershell-module
deve estar presente e conter os módulos assinados do PowerShell.
Em ambos os casos, verificar se os arquivos .psd1 e .psm1 estão assinados pode ser feito executando o comando Get-AuthenticodeSignature no arquivo ou clicando com o botão direito do mouse no próprio arquivo e validando a assinatura digital.
WorkItems que utilizam a propriedade "powerShellScript" devem ser atualizados para usar a propriedade "powerShellCommand"
A plataforma do Windows Admin Center precisa ser capaz de determinar a qual módulo um comando do PowerShell pertence. Devido a esse requisito, WorkItems que especificam um comando do PowerShell usando a propriedade powerShellScript
causam um erro.
Para atenuar esse comportamento, use a propriedade powerShellCommand
, juntamente com o método createCommand
, para formar um objeto de comando válido.
Veja um exemplo de um WorkItem usando o método antigo:
const workItem : WorkItemSubmitRequest = {
typeId: "SampleWorkItem",
title: "Title",
powerShellScript: PowerShellScripts.[scriptName],
successMessage: "Success",
errorMessage: "Error",
progressMessage: "In progress..."
}
Veja o mesmo WorkItem usando o novo método:
const workItem : WorkItemSubmitRequest = {
typeId: "SampleWorkItem",
title: "Title",
powerShellCommand: PowerShell.createCommand(PowerShellScripts.[scriptName]),
successMessage: "Success",
errorMessage: "Error",
progressMessage: "In progress..."
}
Garantir que os scripts do PowerShell sejam executados no modo de Linguagem restrita
Muitas políticas WDAC forçam todos os scripts do PowerShell a serem executados no modo de Linguagem restrita. Para manter a funcionalidade completa em todo o Windows Admin Center, você deve garantir que todos os scripts em sua extensão sigam estas práticas recomendadas:
- Se os arquivos de script forem exportados usando módulos do PowerShell, eles deverão exportar explicitamente as funções por nome sem o uso de caracteres curinga. Esse requisito é para evitar expor inadvertidamente funções auxiliares que podem não ser usadas publicamente.
- O fornecimento de ponto de um arquivo de script traz todas as funções, variáveis e aliases desse script para o escopo atual. Essa funcionalidade impede que um script confiável seja originado em um script não confiável e exponha todas as suas funções internas. Da mesma forma, um script não confiável é impedido de ser originado em um script confiável para que ele não possa poluir o escopo confiável.
- É recomendável evitar o uso do comando Start-Job para executar blocos de script, a menos que esse bloco de script já possa ser executado com êxito no modo Linguagem restrita.
Tratamento de erro sugerido para falha ao dar suporte ao gerenciamento de infraestrutura imposta pelo WDAC
Se você não planeja dar suporte à execução de sua extensão em computadores imposto pelo WDAC, sugerimos adicionar a interface do usuário explicando que o gerenciamento da infraestrutura imposta do WDAC é um cenário sem suporte em sua extensão para evitar confusão do usuário. Recomendamos um layout como nossas páginas de serviços híbridos do Azure existentes, que apresenta o ícone de extensão e o texto centralizado no iFrame da extensão.
Para o texto nesta página, sugerimos a seguinte redação:
"No momento, essa extensão não dá suporte à execução em computadores com o WDAC (Controle de Aplicativos do Windows Defender) imposto."
Este texto é apenas uma sugestão. Se você não tiver certeza sobre a redação que gostaria de usar, envie um email para a equipe de Windows Admin Center em wacextensionrequests@microsoft.com.
Detectando a imposição do WDAC de sua extensão
Para seguir as diretrizes na seção anterior, você precisa determinar se o nó ao qual você está conectado tem o WDAC imposto. O Windows Admin Center expõe um método chamado getPsLanguageMode
, definido como parte das operações do WDAC do Windows Admin Center, para determinar a imposição do WDAC.
Esse método tem duas saídas:
- Status – tipo HTTPStatusCode
- psLanguageMode – tipo PsLanguageMode (enumeração)
Você pode considerar que o WDAC será imposto se o PowerShell estiver em execução no Modo de Linguagem Restrita, que corresponde a um valor psLanguageMode de 3.
O seguinte código de exemplo TypeScript fornece um exemplo de como usar esse método:
import { Component, OnInit } from '@angular/core';
import { AppContextService } from '@microsoft/windows-admin-center-sdk/angular';
import { WdacOperations } from '@microsoft/windows-admin-center-sdk/core';
import { PSLanguageMode, PsLanguageModeResult } from '@microsoft/windows-admin-center-sdk/core/data/wdac-operations';
@Component({
selector: 'default-component',
templateUrl: './default.component.html',
styleUrls: ['./default.component.css']
})
export class DefaultComponent implements OnInit {
wdacEnforced: boolean;
constructor(private appContextService: AppContextService) {
//
}
public ngOnInit(): void {
}
public checkWDACEnforced(): void {
const wdacOperations = new WdacOperations(this.appContextService);
wdacOperations.getPsLanguageMode(this.appContextService.activeConnection.nodeName).subscribe(
(response: PsLanguageModeResult) => {
if (response.psLanguageMode.toString() === PSLanguageMode[PSLanguageMode.ConstrainedLanguage]) {
this.wdacEnforced = true;
}
else {
this.wdacEnforced = false;
}
}
);
}
}
Testando sua extensão na infraestrutura imposta pelo WDAC
Leia mais sobre os requisitos de política do Controle de Aplicativos do Windows Defender para Windows Admin Center para começar a testar sua extensão na infraestrutura imposta pelo WDAC.