使用 CreateProcessWithTokenW 在 CMD 中启动 CMD

Start CMD in CMD with CreateProcessWithTokenW

本文关键字:CMD 启动 CreateProcessWithTokenW 使用      更新时间:2023-10-16

我有一个控制台应用程序,它调用CreateProcessWithTokenW()WinAPI函数来创建启动cmd控制台的新进程。通过调用它,它会启动一个新的CMD窗口。我想在调用 cmd 窗口中生成另一个 cmd(而不是在新窗口中(。

所以我想模拟相同的行为,就像你启动cmd并键入"cmd"一样。

ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\Windows\System32\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

这是一个最小的可重现代码片段。 我添加了 CreateProcess 而不是 CreateProcessWithToken。如果我为第 5 个参数 (dwCreationFlag( 定义 0,那么它会在 Powershell 中启动 CMD。但是对于CreateProcessWithToken,行为是不一样的。

使用提升的电源外壳运行此代码(因为它需要Se_Debug_Priv(

#include <stdio.h> 
#include <Windows.h> 
#include <WinBase.h> 
#include <iostream> 
#include <tchar.h> 
int main() {
//DEFINE HERE PID OF winlogon.exe
DWORD pid = 940;
HANDLE currentProcess = {};
HANDLE AccessToken = {};
currentProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, pid);
OpenProcessToken(currentProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY, &AccessToken);
HANDLE pToken = AccessToken;
SECURITY_IMPERSONATION_LEVEL seImpersonateLevel = SecurityImpersonation;
TOKEN_TYPE tokenType = TokenPrimary;
HANDLE pNewToken = new HANDLE;
DuplicateTokenEx(pToken, MAXIMUM_ALLOWED, NULL, seImpersonateLevel, tokenType, &pNewToken);
STARTUPINFO si = {};
PROCESS_INFORMATION pi = {};
//TEST1
//Creates a new window for both functions so the 5th seems to be ignored 
CreateProcessWithTokenW(pNewToken, 0, L"C:\Windows\System32\cmd.exe", NULL, 0, NULL, NULL, &si, &pi);
CreateProcessWithTokenW(pNewToken, 0, L"cmds.bat", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
//TEST2
//Create a new windows, assumed behavior
CreateProcessW(L"C:\Windows\System32\cmd.exe", NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
//Creates also a new window, NOT assumed behavior
CreateProcessW(L"C:\Windows\System32\cmd.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
return 0;
}

去掉CREATE_NEW_CONSOLE标志:


CREATE_NEW_CONSOLE 0x00000010

新进程具有新的控制台,而不是继承父进程的控制台。此标志不能与DETACHED_PROCESS标志一起使用。

默认情况下启用此标志。

该闪存是强制创建新的CMD窗口的原因。否则,将在调用进程的现有CMD窗口中创建新进程。

就我而言,您应该使用CREATE_NEW_CONSOLE.根据代码:

ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\Windows\System32\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

问题不在于使用CreateProcessWithTokenW ()winapi。您能否向我们提供一个最小的可重现示例来重现该问题。

这是代码:

STARTUPINFOEX startup_info = {};
PROCESS_INFORMATION process_info = {};
BOOL CreateProcTokenRes = FALSE;
CreateProcTokenRes = CreateProcessWithTokenW(NewToken, 0, L"C:\Windows\system32\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &process_info);
if (!CreateProcTokenRes)
{
_tprintf(L"Cannot Create Process With Token. Failed with Error Code: %dn", GetLastError());
CloseHandle(NewToken);

有关更多详细信息,我建议您参考链接:https://niiconsulting.com/checkmate/2019/11/token-manipulation-attacks-part-2-process-of-impersonation/