api: elevate only when needed for system operations
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
779d0e0c38
commit
7964694e1e
@ -597,10 +597,16 @@ WintunGetAdapter(
|
|||||||
_In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name,
|
_In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name,
|
||||||
_Out_ WINTUN_ADAPTER **Adapter)
|
_Out_ WINTUN_ADAPTER **Adapter)
|
||||||
{
|
{
|
||||||
|
if (!ElevateToSystem())
|
||||||
|
return LOG(WINTUN_LOG_ERR, L"Failed to impersonate SYSTEM user"), ERROR_ACCESS_DENIED;
|
||||||
|
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
HANDLE Mutex = NamespaceTakeMutex(Pool);
|
HANDLE Mutex = NamespaceTakeMutex(Pool);
|
||||||
if (!Mutex)
|
if (!Mutex)
|
||||||
return ERROR_INVALID_HANDLE;
|
{
|
||||||
|
Result = ERROR_INVALID_HANDLE;
|
||||||
|
goto cleanupToken;
|
||||||
|
}
|
||||||
|
|
||||||
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
||||||
if (DevInfo == INVALID_HANDLE_VALUE)
|
if (DevInfo == INVALID_HANDLE_VALUE)
|
||||||
@ -675,6 +681,8 @@ cleanupDevInfo:
|
|||||||
SetupDiDestroyDeviceInfoList(DevInfo);
|
SetupDiDestroyDeviceInfoList(DevInfo);
|
||||||
cleanupMutex:
|
cleanupMutex:
|
||||||
NamespaceReleaseMutex(Mutex);
|
NamespaceReleaseMutex(Mutex);
|
||||||
|
cleanupToken:
|
||||||
|
RevertToSelf();
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1562,15 +1570,25 @@ WintunCreateAdapter(
|
|||||||
_Out_ WINTUN_ADAPTER **Adapter,
|
_Out_ WINTUN_ADAPTER **Adapter,
|
||||||
_Inout_ BOOL *RebootRequired)
|
_Inout_ BOOL *RebootRequired)
|
||||||
{
|
{
|
||||||
#ifdef MAYBE_WOW64
|
if (!ElevateToSystem())
|
||||||
if (NativeMachine != IMAGE_FILE_PROCESS)
|
return LOG(WINTUN_LOG_ERR, L"Failed to impersonate SYSTEM user"), ERROR_ACCESS_DENIED;
|
||||||
return CreateAdapterNatively(Pool, Name, RequestedGUID, Adapter, RebootRequired);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DWORD Result = ERROR_SUCCESS;
|
DWORD Result = ERROR_SUCCESS;
|
||||||
|
#ifdef MAYBE_WOW64
|
||||||
|
if (NativeMachine != IMAGE_FILE_PROCESS)
|
||||||
|
{
|
||||||
|
Result = CreateAdapterNatively(Pool, Name, RequestedGUID, Adapter, RebootRequired);
|
||||||
|
RevertToSelf();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
WCHAR RandomTempSubDirectory[MAX_PATH];
|
WCHAR RandomTempSubDirectory[MAX_PATH];
|
||||||
if ((Result = CreateTemporaryDirectory(RandomTempSubDirectory)) != ERROR_SUCCESS)
|
if ((Result = CreateTemporaryDirectory(RandomTempSubDirectory)) != ERROR_SUCCESS)
|
||||||
return LOG(WINTUN_LOG_ERR, L"Failed to create temporary folder"), Result;
|
{
|
||||||
|
LOG(WINTUN_LOG_ERR, L"Failed to create temporary folder");
|
||||||
|
goto cleanupToken;
|
||||||
|
}
|
||||||
|
|
||||||
WCHAR CatPath[MAX_PATH] = { 0 };
|
WCHAR CatPath[MAX_PATH] = { 0 };
|
||||||
WCHAR SysPath[MAX_PATH] = { 0 };
|
WCHAR SysPath[MAX_PATH] = { 0 };
|
||||||
@ -1619,6 +1637,8 @@ cleanupDelete:
|
|||||||
DeleteFileW(InfPath);
|
DeleteFileW(InfPath);
|
||||||
cleanupDirectory:
|
cleanupDirectory:
|
||||||
RemoveDirectoryW(RandomTempSubDirectory);
|
RemoveDirectoryW(RandomTempSubDirectory);
|
||||||
|
cleanupToken:
|
||||||
|
RevertToSelf();
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1663,20 +1683,31 @@ cleanupArgv:
|
|||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequired)
|
WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequired)
|
||||||
{
|
{
|
||||||
|
if (!ElevateToSystem())
|
||||||
|
return LOG(WINTUN_LOG_ERR, L"Failed to impersonate SYSTEM user"), ERROR_ACCESS_DENIED;
|
||||||
|
|
||||||
|
DWORD Result;
|
||||||
#ifdef MAYBE_WOW64
|
#ifdef MAYBE_WOW64
|
||||||
if (NativeMachine != IMAGE_FILE_PROCESS)
|
if (NativeMachine != IMAGE_FILE_PROCESS)
|
||||||
return DeleteAdapterNatively(Adapter, RebootRequired);
|
{
|
||||||
|
Result = DeleteAdapterNatively(Adapter, RebootRequired);
|
||||||
|
RevertToSelf();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HDEVINFO DevInfo;
|
HDEVINFO DevInfo;
|
||||||
SP_DEVINFO_DATA DevInfoData;
|
SP_DEVINFO_DATA DevInfoData;
|
||||||
DWORD Result = GetDevInfoData(&Adapter->CfgInstanceID, &DevInfo, &DevInfoData);
|
Result = GetDevInfoData(&Adapter->CfgInstanceID, &DevInfo, &DevInfoData);
|
||||||
if (Result == ERROR_FILE_NOT_FOUND)
|
if (Result == ERROR_FILE_NOT_FOUND)
|
||||||
return ERROR_SUCCESS;
|
{
|
||||||
if (Result != ERROR_SUCCESS)
|
Result = ERROR_SUCCESS;
|
||||||
|
goto cleanupToken;
|
||||||
|
}
|
||||||
|
else if (Result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
LOG(WINTUN_LOG_ERR, L"Failed to get device info data");
|
LOG(WINTUN_LOG_ERR, L"Failed to get device info data");
|
||||||
return Result;
|
goto cleanupToken;
|
||||||
}
|
}
|
||||||
SetQuietInstall(DevInfo, &DevInfoData);
|
SetQuietInstall(DevInfo, &DevInfoData);
|
||||||
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
|
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
|
||||||
@ -1689,6 +1720,8 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
|
|||||||
else
|
else
|
||||||
Result = LOG_LAST_ERROR(L"Unable to remove existing adapter");
|
Result = LOG_LAST_ERROR(L"Unable to remove existing adapter");
|
||||||
SetupDiDestroyDeviceInfoList(DevInfo);
|
SetupDiDestroyDeviceInfoList(DevInfo);
|
||||||
|
cleanupToken:
|
||||||
|
RevertToSelf();
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +195,7 @@
|
|||||||
<ClInclude Include="api.h" />
|
<ClInclude Include="api.h" />
|
||||||
<ClInclude Include="adapter.h" />
|
<ClInclude Include="adapter.h" />
|
||||||
<ClInclude Include="atomic.h" />
|
<ClInclude Include="atomic.h" />
|
||||||
|
<ClInclude Include="elevate.h" />
|
||||||
<ClInclude Include="logger.h" />
|
<ClInclude Include="logger.h" />
|
||||||
<ClInclude Include="namespace.h" />
|
<ClInclude Include="namespace.h" />
|
||||||
<ClInclude Include="nci.h" />
|
<ClInclude Include="nci.h" />
|
||||||
@ -206,6 +207,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="api.c" />
|
<ClCompile Include="api.c" />
|
||||||
<ClCompile Include="adapter.c" />
|
<ClCompile Include="adapter.c" />
|
||||||
|
<ClCompile Include="elevate.c" />
|
||||||
<ClCompile Include="logger.c" />
|
<ClCompile Include="logger.c" />
|
||||||
<ClCompile Include="namespace.c" />
|
<ClCompile Include="namespace.c" />
|
||||||
<ClCompile Include="nci.c" />
|
<ClCompile Include="nci.c" />
|
||||||
|
@ -55,6 +55,9 @@
|
|||||||
<ClInclude Include="atomic.h">
|
<ClInclude Include="atomic.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="elevate.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="api.c">
|
<ClCompile Include="api.c">
|
||||||
@ -87,5 +90,8 @@
|
|||||||
<ClCompile Include="session.c">
|
<ClCompile Include="session.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="elevate.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
101
api/elevate.c
Normal file
101
api/elevate.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
ElevateToSystem(void)
|
||||||
|
{
|
||||||
|
HANDLE CurrentProcessToken, ThreadToken, ProcessSnapshot, WinlogonProcess, WinlogonToken, DuplicatedToken;
|
||||||
|
PROCESSENTRY32W ProcessEntry = { .dwSize = sizeof(PROCESSENTRY32W) };
|
||||||
|
BOOL Ret;
|
||||||
|
DWORD LastError = ERROR_SUCCESS;
|
||||||
|
TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } };
|
||||||
|
CHAR LocalSystemSid[0x400];
|
||||||
|
DWORD RequiredBytes = sizeof(LocalSystemSid);
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
TOKEN_USER MaybeLocalSystem;
|
||||||
|
CHAR LargeEnoughForLocalSystem[0x400];
|
||||||
|
} TokenUserBuffer;
|
||||||
|
|
||||||
|
Ret = CreateWellKnownSid(WinLocalSystemSid, NULL, &LocalSystemSid, &RequiredBytes);
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (!Ret)
|
||||||
|
goto cleanup;
|
||||||
|
Ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken);
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (!Ret)
|
||||||
|
goto cleanup;
|
||||||
|
Ret =
|
||||||
|
GetTokenInformation(CurrentProcessToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
|
||||||
|
LastError = GetLastError();
|
||||||
|
CloseHandle(CurrentProcessToken);
|
||||||
|
if (!Ret)
|
||||||
|
goto cleanup;
|
||||||
|
if (EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))
|
||||||
|
return TRUE;
|
||||||
|
Ret = LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid);
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (!Ret)
|
||||||
|
goto cleanup;
|
||||||
|
ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (ProcessSnapshot == INVALID_HANDLE_VALUE)
|
||||||
|
goto cleanup;
|
||||||
|
for (Ret = Process32FirstW(ProcessSnapshot, &ProcessEntry); Ret;
|
||||||
|
Ret = Process32NextW(ProcessSnapshot, &ProcessEntry))
|
||||||
|
{
|
||||||
|
if (_wcsicmp(ProcessEntry.szExeFile, L"winlogon.exe"))
|
||||||
|
continue;
|
||||||
|
RevertToSelf();
|
||||||
|
Ret = ImpersonateSelf(SecurityImpersonation);
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (!Ret)
|
||||||
|
continue;
|
||||||
|
Ret = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken);
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (!Ret)
|
||||||
|
continue;
|
||||||
|
Ret = AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
|
||||||
|
LastError = GetLastError();
|
||||||
|
CloseHandle(ThreadToken);
|
||||||
|
if (!Ret)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
WinlogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessEntry.th32ProcessID);
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (!WinlogonProcess)
|
||||||
|
continue;
|
||||||
|
Ret = OpenProcessToken(WinlogonProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &WinlogonToken);
|
||||||
|
LastError = GetLastError();
|
||||||
|
CloseHandle(WinlogonProcess);
|
||||||
|
if (!Ret)
|
||||||
|
continue;
|
||||||
|
Ret = DuplicateToken(WinlogonToken, SecurityImpersonation, &DuplicatedToken);
|
||||||
|
LastError = GetLastError();
|
||||||
|
CloseHandle(WinlogonToken);
|
||||||
|
if (!Ret)
|
||||||
|
continue;
|
||||||
|
if (!GetTokenInformation(DuplicatedToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes))
|
||||||
|
goto next;
|
||||||
|
if (SetLastError(ERROR_ACCESS_DENIED), !EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))
|
||||||
|
goto next;
|
||||||
|
if (!SetThreadToken(NULL, DuplicatedToken))
|
||||||
|
goto next;
|
||||||
|
CloseHandle(DuplicatedToken);
|
||||||
|
CloseHandle(ProcessSnapshot);
|
||||||
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
return TRUE;
|
||||||
|
next:
|
||||||
|
LastError = GetLastError();
|
||||||
|
CloseHandle(DuplicatedToken);
|
||||||
|
}
|
||||||
|
RevertToSelf();
|
||||||
|
CloseHandle(ProcessSnapshot);
|
||||||
|
cleanup:
|
||||||
|
SetLastError(LastError);
|
||||||
|
return FALSE;
|
||||||
|
}
|
9
api/elevate.h
Normal file
9
api/elevate.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
ElevateToSystem(void);
|
@ -8,6 +8,7 @@
|
|||||||
#include "adapter.h"
|
#include "adapter.h"
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
#include "elevate.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "namespace.h"
|
#include "namespace.h"
|
||||||
#include "nci.h"
|
#include "nci.h"
|
||||||
|
@ -56,101 +56,6 @@ ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_ const WCHAR *LogLine)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
|
||||||
ElevateToSystem(void)
|
|
||||||
{
|
|
||||||
HANDLE CurrentProcessToken, ThreadToken, ProcessSnapshot, WinlogonProcess, WinlogonToken, DuplicatedToken;
|
|
||||||
PROCESSENTRY32W ProcessEntry = { .dwSize = sizeof(PROCESSENTRY32W) };
|
|
||||||
BOOL Ret;
|
|
||||||
DWORD LastError = ERROR_SUCCESS;
|
|
||||||
TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } };
|
|
||||||
CHAR LocalSystemSid[0x400];
|
|
||||||
DWORD RequiredBytes = sizeof(LocalSystemSid);
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
TOKEN_USER MaybeLocalSystem;
|
|
||||||
CHAR LargeEnoughForLocalSystem[0x400];
|
|
||||||
} TokenUserBuffer;
|
|
||||||
|
|
||||||
Ret = CreateWellKnownSid(WinLocalSystemSid, NULL, &LocalSystemSid, &RequiredBytes);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (!Ret)
|
|
||||||
goto cleanup;
|
|
||||||
Ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (!Ret)
|
|
||||||
goto cleanup;
|
|
||||||
Ret =
|
|
||||||
GetTokenInformation(CurrentProcessToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
|
|
||||||
LastError = GetLastError();
|
|
||||||
CloseHandle(CurrentProcessToken);
|
|
||||||
if (!Ret)
|
|
||||||
goto cleanup;
|
|
||||||
if (EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))
|
|
||||||
return TRUE;
|
|
||||||
Ret = LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (!Ret)
|
|
||||||
goto cleanup;
|
|
||||||
ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (ProcessSnapshot == INVALID_HANDLE_VALUE)
|
|
||||||
goto cleanup;
|
|
||||||
for (Ret = Process32FirstW(ProcessSnapshot, &ProcessEntry); Ret;
|
|
||||||
Ret = Process32NextW(ProcessSnapshot, &ProcessEntry))
|
|
||||||
{
|
|
||||||
if (_wcsicmp(ProcessEntry.szExeFile, L"winlogon.exe"))
|
|
||||||
continue;
|
|
||||||
RevertToSelf();
|
|
||||||
Ret = ImpersonateSelf(SecurityImpersonation);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (!Ret)
|
|
||||||
continue;
|
|
||||||
Ret = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (!Ret)
|
|
||||||
continue;
|
|
||||||
Ret = AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
|
|
||||||
LastError = GetLastError();
|
|
||||||
CloseHandle(ThreadToken);
|
|
||||||
if (!Ret)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
WinlogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessEntry.th32ProcessID);
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (!WinlogonProcess)
|
|
||||||
continue;
|
|
||||||
Ret = OpenProcessToken(WinlogonProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &WinlogonToken);
|
|
||||||
LastError = GetLastError();
|
|
||||||
CloseHandle(WinlogonProcess);
|
|
||||||
if (!Ret)
|
|
||||||
continue;
|
|
||||||
Ret = DuplicateToken(WinlogonToken, SecurityImpersonation, &DuplicatedToken);
|
|
||||||
LastError = GetLastError();
|
|
||||||
CloseHandle(WinlogonToken);
|
|
||||||
if (!Ret)
|
|
||||||
continue;
|
|
||||||
if (!GetTokenInformation(DuplicatedToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes))
|
|
||||||
goto next;
|
|
||||||
if (SetLastError(ERROR_ACCESS_DENIED), !EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))
|
|
||||||
goto next;
|
|
||||||
if (!SetThreadToken(NULL, DuplicatedToken))
|
|
||||||
goto next;
|
|
||||||
CloseHandle(DuplicatedToken);
|
|
||||||
CloseHandle(ProcessSnapshot);
|
|
||||||
SetLastError(ERROR_SUCCESS);
|
|
||||||
return TRUE;
|
|
||||||
next:
|
|
||||||
LastError = GetLastError();
|
|
||||||
CloseHandle(DuplicatedToken);
|
|
||||||
}
|
|
||||||
RevertToSelf();
|
|
||||||
CloseHandle(ProcessSnapshot);
|
|
||||||
cleanup:
|
|
||||||
SetLastError(LastError);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int Argc;
|
static int Argc;
|
||||||
static WCHAR **Argv;
|
static WCHAR **Argv;
|
||||||
|
|
||||||
@ -159,13 +64,11 @@ Init(void)
|
|||||||
{
|
{
|
||||||
WintunSetLogger(ConsoleLogger);
|
WintunSetLogger(ConsoleLogger);
|
||||||
Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
|
Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
|
||||||
ElevateToSystem();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Done(void)
|
Done(void)
|
||||||
{
|
{
|
||||||
RevertToSelf();
|
|
||||||
LocalFree(Argv);
|
LocalFree(Argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,13 +78,19 @@ WintunStartSession(_In_ const WINTUN_ADAPTER *Adapter, _In_ DWORD Capacity, _Out
|
|||||||
Result = LOG_LAST_ERROR(L"Failed to allocate ring memory");
|
Result = LOG_LAST_ERROR(L"Failed to allocate ring memory");
|
||||||
goto cleanupRings;
|
goto cleanupRings;
|
||||||
}
|
}
|
||||||
|
if (!ElevateToSystem())
|
||||||
|
{
|
||||||
|
LOG(WINTUN_LOG_ERR, L"Failed to impersonate SYSTEM user");
|
||||||
|
Result = ERROR_ACCESS_DENIED;
|
||||||
|
goto cleanupAllocatedRegion;
|
||||||
|
}
|
||||||
(*Session)->Descriptor.Send.RingSize = RingSize;
|
(*Session)->Descriptor.Send.RingSize = RingSize;
|
||||||
(*Session)->Descriptor.Send.Ring = (TUN_RING *)AllocatedRegion;
|
(*Session)->Descriptor.Send.Ring = (TUN_RING *)AllocatedRegion;
|
||||||
(*Session)->Descriptor.Send.TailMoved = CreateEventW(SecurityAttributes, FALSE, FALSE, NULL);
|
(*Session)->Descriptor.Send.TailMoved = CreateEventW(SecurityAttributes, FALSE, FALSE, NULL);
|
||||||
if (!(*Session)->Descriptor.Send.TailMoved)
|
if (!(*Session)->Descriptor.Send.TailMoved)
|
||||||
{
|
{
|
||||||
Result = LOG_LAST_ERROR(L"Failed to create send event");
|
Result = LOG_LAST_ERROR(L"Failed to create send event");
|
||||||
goto cleanupAllocatedRegion;
|
goto cleanupToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*Session)->Descriptor.Receive.RingSize = RingSize;
|
(*Session)->Descriptor.Receive.RingSize = RingSize;
|
||||||
@ -104,18 +110,19 @@ WintunStartSession(_In_ const WINTUN_ADAPTER *Adapter, _In_ DWORD Capacity, _Out
|
|||||||
}
|
}
|
||||||
DWORD BytesReturned;
|
DWORD BytesReturned;
|
||||||
if (!DeviceIoControl(
|
if (!DeviceIoControl(
|
||||||
(*Session)->Handle,
|
(*Session)->Handle,
|
||||||
TUN_IOCTL_REGISTER_RINGS,
|
TUN_IOCTL_REGISTER_RINGS,
|
||||||
&(*Session)->Descriptor,
|
&(*Session)->Descriptor,
|
||||||
sizeof(TUN_REGISTER_RINGS),
|
sizeof(TUN_REGISTER_RINGS),
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&BytesReturned,
|
&BytesReturned,
|
||||||
NULL))
|
NULL))
|
||||||
{
|
{
|
||||||
Result = LOG_LAST_ERROR(L"Failed to perform ioctl");
|
Result = LOG_LAST_ERROR(L"Failed to perform ioctl");
|
||||||
goto cleanupHandle;
|
goto cleanupHandle;
|
||||||
}
|
}
|
||||||
|
RevertToSelf();
|
||||||
(*Session)->Capacity = Capacity;
|
(*Session)->Capacity = Capacity;
|
||||||
(void)InitializeCriticalSectionAndSpinCount(&(*Session)->Receive.Lock, LOCK_SPIN_COUNT);
|
(void)InitializeCriticalSectionAndSpinCount(&(*Session)->Receive.Lock, LOCK_SPIN_COUNT);
|
||||||
(void)InitializeCriticalSectionAndSpinCount(&(*Session)->Send.Lock, LOCK_SPIN_COUNT);
|
(void)InitializeCriticalSectionAndSpinCount(&(*Session)->Send.Lock, LOCK_SPIN_COUNT);
|
||||||
@ -126,6 +133,8 @@ cleanupReceiveTailMoved:
|
|||||||
CloseHandle((*Session)->Descriptor.Receive.TailMoved);
|
CloseHandle((*Session)->Descriptor.Receive.TailMoved);
|
||||||
cleanupSendTailMoved:
|
cleanupSendTailMoved:
|
||||||
CloseHandle((*Session)->Descriptor.Send.TailMoved);
|
CloseHandle((*Session)->Descriptor.Send.TailMoved);
|
||||||
|
cleanupToken:
|
||||||
|
RevertToSelf();
|
||||||
cleanupAllocatedRegion:
|
cleanupAllocatedRegion:
|
||||||
VirtualFree(AllocatedRegion, 0, MEM_RELEASE);
|
VirtualFree(AllocatedRegion, 0, MEM_RELEASE);
|
||||||
cleanupRings:
|
cleanupRings:
|
||||||
@ -137,7 +146,7 @@ cleanupRings:
|
|||||||
void WINAPI
|
void WINAPI
|
||||||
WintunEndSession(_In_ TUN_SESSION *Session)
|
WintunEndSession(_In_ TUN_SESSION *Session)
|
||||||
{
|
{
|
||||||
SetEvent(Session->Descriptor.Send.TailMoved); // wake the reader if it's sleeping
|
SetEvent(Session->Descriptor.Send.TailMoved); // Wake the reader if it's sleeping.
|
||||||
DeleteCriticalSection(&Session->Send.Lock);
|
DeleteCriticalSection(&Session->Send.Lock);
|
||||||
DeleteCriticalSection(&Session->Receive.Lock);
|
DeleteCriticalSection(&Session->Receive.Lock);
|
||||||
CloseHandle(Session->Handle);
|
CloseHandle(Session->Handle);
|
||||||
|
Loading…
Reference in New Issue
Block a user