Skip to content

Commit

Permalink
Fix nmap#756 - Support running NpcapHelper.exe as a different user.
Browse files Browse the repository at this point in the history
  • Loading branch information
conioh committed Oct 22, 2024
1 parent 92faf25 commit 2122803
Showing 1 changed file with 89 additions and 5 deletions.
94 changes: 89 additions & 5 deletions packetWin7/Helper/NpcapHelper/NpcapHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,60 @@ void terminateSelf() noexcept
TerminateProcess(hself, 0);
}

// Slightly modified from:
// https://learn.microsoft.com/en-us/windows/win32/secauthz/enabling-and-disabling-privileges-in-c--
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;

if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
TRACE_PRINT1("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
{
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
}
else
{
tp.Privileges[0].Attributes = 0;
}

// Enable the privilege or disable all privileges.

if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
TRACE_PRINT1("AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
TRACE_PRINT("The token does not have the specified privilege.\n");
return FALSE;
}

return TRUE;
}

_Must_inspect_result_
_Success_(return != INVALID_HANDLE_VALUE)
HANDLE getDeviceHandleInternal(_In_ LPCSTR SymbolicLinkA, _Out_ _On_failure_(_Out_range_(1,MAXDWORD)) DWORD *pdwError)
Expand All @@ -124,6 +178,7 @@ HANDLE getDeviceHandleInternal(_In_ LPCSTR SymbolicLinkA, _Out_ _On_failure_(_Ou
DWORD dwError;
BOOL bResult;
HANDLE hClientProcess;
HANDLE hMyToken;

TRACE_PRINT1("Original handle: %08p.\n", hFile);
if (hFile == INVALID_HANDLE_VALUE)
Expand All @@ -132,6 +187,23 @@ HANDLE getDeviceHandleInternal(_In_ LPCSTR SymbolicLinkA, _Out_ _On_failure_(_Ou
TRACE_PRINT1("CreateFileA failed, GLE=%d.\n", dwError);
return INVALID_HANDLE_VALUE;
}

bResult = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hMyToken);
if (!bResult)
{
*pdwError = dwError = GetLastError();
TRACE_PRINT1("OpenProcessToken failed, GLE=%d.\n", dwError);
return INVALID_HANDLE_VALUE;
}

bResult = SetPrivilege(hMyToken, SE_DEBUG_NAME, TRUE);
if (!bResult)
{
*pdwError = dwError = GetLastError();
TRACE_PRINT1("SetPrivilege failed, GLE=%d.\n", dwError);
return INVALID_HANDLE_VALUE;
}

hClientProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, g_sourcePID);
if (hClientProcess == NULL)
{
Expand Down Expand Up @@ -173,6 +245,11 @@ BOOL createPipe(LPCSTR pipeName) noexcept
HANDLE hHeap = GetProcessHeap();
char lpszPipename[BUFSIZE];
sprintf_s(lpszPipename, BUFSIZE, "\\\\.\\pipe\\%s", pipeName);

struct TokenInfoBuffer {
TOKEN_USER tokenUser;
BYTE buffer[SECURITY_MAX_SID_SIZE];
};

// Create a DACL that allows only the same user as the PID we were given to access the pipe
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, g_sourcePID);
Expand All @@ -188,10 +265,7 @@ BOOL createPipe(LPCSTR pipeName) noexcept
CloseHandle(hProc);
return FALSE;
}
struct {
TOKEN_USER tokenUser;
BYTE buffer[SECURITY_MAX_SID_SIZE];
} tokenInfoBuffer;
TokenInfoBuffer tokenInfoBuffer;
DWORD dwTokenSize;
ZeroMemory(&tokenInfoBuffer, sizeof(tokenInfoBuffer));
if (!GetTokenInformation(hToken, TokenUser, &tokenInfoBuffer.tokenUser, sizeof(tokenInfoBuffer), &dwTokenSize))
Expand All @@ -208,13 +282,17 @@ BOOL createPipe(LPCSTR pipeName) noexcept
TRACE_PRINT("Invalid owner SID\n");
return FALSE;
}

SID creatorOwnerSid{ 1, 1, SECURITY_CREATOR_SID_AUTHORITY, {SECURITY_CREATOR_OWNER_RIGHTS_RID} };

SECURITY_DESCRIPTOR sd;
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
TRACE_PRINT1("InitializeSecurityDescriptor failed: %#x\n", GetLastError());
return FALSE;
}
DWORD cbDacl = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD);
DWORD cbDacl = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD);
cbDacl += GetLengthSid(&creatorOwnerSid);
cbDacl += GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid);
PACL pDacl = (PACL) HeapAlloc(hHeap, 0, cbDacl);
if (pDacl == NULL)
Expand All @@ -228,6 +306,12 @@ BOOL createPipe(LPCSTR pipeName) noexcept
HeapFree(hHeap, 0, pDacl);
return FALSE;
}
if (!AddAccessAllowedAce(pDacl, ACL_REVISION, GENERIC_ALL, &creatorOwnerSid))
{
TRACE_PRINT1("AddAccessAllowedAce failed: %#x\n", GetLastError());
HeapFree(hHeap, 0, pDacl);
return FALSE;
}
if (!AddAccessAllowedAce(pDacl, ACL_REVISION, GENERIC_ALL, tokenInfoBuffer.tokenUser.User.Sid))
{
TRACE_PRINT1("AddAccessAllowedAce failed: %#x\n", GetLastError());
Expand Down

0 comments on commit 2122803

Please sign in to comment.