简体   繁体   English

在系统上下文中运行进程

[英]Running Process in system context

Is it possible to launch process in system context from a parent process thats running under administrator account with elevation(say a command prompt).是否可以从在具有提升权限的管理员帐户下运行的父进程在系统上下文中启动进程(比如命令提示符)。 The problem is similar to what psexec does but more of how it actually implements this.这个问题类似于 psexec 所做的,但更多的是它如何实际实现它。

I was thinking opening the crss.exe/winlogon.exe process duplicating the token and launching a new process using that process token.我正在考虑打开 crss.exe/winlogon.exe 进程复制令牌并使用该进程令牌启动新进程。 But I fail to even open the process handle (Getlasterror return 5).但我什至无法打开进程句柄(Getlasterror 返回 5)。 Can someone let me know if this is the right approach or the process should be launched differently?有人可以告诉我这是正确的方法还是应该以不同的方式启动流程?

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;
    }
}

I am sure its possible as there is a working tool (psexec) but I couldnt find any reference online to do this.我确信这是可能的,因为有一个可用的工具 (psexec),但我无法在网上找到任何参考资料来执行此操作。

Also this is similar to question , but posting separately as there was details on how it had to be achieved.这也类似于问题,但单独发布,因为有关于如何实现它的详细信息。

Yes, this is possible (without any service help). 是的,这是可能的(没有任何服务帮助)。

But I fail to even open the process handle 但是我什至没有打开流程句柄

Does your process have the SE_DEBUG_PRIVILEGE privilege enabled? 您的进程是否启用了SE_DEBUG_PRIVILEGE特权?

With this privilege, you can open a system process with all access if it is not protected (smss.exe, csrss.exe, services.exe), and use that handle in CreateProcessAsUser (), or with UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS) if you also have SE_ASSIGNPRIMARYTOKEN_PRIVILEGE and SE_TCB_PRIVILEGE privileges enabled (for setting the token's SessionId to 0), which you can get in 2 ways: 拥有此特权,如果未受保护(smss.exe,csrss.exe,services.exe),则可以打开具有所有访问权限的系统进程,并在CreateProcessAsUser ()中使用该句柄,或者在还具有UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS)情况下使用启用了SE_ASSIGNPRIMARYTOKEN_PRIVILEGESE_TCB_PRIVILEGE特权(用于将令牌的SessionId设置为0),您可以通过两种方式获得特权:

  • open a thread from an unprotected system process and impersonate it, then open your own thread token and adjust privileges on it. 从不受保护的系统进程中打开线程并进行模拟,然后打开自己的线程令牌并调整其特权。

  • open a token from any system process (this works even for protected processes), duplicate the token, adjust privileges on it, and then impersonate with this token. 从任何系统进程中打开一个令牌(即使对于受保护的进程也是如此),复制该令牌,调整其特权,然后使用该令牌进行模拟。

To "launch a process in the system context", if you want to run the process: 如果要运行进程,请“在系统上下文中启动进程”:

  • with the LocalSystem token. 使用LocalSystem令牌。

  • in the System terminal session (0) 在系统终端会话中(0)

Both, as I say, are possible. 正如我所说,两者都是可能的。 And all you need is SE_DEBUG_PRIVILEGE . 您只需要SE_DEBUG_PRIVILEGE

  1. more simply - open some system process with PROCESS_CREATE_PROCESS access right. 更简单-使用PROCESS_CREATE_PROCESS访问权限打开某些系统进程。 Use this handle with UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS) . 将此句柄与UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS) As a result, your started process inherits a token from the system process. 结果,您启动的进程从系统进程继承了一个令牌。 This will be not work on XP, but there it is possible to hook NtCreateProcess/Ex() to replace HANDLE ParentProcess with your opened handle. 这在XP上将不起作用,但是可以钩住NtCreateProcess/Ex()以用打开的句柄替换HANDLE ParentProcess

  2. Another way is to use CreateProcessAsUser() . 另一种方法是使用CreateProcessAsUser() Before creating the process, you will be need SE_ASSIGNPRIMARYTOKEN_PRIVILEGE and SE_TCB_PRIVILEGE privileges to set the token's TokenSessionId (if you want to run in session 0). 在创建流程之前,您将需要SE_ASSIGNPRIMARYTOKEN_PRIVILEGESE_TCB_PRIVILEGE特权来设置令牌的TokenSessionId (如果要在会话0中运行)。

Thanks to RbMm answer I figured a way to accomplish this task.感谢 RbMm 的回答,我想出了一种方法来完成这项任务。

For any of you who did not succeed, I leave below something that might help:对于任何没有成功的人,我在下面留下一些可能有帮助的东西:

//First we need to add debug privilege to this process
HANDLE hToken;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
    &hToken))
{
    std::cout << "OpenProcessToken failed: " << GetLastError();
    return 0;
}

TOKEN_PRIVILEGES tk;
tk.PrivilegeCount = 1;
tk.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tk.Privileges[0].Luid))
{
    std::cout << "LookupPrivilegeValue failed: " << GetLastError();
    return 0;
}

AdjustTokenPrivileges(hToken, FALSE, &tk, 0, NULL, 0);
if((DWORD res = GetLastError()) != ERROR_SUCCESS)
{
    std::cout << "AdjustTokenPrivileges failed: " << res;
}

CloseHandle(hToken);

//Now we need a handle to a process that already runs as SYSTEM.
//You can choose any process that is not protected (if OpenProcess fails try with other process)

//pid of chosen process (you can get this by opening task manager and go to
//Details tab or by enumerating all processes and extract that one you need)
DWORD pid;
HANDLE hProcess = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid);
if (!hProcess)
{
    std::cout << "OpenProcess with pid " << pid << "failed: " << GetLastError();
    return 0
}

//We need to initialize a list that contains PROC_THREAD_ATTRIBUTE_PARENT_PROCESS 
//to specify that parent process of the process we are going to start is the 
//process we opened earlier (this will make the child process inherit the system context).
//This list will be specified in a STARTUPINFOEX object that CreateProcess will get
STARTUPINFOEX siex = { sizeof(STARTUPINFOEX) };
siex.StartupInfo.cb = sizeof(STARTUPINFOEXW);

//We need to initialize our list. To do this we call InitializeProcThreadAttributeList 
//with a NULL list to get how big our list needs to be to store all attributes 
//we want to specify, then we allocate our list with the size we got from first call 
//and we call again the function to initialize the list.
SIZE_T cbAttributeListSize = 0;
if(!InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize))
{
    std::cout << "InitializeProcThreadAttributeList failed: " << GetLastError();
    return 0
}

siex.lpAttributeList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize));
if(!InitializeProcThreadAttributeList(siex.lpAttributeList, 1, 0, &cbAttributeListSize))
{
    std::cout << "InitializeProcThreadAttributeList failed: " << GetLastError();
    return 0
}

if(!UpdateProcThreadAttribute(siex.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProcess, sizeof(hProcess), NULL, NULL))
{
    std::cout << "UpdateProcThreadAttribute failed: " << GetLastError();
    return 0
}

//path to program we want to run in system context
LPWSTR szCmdline = _wcsdup(TEXT("C:\\Windows\\System32\\notepad.exe"));
PROCESS_INFORMATION pi = { 0 };

if(!CreateProcess(NULL, szCmdline, nullptr, nullptr, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, reinterpret_cast<LPSTARTUPINFOW>(&siex), &pi))
{
    std::cout << "CreateProcess failed: " << GetLastError();
    return 0
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何停止在其他系统的Shell中运行的进程? - How to stop a process running in a shell in a different system? 在虚拟文件系统中运行进程? - Running a process inside a virtual file system? Windows 7或Windows 2008如何在本地系统帐户或系统上下文中启动进程(通过桌面应用程序) - Windows 7 or Windows 2008 how to launch a process in Local System Account or System Context (from desktop aplication) 我的进程正在运行时,SYSTEM_INFO :: dwActiveProcessorMask可以更改吗? - Can SYSTEM_INFO::dwActiveProcessorMask change while my process is running? 使用SYSTEM级别进程(Windows Service)中已登录的用户上下文模拟并运行任何方法: - Impersonate and run any method using a logged in user context from SYSTEM level process (Windows Service): 获取系统(上下文)菜单 - Get system (context) menu 在父级获得终止信号并退出后,使使用system()生成的子进程继续运行 - Make child process spawned with system() keep running after parent gets kill signals and exits 如何使用编程方式拦截在Linux上正在运行的进程中调用的系统调用? - how to use programming way to intercept system calls invoked in a running process on linux? 如何从以 SYSTEM 身份运行的进程中可靠地获取登录用户名/sid? - How to reliably get LOGON USER name/sid from a process running as SYSTEM? 作为本地系统运行进程 - Run process as Local System
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM