【问题标题】:Start CMD in CMD with CreateProcessWithTokenW在 CMD 中使用 CreateProcessWithTokenW 启动 CMD
【发布时间】: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);

【问题讨论】:

标签: c++ c visual-studio


【解决方案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 似乎忽略了这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多