【发布时间】:2016-08-30 22:31:33
【问题描述】:
是否可以从在管理员帐户下运行的父进程在系统上下文中启动进程并提升权限(比如命令提示符)。这个问题与 psexec 所做的类似,但更多的是它实际上是如何实现的。
我正在考虑打开 crss.exe/winlogon.exe 进程以复制令牌并使用该进程令牌启动一个新进程。但我什至无法打开进程句柄(Getlasterror return 5)。有人可以告诉我这是正确的方法还是应该以不同的方式启动流程?
HANDLE hWinLogonProcess;
for(const auto& ps : running_processes)
{
if(ps.id == GetCurrentProcessId() ||
0 != ps.short_name.CompareNoCase(L"winlogon.exe"))
{
continue;
}
DWORD dwWinLogonSessionId(0);
if(FALSE == ProcessIdToSessionId(GetCurrentProcessId(), &dwWinLogonSessionId))
{
std::wcerr<<"Could not get Winlogon process session id"<<std::endl;
continue;
}
if(dwWinLogonSessionId != dwCurSessionId)
{
continue;
}
hWinLogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ps.id);
if(FALSE == hWinLogonProcess)
{
std::wcerr<<"Failed to get winlogon process handle"<<std::endl;
return;
}
else
{
std::wcout<<"Able to open process "<<ps.short_name.GetString()<<" handle"<<std::endl;
break;
}
}
我相信这是可能的,因为有一个工作工具 (psexec),但我在网上找不到任何参考资料。
这也类似于question,但单独发布,因为有关于如何实现它的详细信息。
【问题讨论】:
-
见how psexec works。简而言之,psexec 以管理员用户身份登录并安装并运行一个临时服务以获得系统访问权限,然后该服务运行该命令,然后 psexec 停止并卸载该服务。 psexec 使用管道在自己和服务之间交换输入/输出,服务使用管道与运行命令交换输入/输出。
-
感谢@RemyLebeau,我看到 psexec 创建了一个服务来实现这一点。但是我有一个 dll,不想为此引入一个新的 exe。是否有可能以编程方式实现这一目标。由于我当前的进程已经以管理员权限运行。
-
只有服务才能获得系统权限,只有管理员才能安装服务。您不能将 DLL 作为服务直接运行(除非它是驱动程序),但您也不需要编写单独的 EXE。您可以 1) 将 DLL 设计为可从
Rundll32调用,然后将该 EXE 用作服务,或者 2) 将您的主 EXE 安装为具有命令行参数的服务,然后添加相关的服务 API 调用当 EXE 使用该参数运行时,您的WinMain()函数,并让您的“服务”根据需要使用 DLL。 -
@RemyLebeau - “只有服务才能获得系统特权” - 这不是真的 - 真的是任何拥有 SE_DEBUG_PRIVILEGE 的人。如果有这个,我们可以使用 PROCESS_QUERY_LIMITED_INFORMATION 打开任何进程(甚至受保护),然后打开它的令牌,复制它并分配给我们的线程。不需要任何服务
-
@user3279954 - 是的,这是可能的,我什至有专门的工具
标签: c++ windows winapi win32gui