在 CMD 中使用 CreateProcessWithTokenW 启动 CMD
Posted
技术标签:
【中文标题】在 CMD 中使用 CreateProcessWithTokenW 启动 CMD【英文标题】:Start CMD in CMD with CreateProcessWithTokenW 【发布时间】:2020-01-07 15:57:58 【问题描述】:我有一个控制台应用程序,它调用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 函数和 CREATE_NEW_CONSOLE 来创建一个带有新控制台的控制台进程。 更多细节我建议你可以参考链接:Creation of a Console .这是一个类似的问题:***.com/questions/20692490/… 【参考方案1】:这是一个最小的可重现代码sn-p。 我添加了 CreateProcess 而不是 CreateProcessWithToken ....如果我为第 5 个参数 (dwCreationFlag) 定义 0,那么它将在 Powershell 中启动 CMD。但是对于 CreateProcessWithToken,行为就不一样了。
使用提升的 powershell 运行此代码(因为它需要 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;
【讨论】:
【参考方案2】:去掉CREATE_NEW_CONSOLE
标志:
CREATE_NEW_CONSOLE 0x00000010
新进程有一个新的控制台,而不是继承父级的控制台。该标志不能与 DETACHED_PROCESS 标志一起使用。
此标志默认启用。
闪存是强制创建新 CMD 窗口的原因。没有它,新进程将在调用进程的现有 CMD 窗口中创建。
【讨论】:
ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, NULL, &si, &pi);或 ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, 0, NULL, NULL, &si, &pi);具有与 CREATE_NEW_CONSOLE 标志相同的行为。【参考方案3】:就我而言,您应该使用CREATE_NEW_CONSOLE
。根据代码:
ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
问题不在于使用CreateProcessWithTokenW ()
winapi。您能否向我们提供minimal reproducible example以重现该问题。
代码如下:
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: %d\n", GetLastError());
CloseHandle(NewToken);
更多详情我建议你可以参考链接:https://niiconsulting.com/checkmate/2019/11/token-manipulation-attacks-part-2-process-of-impersonation/
【讨论】:
清除:我不希望 CREATE_NEW_CONSOLE 的行为......它希望它在现有/调用 cmd/powershell 中产生。我读到我必须将标志设置为 0。使用函数 CreateProcess 效果很好,但 CreateProcessWithToken 似乎忽略了这一点。以上是关于在 CMD 中使用 CreateProcessWithTokenW 启动 CMD的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 CreateProcess 在 cmd 中执行命令?