Start CMD in CMD with CreateProcessWithTokenW - c++

I have a console application which calls the CreateProcessWithTokenW() WinAPI function to create a new process which starts a cmd console. By calling it, it starts a new CMD Window. I want to spawn another cmd within the calling cmd window (not in a new window).
So I want to simulate the same behavior like if you start cmd and type "cmd".
ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

Here is a minimal reproducible code snippet.
I added CreateProcess instead of CreateProcessWithToken....if i define 0 for 5th argument (dwCreationFlag) than it starts the CMD in the Powershell. But for CreateProcessWithToken the behavior is not the same.
Run this code with a elevated powershell (because it needs 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;
}

Get rid of the CREATE_NEW_CONSOLE flag:
CREATE_NEW_CONSOLE
0x00000010
The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS flag.
This flag is enabled by default.
That flash is what is forcing a new CMD window to be created. Without that, the new process will be created in the existing CMD window of the calling process.

As far as I'm concerned, you should use CREATE_NEW_CONSOLE. According to the code:
ret = CreateProcessWithTokenW(pNewToken, 0, L"C:\\Windows\\System32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
The problem is not with the use of CreateProcessWithTokenW () winapi. Could you please provide us with a minimal reproducible exampleto reproduce the issue.
Here is the code:
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);
For more details I suggest you could refer to the link:https://niiconsulting.com/checkmate/2019/11/token-manipulation-attacks-part-2-process-of-impersonation/

Related

Parent process hangs when calling CreateProcess() in MFC

My code is,
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
info.dwFlags = STARTF_USESHOWWINDOW;
info.wShowWindow = TRUE;
if (CreateProcess("My_program.exe", command, NULL, NULL, TRUE,
CREATE_NEW_CONSOLE, NULL, NULL, &info, &processInfo))
{
WaitForSingleObject(processInfo.hProcess, INFINITE);
GetExitCodeProcess(processInfo.hProcess, &exit_code);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
When i call this function CreateProcess(), My_program.exe invokes and runs.
But my MFC Diolog box gets hang and it shows not responding. Can anyone please help me to avoid this.

Handle firefox error message “Cannot load XPCOM” using C++

I'm trying to open Mozilla Firefox using CreateProcess(). However, If Firefox is auto updating while I try to open it, I get the following error message:
Cannot load XPCOM
And I need to restart the application.
Here is the code I'm using:
path = MozillaExePath.c_str();
STARTUPINFO info = { sizeof(STARTUPINFO), NULL, NULL, "FireFox", 0,0,800, 600, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL };
PROCESS_INFORMATION processInfo;
if (CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
WaitForSingleObject(processInfo.hProcess, 3000);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
else
{
WriteLogFile("May be error with mozilla firefox...\n");
exit(1);
}
So, how can I handle that error message using C++?
Here is a different way to do this that is working for me:
#include <shellapi.h>
[...]
if (ShellExecute(NULL, TEXT("open"), TEXT("firefox.exe"), NULL, NULL, 0) <= HINSTANCE(32))
{
WriteLogFile("Could not open Mozilla Firefox...\n");
}
Reference:
https://learn.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-shellexecutea

Redirecting CreateProcess input stream to a file

I'm using CreateProcess to substitute a system() call in my code. I was using:
system(xfoil.exe < create_results.txt");
Which I am substituing by this:
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
LPCWSTR input_file = _tcsdup(TEXT(".\\create_results.txt"));
HANDLE inpfl = CreateFile(input_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
StartupInfo.hStdInput = inpfl;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo; //Only compulsory field
LPCWSTR exe_path =_tcsdup(TEXT(".\\xfoil.exe"));
if (CreateProcess(exe_path, NULL,
NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL,
NULL, &StartupInfo, &ProcessInfo))
{
WaitForSingleObject(&ProcessInfo.hProcess, 2000);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(inpfl);
}
else
{
CloseHandle(inpfl);
std::cout << "Could not create xfoil process" << std::endl;
}
The reason being I need to control how long the process is allowed to run ( 2000ms in this case), however it seems that this method does not work.
I'm redirecting the input of the process to the handle of the file I want as input (to substitute the < operator), but the process is not receiving anything. It does launch the xfoil.exe in a separate console, though.
You need to set file security attributes to allow handle to be inherited and startup info flag to make child process use the handle passed:
::STARTUPINFO startup_information{};
::SECURITY_ATTRIBUTES security_attributes
{
sizeof(::SECURITY_ATTRIBUTES)
, nullptr
, TRUE // allow handle to be inherited
};
::HANDLE const inpfl{::CreateFileW(input_file, GENERIC_READ, FILE_SHARE_READ, ::std::addressof(security_attributes), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)};
if(INVALID_HANDLE_VALUE == inpfl)
{
auto const last_error{::GetLastError()};
// handle error...
}
startup_information.cb = sizeof(startup_information);
startup_information.dwFlags = STARTF_USESTDHANDLES;
startup_information.hStdInput = inpfl;
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
LPCWSTR input_file = _tcsdup(TEXT(".\\create_results.txt"));
HANDLE inpfl = CreateFile(input_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
StartupInfo.hStdInput = inpfl;
What happens to StartupInfo.hStdInput after the next call?
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
Oops... hStdInput zeroed now
Doing this initially...
PROCESS_INFORMATION ProcessInfo = {};
STARTUPINFO StartupInfo = {};
... will prevent you from needing to zero anything... see
Also, according to CreateProcess StartupInfo documentation, you have to, for hStdInput, set dwFlags to STARTF_USESTDHANDLES, else the default input is the keyboard buffer

MFC Command Window Command

In MFC I want to Create a process by opening Command Window and executing a command in that say open notepad.
i Found this tried it didn't work
STARTUPINFO sInfo = {0};
sInfo.cb = sizeof(sInfo);
PROCESS_INFORMATION pInfo = {0};
CreateProcess("C:\\WINDOWS\\System32\\cmd.exe",""0,0,TRUE,
NORMAL_PRIORITY_CLASS,0,0,&sInfo,&pInfo);
You're not telling cmd to do anything. Try this:
CreateProcess(0, "C:\\WINDOWS\\System32\\cmd.exe /c notepad.exe", 0, 0, TRUE, 0, 0, 0, &sInfo, &pInfo);
But maybe this is easier
ShellExecute(0, "open", "cmd.exe", "/C notepad.exe", 0, SW_HIDE);
Or even this:
system("notepad.exe");
Go to the MSDN document we can see, you don't specify the second parameter that is the command line to excute.
On the other hand, there are no NORMAL_PRIORITY_CLASS enum item for the sixth parameter. You should do like this:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = TRUE;
TCHAR cmdline[] =TEXT(" notepad.exe");
BOOL bRet = ::CreateProcess (
TEXT("C:\\WINDOWS\\System32\\cmd.exe"),
cmdline,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);

How to hide Matlab Command Window and command prompt from calling system in C++

I execute the Matlab script file using system() which uses the command prompt and it's working fine. But i wish to hide everything and hope it runs in the background and only showing my GUI from the script file. Any idea?
This is my command in MSVS C++ (Note : i cut short the path name for simplicity purposes) :
system("\"\"C:\\matlab.exe\" -nodisplay -nosplash -nodesktop -r \"run('C:\\main.m');\"\"");
You could try CreateProcess instead of system. A simple example:
#include <windows.h>
#include <stdio.h>
int main() {
PROCESS_INFORMATION pi;
STARTUPINFO si = {
sizeof(si),
NULL, NULL, NULL,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL
};
BOOL res = CreateProcess(
NULL,
"C:\\matlab.exe -nodisplay -nosplash -nodesktop -r \"run('C:\\main.m');\"",
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL,
NULL, // starting directory (NULL means same dir as parent)
&si, &pi
);
if (res == FALSE) printf("CreateProcess failed\n");
return 0;
}
You might be better off using the MATLAB Engine API.