在 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, &amp;si, &amp;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的主要内容,如果未能解决你的问题,请参考以下文章

在 CMD 中使用环境变量

如何在cmd中使用输入

如何使用 CreateProcess 在 cmd 中执行命令?

在 prepareStatement 中使用 COALESCE 来“插入”cmd

cmd中怎么调用python脚本?

如何使用c#在cmd中运行命令[重复]