Windows高权限程序以低权限启动子进程
windows中父进程为高权限如何以低权限启动子进程,在本文中给出一种方法,供读者参考。
实现思路: 再任务管理其中找到一个低权限的程序,一般explorer.exe是以当前用户普通权限启动。我们这里使用explorer.exe为例。 首先需要根据程序名获取explorer.exe的token,并根据这个token利用DuplicateTokenEx函数复制一个新的token用于创建新的子进程。利用这个token创建新的环境变量。然后利用新的token和环境变量启动新进程就能得到和explorer.exe一样的权限了。
实现
-
获取explorer.exe的token
这个可以使用CreateToolhelp32Snapshot获取所有进程的一个快照,然后使用Process32First函数枚举所有进程并找到explorer.exe对应的HANDLE,最后利用OpenProcessToken函数获取explorer.exe的token。
-
CreateToolhelp32Snapshot函数原型
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
dwFlags 标志你要使用的是哪一个快照,这里我们使用TH32CS_SNAPPROCESS标志
th32ProcessID 使用0,指的是当前进程。
-
使用Process32FirstW函数枚举进程
BOOL Process32FirstW(
HANDLE hSnapshot,
LPPROCESSENTRY32W lppe
);
hSnapshot 为CreateToolhelp32Snapshot的返回值
lppe 为PROCESSENTRY32W结构体指针
-
Process32NextW
BOOL Process32NextW(
HANDLE hSnapshot,
LPPROCESSENTRY32W lppe
);
Process32NextW函数检索下一个进程
-
OpenProcess
HANDLE OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
);
dwProcessId 进程ID
-
OpenProcessToken
BOOL OpenProcessToken(
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle
);
OpenProcessToken 函数可以打开与进程关联的访问令牌即我们上面所说的token
ProcessHandle 为OpenProcess的返回值,其他参数可参考msdn文档
-
DuplicateTokenEx函数复制新的token
BOOL DuplicateTokenEx(
HANDLE hExistingToken,
DWORD dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpTokenAttributes,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
TOKEN_TYPE TokenType,
PHANDLE phNewToken
);
hExistingToken 已经存在的token
phNewToken 新的token
-
CreateEnvironmentBlock 创建新的环境变量
BOOL CreateEnvironmentBlock(
LPVOID *lpEnvironment,
HANDLE hToken,
BOOL bInherit
);
hToken 为DuplicateTokenEx复制的新的token即为phNewToken
-
CreateProcessAsUserW 函数使用新的token和新的环境变量创建新的进程
BOOL CreateProcessAsUserW(
HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
-
DestroyEnvironmentBlock函数销毁环境变量
BOOL DestroyEnvironmentBlock(
LPVOID lpEnvironment
);
lpEnvironment 即为CreateEnvironmentBlock函数获取的环境变量
代码
BOOL GetTokenByName1(HANDLE &hToken, const LPCWSTR proName)
{
if (proName == NULL)
{
return FALSE;
}
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32W pe32 = { 0 };
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return (FALSE);
}
pe32.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(hProcessSnap, &pe32))
{
do
{
if (0 == wcscmp(pe32.szExeFile, proName))
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
CloseHandle(hProcess);
CloseHandle(hProcessSnap);
return (bRet);
}
} while (Process32NextW(hProcessSnap, &pe32));
bRet = FALSE;
}
else
{
bRet = FALSE;
}
CloseHandle(hProcessSnap);
return (bRet);
}
BOOL CreateProcessUserMy(IN LPCWSTR pro_name, IN LPCWSTR application_name,
IN LPWSTR command_line, IN LPSECURITY_ATTRIBUTES process_attributes,
IN LPSECURITY_ATTRIBUTES thread_attributes, IN BOOL inherit_handles,
IN DWORD creation_flags, IN LPVOID environment,
IN LPCWSTR current_directory, IN LPSTARTUPINFOW startup_info,
OUT LPPROCESS_INFORMATION process_information)
{
HANDLE token = NULL;
HANDLE token_dup;
BOOL ret = FALSE;
ret = GetTokenByName1(token, pro_name);
if (token == NULL)
{
LOG_ERROR("get token == NULL");
return FALSE;
}
ret = DuplicateTokenEx(token, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary,
&token_dup);
//创建新环境变量
ret = CreateEnvironmentBlock(&environment, token_dup, FALSE);
CloseHandle(token);
if (!ret)
{
return false;
}
ret = CreateProcessAsUserW(token_dup, application_name, command_line, process_attributes,
thread_attributes, inherit_handles, creation_flags, environment,
current_directory, startup_info, process_information);
LOG_INFO("CreateProcessAsUser ret = %d", ret);
DestroyEnvironmentBlock(environment);
CloseHandle(token_dup);
return ret;
}
DWORD LaunchAppAsExplorer1(LPCWSTR lpImage, LPWSTR lpCommand)
{
STARTUPINFOW startup_info;
PROCESS_INFORMATION proc_info;
BOOL ret = FALSE;
DWORD dwPid = 0;
ZeroMemory(&startup_info, sizeof(startup_info));
startup_info.cb = sizeof(startup_info);
ZeroMemory(&proc_info, sizeof(proc_info));
startup_info.lpDesktop = L"Winsta0\\default";
ret = CreateProcessUserMy(L"explorer.exe", lpImage, lpCommand, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
NULL, NULL, &startup_info, &proc_info);
dwPid = proc_info.dwProcessId;
if (!ret)
{
proc_info.hProcess = 0;
dwPid = 0;
}
CloseHandle(proc_info.hProcess);
CloseHandle(proc_info.hThread);
return dwPid;
}
结束
欢迎关注公众号zzktkj_8888
- END -