← Voltar para Artigos

PowerShell para Segurança Ofensiva — Parte 1: Fundamentos

Entenda os fundamentos do PowerShell — objetos, pipeline e cmdlets essenciais — e por que ele é central em administração, defesa e pentest autorizado.

Imagem de capa do artigo PowerShell para Segurança Ofensiva, Parte 1, Null Trace, com terminal PowerShell estilizado

PowerShell é uma das interfaces mais importantes do ecossistema Windows. Para administradores, ele representa automação e gerenciamento em escala. Para equipes de segurança, essa mesma capacidade o transforma em uma fonte valiosa de telemetria — e em uma ferramenta frequentemente observada durante operações ofensivas.

Diferente de um simples interpretador de comandos, o PowerShell é construído sobre o .NET, expõe objetos estruturados em vez de texto puro e se integra nativamente com WMI, CIM e as APIs administrativas do Windows. Essa combinação o tornou onipresente: está em praticamente toda instalação moderna do sistema, é assinado digitalmente pela Microsoft, é confiável por padrão para a maioria das soluções de segurança e permite automatizar desde tarefas triviais até operações complexas de gerenciamento de domínio.

É exatamente essa onipresença que alimenta o conceito de Living off the Land (LotL): em vez de trazer ferramentas externas — que podem ser detectadas com facilidade — um operador (seja um Red Team autorizado, seja um adversário real) utiliza binários e frameworks já presentes no sistema-alvo para atingir seus objetivos. O PowerShell é, hoje, um dos exemplos mais citados dessa abordagem, e por isso aparece com destaque em frameworks como o MITRE ATT&CK, na técnica T1059.001 — Command and Scripting Interpreter: PowerShell.

Nesta primeira parte da série, o objetivo é construir a base necessária para entender o PowerShell como linguagem, shell e plataforma de automação, antes de avançarmos para cenários mais complexos de enumeração de ambientes Windows e Active Directory. Vale reforçar o ponto de partida:

PowerShell não é uma ferramenta maliciosa. É uma plataforma administrativa poderosa que pode ser utilizada tanto por administradores quanto por profissionais de segurança e adversários — o que muda é a intenção, a autorização e o contexto de uso.

USO RESPONSÁVEL

Todos os comandos deste artigo devem ser executados apenas em laboratório próprio, máquinas virtuais isoladas, ambientes de CTF ou infraestrutura para a qual você tenha autorização explícita por escrito. Executar essas técnicas contra sistemas de terceiros sem autorização é ilegal.

Entendendo o PowerShell

O PowerShell nasceu como um projeto interno da Microsoft (codinome Monad) e foi lançado publicamente em 2006 como uma tentativa de resolver um problema antigo: o CMD e o VBScript eram limitados demais para administração séria de sistemas em escala. A solução foi construir um shell inteiramente sobre o .NET Framework (e, a partir do PowerShell 6, sobre o .NET Core multiplataforma), o que trouxe acesso direto a praticamente toda a superfície de classes e métodos do .NET.

Alguns conceitos são essenciais para qualquer pessoa que vá trabalhar com PowerShell de forma séria:

  • Cmdlets — comandos nativos no padrão Verbo-Substantivo (ex.: Get-Process, Stop-Service). O padrão é consistente e previsível: verbos como Get, Set, New, Remove, Start e Stop se repetem em toda a plataforma.
  • Pipeline — o operador | encadeia comandos passando objetos, não texto, de um cmdlet para o próximo.
  • Objetos — cada saída de comando é uma instância de uma classe .NET, com propriedades e métodos acessíveis diretamente.
  • Aliases — atalhos para cmdlets (ex.: ls é um alias para Get-ChildItem).
  • Providers — camadas que expõem estruturas hierárquicas (sistema de arquivos, Registry, certificados, variáveis de ambiente) como se fossem um sistema de diretórios navegável.
  • Modules — pacotes de cmdlets, funções e recursos que podem ser importados sob demanda (Import-Module ActiveDirectory, por exemplo).
  • WMI / CIM — Windows Management Instrumentation e Common Information Model, as camadas que expõem informações profundas de hardware, sistema operacional e configuração para consulta e gerenciamento remoto.

A diferença mais fundamental em relação a shells como o Bash está na natureza do que trafega entre comandos:

Bash normalmente trabalha com texto. PowerShell trabalha com objetos.

No Bash, a saída de ps aux é uma tabela de texto que muitas vezes precisa ser recortada com awk, cut ou expressões regulares para extrair um campo específico. No PowerShell, a saída de Get-Process já é uma coleção de objetos System.Diagnostics.Process, com propriedades tipadas como CPU, Id e WorkingSet — não é necessário fazer parsing de texto para acessá-las.

Diagrama mostrando as camadas do PowerShell: PowerShell sobre .NET, sobre WMI/CIM, sobre as APIs do Windows
Camadas de acesso do PowerShell ao sistema operacional Windows.

PowerShell vs. CMD vs. Bash

Para quem já tem familiaridade com Linux, o caminho mais rápido para aprender PowerShell é reconhecer os cmdlets equivalentes às ferramentas Unix mais usadas no dia a dia:

ObjetivoPowerShellCMD / Linux equivalente
Listar arquivosGet-ChildItemdir / ls
Mudar de diretórioSet-Locationcd
Exibir conteúdo de arquivoGet-Contenttype / cat
Copiar arquivoCopy-Itemcopy / cp
Mover/renomearMove-Itemmove / mv
Remover arquivoRemove-Itemdel / rm
Listar processosGet-Processtasklist / ps
Listar serviçosGet-Servicesc query / systemctl
Ajuda de um comandoGet-Helphelp / man

Muitos desses cmdlets já possuem aliases que imitam o mundo Unix — ls, cd, cat, pwd, cp, mv e rm funcionam de fato no PowerShell. Mas é importante entender que são apenas atalhos textuais: rm aciona Remove-Item, que não tem exatamente o mesmo comportamento, flags ou tratamento de erros que o rm do GNU Coreutils. Confiar cegamente no alias sem entender o cmdlet por trás dele é uma fonte comum de comportamento inesperado em scripts.

Sistema de ajuda

Antes de decorar comandos, vale a pena dominar o sistema de descoberta do próprio PowerShell — ele foi desenhado para ser autoexplicativo.

  • Get-Help — exibe a documentação de um cmdlet, incluindo sintaxe, parâmetros e exemplos.
  • Get-Command — pesquisa cmdlets, funções e aliases disponíveis por nome, verbo ou substantivo.
  • Get-Member — lista as propriedades e métodos do objeto que está passando pelo pipeline.
Get-Help Get-Process
Get-Help Get-Process -Examples
Get-Command *service*
Get-Process | Get-Member

Esse último exemplo — encadear Get-Member ao final de qualquer comando — é provavelmente o hábito mais valioso para quem está começando: ele revela exatamente quais propriedades um objeto expõe, tornando desnecessário adivinhar nomes de campos.

Navegação e enumeração de arquivos

A navegação no sistema de arquivos segue o mesmo padrão Verbo-Substantivo:

Get-Location                 # equivalente a pwd
Get-ChildItem                # equivalente a ls / dir
Set-Location C:Windows      # equivalente a cd
Get-Content .arquivo.txt    # equivalente a cat

O PowerShell também suporta wildcards para filtrar resultados diretamente na navegação: * substitui qualquer sequência de caracteres e ? substitui exatamente um caractere. Um exemplo seguro de laboratório:

# Lista todos os arquivos .log dentro de C:lab
Get-ChildItem -Path C:lab -Filter *.log -Recurse

# Lista arquivos cujo nome tem exatamente 5 caracteres antes da extensão
Get-ChildItem -Path C:lab -Filter ?????.txt

O parâmetro -Recurse percorre subdiretórios recursivamente e é frequentemente combinado com filtros de conteúdo (que veremos mais adiante) para localizar arquivos de interesse em uma árvore inteira de diretórios.

Pipeline: o coração do PowerShell

Se há um conceito que separa quem apenas “usa comandos” de quem realmente domina PowerShell, é o pipeline. Cada cmdlet recebe objetos de entrada, processa e emite objetos de saída — que se tornam a entrada do próximo cmdlet na cadeia. O fluxo pode ser resumido assim:

Diagrama do fluxo do pipeline do PowerShell: Command gera Object, que passa pelo Pipeline, é processado por Filter/Select e resulta em Output
Fluxo de objetos no pipeline do PowerShell.

Na prática, isso permite construir consultas expressivas sem escrever um script inteiro. Dois exemplos comuns:

# Ordena os processos por consumo de CPU, do maior para o menor
Get-Process | Sort-Object CPU -Descending

# Filtra apenas os serviços que estão em execução
Get-Service | Where-Object Status -eq 'Running'

Sort-Object e Where-Object não precisam saber nada sobre processos ou serviços especificamente — eles operam sobre qualquer objeto que receberem, inspecionando as propriedades solicitadas. Essa composabilidade é o motivo pelo qual PowerShell é tão eficiente para enumeração: um punhado de cmdlets genéricos (Where-Object, Select-Object, Sort-Object, ForEach-Object, Group-Object) combinados com cmdlets específicos cobrem a grande maioria dos casos de uso administrativos e de reconhecimento de host.

Enumeração do sistema

Um dos usos mais imediatos do PowerShell — tanto para administração quanto para reconhecimento autorizado — é levantar um inventário rápido do host. Os comandos abaixo são todos nativos e não exigem módulos adicionais em instalações modernas do Windows:

Get-ComputerInfo                 # visão geral de SO, build, hotfixes, hardware
Get-Process                      # processos em execução
Get-Service                      # serviços instalados e seu estado
Get-NetIPAddress                 # configuração de IP das interfaces de rede
Get-NetTCPConnection             # conexões TCP ativas e portas em escuta

Esse tipo de levantamento tem valor em múltiplos contextos: administradores usam para inventário e troubleshooting; equipes de DFIR usam para reconstruir o estado de um host durante uma investigação; e em um pentest autorizado, é exatamente esse tipo de informação — versão do sistema, patches ausentes, serviços expostos, conexões ativas — que orienta os próximos passos de uma avaliação.

Usuários e sessões

Para enumerar contas locais, o cmdlet nativo é Get-LocalUser:

Get-LocalUser
Get-LocalUser | Where-Object Enabled -eq $true

Para visualizar sessões interativas ativas em um host, o Windows conta com duas ferramentas administrativas legadas que continuam amplamente usadas: quser (lista usuários conectados, estado da sessão e tempo de ociosidade) e qwinsta (lista sessões, incluindo as desconectadas). Ambas são úteis para entender rapidamente quem está logado em um servidor antes de qualquer ação administrativa — mas não são, e não devem ser tratadas como, ferramentas para interromper sessões de terceiros sem autorização.

Processos e serviços em detalhe

Get-Process e Get-Service merecem atenção especial porque aparecem em praticamente todo fluxo de análise de host. Combinados com Where-Object, permitem consultas direcionadas:

# Serviços em execução, ordenados por nome
Get-Service | Where-Object Status -eq 'Running' | Sort-Object Name

# Processos com maior consumo de memória
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 10

Esse tipo de consulta é rotina para inventário, diagnóstico de performance, resposta a incidentes (identificar um processo anômalo consumindo recursos) e para a fase de reconhecimento de host em um pentest autorizado, onde entender o que está rodando informa a superfície de ataque disponível.

Registry

O Registro do Windows é exposto ao PowerShell como um provider navegável, com os mesmos cmdlets usados no sistema de arquivos. As três raízes mais relevantes no dia a dia são:

  • HKLM (HKEY_LOCAL_MACHINE) — configurações globais da máquina.
  • HKCU (HKEY_CURRENT_USER) — configurações do usuário atual.
  • HKCR (HKEY_CLASSES_ROOT) — associações de tipo de arquivo e informações de COM.
Get-ChildItem HKLM:SOFTWARE
Get-ItemProperty -Path 'HKLM:SOFTWAREMicrosoftWindowsCurrentVersion'

Do ponto de vista defensivo, o Registry é relevante porque configurações sensíveis — chaves de execução automática, credenciais mal armazenadas, parâmetros de aplicações legadas — muitas vezes acabam salvas em texto claro por má prática de desenvolvimento ou implantação. O que o Blue Team deve procurar:

  • Chaves de Run e RunOnce com entradas não reconhecidas (possível persistência).
  • Valores de configuração de aplicações contendo strings que pareçam senhas, tokens ou connection strings.
  • Alterações recentes em chaves sensíveis, correlacionadas com os logs de auditoria do Registry (Event ID 4657, quando habilitado).

Onde credenciais expostas costumam aparecer

Um dos erros de configuração mais recorrentes em ambientes reais é o armazenamento inadequado de segredos. Este artigo não vai demonstrar técnicas de coleta de credenciais reais — o objetivo aqui é puramente conceitual, para orientar tanto avaliação (em ambiente autorizado) quanto detecção. Locais onde credenciais expostas aparecem com frequência:

  • Arquivos de configuração de aplicações (web.config, appsettings.json, arquivos .env).
  • Scripts de automação e deployment deixados em compartilhamentos de rede.
  • Variáveis de ambiente configuradas de forma persistente no sistema.
  • Valores gravados diretamente no Registry por instaladores mal projetados.
  • Histórico de comandos, quando segredos são digitados diretamente na linha de comando.

Um exemplo ilustrativo, com dado inteiramente fictício, de como esse tipo de exposição costuma se parecer em um arquivo de configuração de laboratório:

# labdeploy.ps1 (exemplo fictício de laboratório)
$ConnString = "Server=lab-sql;User=svc_deploy;Password=DEMO_SECRET_123;"

Detecção: soluções de DLP e regras de EDR podem varrer compartilhamentos e repositórios em busca de padrões como password=, pwd= ou connection strings. Mitigação: cofres de segredo dedicados (Azure Key Vault, HashiCorp Vault, Microsoft.PowerShell.SecretManagement), rotação periódica de credenciais de serviço e revisão de permissões de compartilhamentos de rede que hospedam scripts.

Buscando padrões em arquivos: Select-String

O equivalente PowerShell ao grep — e sucessor natural do legado findstr do CMD — é o Select-String. Ele aceita expressões regulares e é a ferramenta natural para localizar padrões dentro de árvores de arquivos, como no exemplo de detecção acima:

# Procura o marcador fictício DEMO_SECRET em arquivos de laboratório
Select-String -Path ".lab*.txt" -Pattern "DEMO_SECRET"

# Busca recursiva com expressão regular simples
Get-ChildItem -Path C:lab -Recurse -Include *.ps1,*.txt |
    Select-String -Pattern "DEMO_SECRET"

Os exemplos acima usam exclusivamente um marcador fictício (DEMO_SECRET) dentro de uma pasta de laboratório — a técnica é a mesma que seria usada para localizar qualquer padrão de texto, mas o uso responsável exige buscar apenas em dados que você tem autorização para inspecionar.

Execution Policy

A Execution Policy controla se e como scripts .ps1 podem ser executados em uma sessão. Os níveis mais comuns:

Get-ExecutionPolicy
Get-ExecutionPolicy -List
  • Restricted — nenhum script é executado (padrão histórico em algumas versões do Windows client).
  • AllSigned — apenas scripts assinados digitalmente por um editor confiável.
  • RemoteSigned — scripts locais rodam livremente; scripts baixados da internet precisam de assinatura.
  • Unrestricted — todos os scripts executam, com aviso para arquivos baixados da internet.
  • Bypass — nada é bloqueado e nenhum aviso é exibido.
ATENÇÃO

Execution Policy não deve ser tratada como uma fronteira de segurança equivalente a controle de aplicação. Ela existe para evitar execução acidental de scripts, não para impedir um usuário determinado — o parâmetro -ExecutionPolicy Bypass contorna a checagem por padrão. Controles reais de execução vêm de AppLocker, WDAC e Constrained Language Mode.

Por esse motivo, este artigo não demonstra alteração persistente de política em sistemas de produção. Se você precisar ajustar a policy para testes, faça-o apenas em uma máquina de laboratório e prefira o escopo de processo (-Scope Process), que não deixa alteração residual no sistema.

Downloads com Invoke-WebRequest

Invoke-WebRequest (e seu primo mais moderno, Invoke-RestMethod, voltado a APIs) é o cmdlet nativo para requisições HTTP. É uma ferramenta legítima de automação — usada para baixar atualizações, consumir APIs internas, testar disponibilidade de serviços — e também um dos comandos mais monitorados por soluções de EDR, justamente por seu uso recorrente em cadeias de execução ofensivas.

Invoke-WebRequest -Uri "https://example.com/sample.txt" -OutFile ".sample.txt"

O exemplo usa um domínio de exemplo e um arquivo de texto inofensivo apenas para ilustrar a sintaxe. Em qualquer avaliação de segurança real, o tráfego de rede gerado por esse tipo de comando é exatamente o que uma equipe de detecção deve conseguir correlacionar com o processo que o originou.

Execução em memória (fileless)

Fileless execution é o termo usado para técnicas em que código é carregado e executado inteiramente na memória do processo, sem gravar um binário ou script no disco. O PowerShell é frequentemente citado nesse contexto porque suporta nativamente a execução de código recebido via string, pipeline ou rede, sem exigir um arquivo intermediário.

Do lado ofensivo, a motivação é reduzir artefatos em disco que ferramentas de antivírus tradicionais, baseadas em assinatura de arquivo, poderiam detectar. Do lado defensivo, essa mesma característica levou ao desenvolvimento de controles que operam no nível de comportamento e de conteúdo do script, não apenas no nível de arquivo:

  • AMSI (Antimalware Scan Interface) — expõe o conteúdo de scripts, mesmo gerados dinamicamente, para o mecanismo antimalware registrado no sistema, antes da execução.
  • Script Block Logging — registra o conteúdo completo de blocos de script executados, incluindo código gerado dinamicamente.
  • PowerShell Operational Log — o canal de eventos onde essa telemetria fica disponível para análise.

Este artigo não inclui nenhum payload funcional de execução em memória — o objetivo é que você entenda o conceito e, principalmente, quais controles de visibilidade existem para monitorá-lo, que serão detalhados na seção de logs mais adiante.

Base64: codificação, não criptografia

Um ponto de confusão comum — inclusive fora do contexto de segurança — é tratar Base64 como uma forma de criptografia. Não é: Base64 é apenas uma codificação reversível, sem chave, usada para representar dados binários como texto ASCII seguro para transporte. Qualquer pessoa pode decodificá-la instantaneamente.

# Codificando um texto simples
$text = 'Null Trace'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($text)
[Convert]::ToBase64String($bytes)

# Decodificando de volta
$encoded = 'TgB1AGwAbAAgAFQAcgBhAGMAZQA='
$decodedBytes = [Convert]::FromBase64String($encoded)
[System.Text.Encoding]::Unicode.GetString($decodedBytes)

O motivo pelo qual Base64 aparece com tanta frequência em telemetria de segurança é o parâmetro -EncodedCommand do powershell.exe, que permite passar um bloco de comando inteiro codificado em Base64 na linha de comando — útil para evitar problemas de escaping de caracteres especiais em automação legítima, mas também um padrão clássico observado em execução ofensiva, já que ofusca superficialmente o comando de uma leitura rápida no Process Explorer ou em logs de linha de comando não decodificados.

PowerShell e soluções de segurança

Um adversário motivado pode tentar interferir em soluções de antivírus e EDR para operar sem ser detectado. Esse comportamento — chamado de defense evasion ou tampering — é uma das táticas mais sensíveis do MITRE ATT&CK (TA0005), e por isso este artigo não demonstra comandos para desativar Defender, EDR ou qualquer solução de antivírus.

O que é legítimo e útil demonstrar é como consultar, de forma passiva, o estado desses serviços — algo que administradores e auditores de segurança fazem rotineiramente:

Get-Service -Name WinDefend
Get-MpComputerStatus

Do lado defensivo, o Microsoft Defender conta com Tamper Protection, que bloqueia alterações não autorizadas em suas próprias configurações mesmo por processos com privilégios administrativos. EDRs modernos também geram alertas de alta severidade especificamente para tentativas de parar seus próprios serviços, desinstalar agentes ou modificar exclusões — telemetria que qualquer SOC deve tratar como prioridade máxima quando observada.

PowerShell 2.0 e ataques de downgrade

O PowerShell 2.0, lançado em 2009, permanece instalável como recurso opcional em muitas versões do Windows por razões de compatibilidade retroativa — e isso é um problema de segurança conhecido. A versão 2.0 antecede a introdução de AMSI, Script Block Logging e boa parte do Constrained Language Mode, o que significa que um adversário capaz de forçar a execução de um script nessa versão específica (o chamado downgrade attack) consegue operar com uma fração da visibilidade e dos controles disponíveis nas versões modernas.

A mitigação recomendada pela própria Microsoft é direta: remover o recurso opcional Windows PowerShell 2.0 em ambientes onde não há dependência legada real. Para detecção, equipes de Blue Team monitoram o Event ID 400 (engine lifecycle) no log de PowerShell, observando o campo EngineVersion — qualquer valor 2.0 em um ambiente que deveria estar rodando versões modernas é um forte indicador de tentativa de downgrade.

Persistência: profiles e tarefas agendadas

Dois mecanismos legítimos de automação do Windows — PowerShell Profiles e Scheduled Tasks — também estão entre os métodos de persistência mais observados em incidentes reais, justamente por serem nativos, comuns em ambientes corporativos e, portanto, fáceis de camuflar entre configurações legítimas.

Como adversários abusam, em nível conceitual: um profile é executado automaticamente sempre que uma nova sessão PowerShell é aberta, o que o torna um gatilho de execução persistente e discreto. Uma Scheduled Task pode ser configurada para rodar com um trigger baseado em tempo ou evento, executando uma action sob um principal (conta) específico — se esse principal tiver privilégios elevados, a tarefa herda esse contexto de privilégio.

Como detectar: monitorar criação e modificação dos arquivos de profile (Event ID 4663 no log de segurança, com auditoria de objeto habilitada), e monitorar criação de tarefas agendadas via Event ID 4698. Como mitigar: restringir permissões de escrita nos diretórios de profile do sistema, revisar periodicamente tarefas agendadas com Get-ScheduledTask e aplicar least privilege nas contas de serviço usadas como principal.

PowerShell Profile

A variável automática $PROFILE aponta para o caminho do script de perfil do usuário atual:

$PROFILE
Test-Path $PROFILE

# Exemplo seguro de laboratório: adiciona uma mensagem ao abrir o console
Add-Content $PROFILE 'Write-Host "Null Trace Lab"'

Em ambientes corporativos, faz sentido tratar alterações no profile como um evento digno de auditoria — a maioria dos usuários nunca precisa editar esse arquivo manualmente, então qualquer modificação inesperada merece investigação.

Scheduled Tasks

Para enumerar tarefas agendadas existentes no host:

Get-ScheduledTask | Select-Object TaskName, State, Author
Get-ScheduledTask -TaskName "NomeDaTarefa" | Get-ScheduledTaskInfo

Cada tarefa é composta por um trigger (quando executar — por horário, no logon, em resposta a um evento), uma action (o que executar) e um principal (sob qual conta e nível de privilégio). Ao revisar tarefas em um host, os três pontos merecem atenção conjunta: uma action apontando para um interpretador de script (powershell.exe, wscript.exe) combinada com um principal privilegiado e um autor não reconhecido é um padrão que justifica investigação mais profunda.

Histórico de comandos

O PowerShell mantém histórico de comandos da sessão atual via Get-History, e o módulo PSReadLine persiste esse histórico entre sessões em um arquivo de texto no perfil do usuário. Isso é conveniente — mas também significa que qualquer segredo digitado diretamente na linha de comando (uma senha passada como parâmetro, por exemplo) fica gravado em texto claro nesse arquivo.

Get-History
(Get-PSReadLineOption).HistorySavePath

Boas práticas para evitar esse tipo de exposição: nunca passar segredos diretamente como argumento de linha de comando; usar o módulo Microsoft.PowerShell.SecretManagement com um cofre (vault) apropriado; e, quando disponível, preferir o Windows Credential Manager para armazenamento de credenciais reutilizáveis. Este artigo não recomenda apagar ou adulterar histórico/logs como técnica — isso é evasão, não higiene de segurança, e é ativamente monitorado em ambientes maduros.

Logs importantes para o Blue Team

Esta é, possivelmente, a seção mais importante do artigo para quem atua em defesa. O PowerShell moderno oferece múltiplas camadas de telemetria, e conhecê-las é pré-requisito tanto para detecção quanto para qualquer avaliação ofensiva que precise entender o que fica registrado:

  • Microsoft-Windows-PowerShell/Operational — o canal de eventos principal, onde vivem os registros de Script Block Logging e engine lifecycle.
  • Script Block Logging — registra o texto completo de blocos de script executados, incluindo código gerado dinamicamente e comandos decodificados de Base64.
  • Module Logging — registra a execução de pipeline por módulo, incluindo variáveis e parâmetros.
  • Transcription — grava uma transcrição em texto de toda a sessão, incluindo entrada e saída, em um arquivo no disco.
  • AMSI — fornece ao mecanismo antimalware registrado uma visão do conteúdo do script antes da execução, mesmo quando gerado dinamicamente.
Diagrama mostrando o caminho da atividade do PowerShell até a detecção: PowerShell Activity, Logging, AMSI/EDR, Detection
Do uso do PowerShell até a detecção pelo Blue Team.
DEFESA

Habilitar Script Block Logging e Module Logging via Diretiva de Grupo (Administrative Templates → Windows Components → Windows PowerShell) é uma das melhorias de visibilidade de maior custo-benefício disponíveis em qualquer ambiente Windows, e não exige licenciamento adicional.

Indicadores que merecem atenção

Sem entrar em contagens específicas de eventos — que variam por ambiente e ferramenta — alguns padrões comportamentais são consistentemente citados como dignos de investigação por equipes de detecção:

  • powershell.exe com argumentos codificados em Base64 (-EncodedCommand / -enc).
  • Processos filhos incomuns gerados a partir de powershell.exe (por exemplo, um segundo interpretador ou uma conexão de rede inesperada).
  • PowerShell iniciado como processo filho de aplicações Office (Word, Excel, Outlook) — padrão clássico de execução via macro.
  • Scripts executados a partir de diretórios temporários ou pastas de downloads do usuário.
  • Uso incomum de Invoke-Expression combinado com conteúdo obtido via rede.
  • Criação de tarefas agendadas fora de janelas de manutenção conhecidas.
  • Alterações inesperadas em arquivos de profile do PowerShell.

Nenhum desses indicadores é definitivo isoladamente — automação legítima também pode gerar alguns deles. O valor está em correlacionar múltiplos sinais e estabelecer uma linha de base do que é normal em cada ambiente.

Hardening: como reduzir o abuso de PowerShell

Um conjunto de controles, aplicados em camadas, reduz significativamente a superfície de abuso do PowerShell sem eliminar sua utilidade administrativa:

  • PowerShell 7 quando aplicável — arquitetura mais moderna e melhor integração com controles de segurança atuais, mantendo o Windows PowerShell 5.1 legado sob controle à parte.
  • Desabilitar PowerShell 2.0 como recurso opcional, eliminando a superfície de downgrade.
  • Constrained Language Mode — restringe o acesso a APIs .NET sensíveis, reduzindo drasticamente o que um script não assinado pode fazer.
  • AppLocker / WDAC — controle de aplicação que pode restringir quais scripts têm permissão para executar.
  • AMSI — mantido atualizado e integrado a um mecanismo antimalware capaz de inspecionar o conteúdo do script.
  • Script Block Logging, Module Logging e Transcription — habilitados via GPO em toda a frota.
  • Defender / EDR — com Tamper Protection habilitado e exclusões revisadas periodicamente.
  • Least privilege — contas administrativas segregadas das contas de uso diário.
  • JEA (Just Enough Administration) — permite delegar tarefas administrativas específicas via PowerShell sem conceder privilégios administrativos completos.

Nenhum desses controles, isoladamente, é suficiente — a combinação de visibilidade (logging), prevenção (AppLocker/WDAC, Constrained Language Mode) e resposta (EDR) é o que efetivamente reduz o risco.

Laboratório recomendado

Para acompanhar os exemplos deste artigo e se preparar para a Parte 2 da série, uma estrutura de laboratório simples é suficiente:

  • Uma VM com Windows 11 (ou Windows Server) isolada, sem acesso à sua rede de produção.
  • Snapshot da VM limpa antes de iniciar os testes, para reverter facilmente.
  • Rede isolada (host-only ou NAT dedicado), sem exposição direta à internet quando não necessário.
  • Sysmon (opcional, mas recomendado) para telemetria de processo mais granular.
  • Windows Event Viewer aberto durante os testes, observando o canal Microsoft-Windows-PowerShell/Operational em tempo real.
LAB

Execute os exemplos deste artigo somente em ambientes próprios ou explicitamente autorizados. Reverter para o snapshot limpo entre exercícios evita que alterações de teste se acumulem e distorçam sua linha de base de observação.

Cheat sheet

Referência rápida dos comandos apresentados neste artigo:

ComandoFinalidade
Get-HelpExibe documentação de um cmdlet
Get-CommandPesquisa cmdlets, funções e aliases
Get-MemberLista propriedades e métodos de um objeto
Get-ChildItemLista arquivos, diretórios ou chaves de Registry
Get-ContentExibe conteúdo de um arquivo
Select-StringBusca padrões de texto (equivalente a grep)
Get-ComputerInfoInventário geral do sistema
Get-ProcessLista processos em execução
Get-ServiceLista serviços e seu estado
Get-LocalUserLista contas locais
Get-NetTCPConnectionLista conexões TCP ativas
Get-ScheduledTaskLista tarefas agendadas
Get-ExecutionPolicyExibe a política de execução ativa
Get-HistoryExibe histórico de comandos da sessão
Invoke-WebRequestRealiza requisições HTTP

Conclusão

PowerShell é parte central do ecossistema Windows — não uma ferramenta de nicho, mas a interface administrativa padrão de praticamente todo ambiente corporativo moderno. Esse mesmo motivo é o que o torna relevante tanto para quem defende quanto para quem avalia a segurança de um ambiente de forma autorizada: entender PowerShell é entender uma parcela significativa de como sistemas Windows são, de fato, operados, automatizados e — quando mal configurados — comprometidos.

Mais importante do que decorar cmdlets é internalizar o modelo mental de objetos e pipeline apresentado aqui: uma vez que esse conceito está claro, a maior parte da superfície do PowerShell — sejam os milhares de cmdlets nativos, sejam módulos de terceiros como o PowerView — passa a seguir um padrão previsível e fácil de explorar com o sistema de ajuda embutido.