CreateProcess API的安全问题

security issue with CreateProcess API

本文关键字:问题 安全 API CreateProcess      更新时间:2023-10-16

目标:我正在尝试将一些文件从客户端发送到服务器。我正在使用"rsync"来传输数据。我正在使用CreateProcessAPi并传递rsync路径和参数。

正案例:当我从本地驱动器发送数据时,如"C:"是我的窗口的安装位置,上述方法可以正常工作并传输数据。

问题:当我尝试发送映射驱动器(共享网络驱动器)的数据时。CreateProcess完成了,但我得到的错误是rsync找不到文件。同样的rsync命令,当我在命令提示符下运行时,所有文件都会成功传输,没有任何错误,但在使用CreateProcess传输文件时失败。

代码

int CreateRsyncProcess(const wchar_t * ptrCommand)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sap,sat,sao;
HANDLE out;
DWORD pwExit;
//init the STARTUPINFO struct
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
wstring cmd = L"";
cmd.append(ptrCommand);

//proc sec attributes
sap.nLength=sizeof(SECURITY_ATTRIBUTES);
sap.lpSecurityDescriptor= NULL;
sap.bInheritHandle=1;
//thread sec attributes
sat.nLength=sizeof(SECURITY_ATTRIBUTES);
sat.lpSecurityDescriptor= NULL;
sat.bInheritHandle=1;

//create the proc
if(!CreateProcess(NULL,(LPWSTR)cmd.c_str(),&sap,&sat,1,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
DWORD err = GetLastError();
if(out != INVALID_HANDLE_VALUE)
CloseHandle(out);
return 1;
}
//wait till the proc ends
WaitForSingleObject(pi.hProcess,INFINITE);
GetExitCodeProcess(pi.hProcess,&pwExit);
//close all
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
if(out != INVALID_HANDLE_VALUE)
CloseHandle(out);
TerminateProcess(pi.hProcess,0);

return pwExit;
}

Rsync Cmd:"C:\Program Files\cwRsync\bin\rsync.exe"-cvriHPDkREL--无隐含目录--stats-e'"C:\Program Files\cwRsync\bin \ssh"-o StrictHostKeyChecking=no-i"C:\Program Files \cwRsync\bin/rsync key"'"/cygdrive/Z/64Bit"user@server.com:~/6a90c592-2b3b-4088-8942-210677c863a/

它的发生是因为一些与安全相关的问题或CreateProcess的权限问题还是其他原因?我陷入困境,请帮帮我。

感谢

编辑::这是一个正常的进程,但当我在服务中运行它时,它会失败。所以基本上现在的问题是服务没有访问网络共享。有什么解决办法吗?

映射的驱动器是按会话的-隔离会话中的服务无法访问用户会话中的映射驱动器。您需要映射服务会话中的驱动器,或者使用UNC路径(而不是映射的驱动器号),并授予服务用户访问共享的权限。

由于显然您正在运行服务,您可能需要加载环境才能访问映射的文件夹。

像这样的东西。

DWORD dwIdCurrentSession = 0xFFFFFFFF;
WTS_SESSION_INFO* pSessionInfo = NULL;          
DWORD dwSessionsCount = 0;
if(WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwSessionsCount))
{   
for(int i=0; i<(int)dwSessionsCount; i++)
{
WTS_SESSION_INFO &si = pSessionInfo[i];
if(si.State == WTSActive)
{                                                       
dwIdCurrentSession = si.SessionId;
break;
}
}
WTSFreeMemory(pSessionInfo);    
}
if(dwIdCurrentSession != 0xFFFFFFFF)
{
HANDLE hLoggedOnUserToken = NULL;           
// Get Session User Token   
if(WTSQueryUserToken(dwIdCurrentSession, &hLoggedOnUserToken))                          
{                   
LPVOID lpEnviroment = NULL;
if(CreateEnvironmentBlock(&lpEnviroment, hLoggedOnUserToken, false))
{               
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Create Process
if(CreateProcessAsUser(hLoggedOnUserToken,
NULL,
(LPWSTR)cmd.c_str(),
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
lpEnviroment,
NULL,
&si,
&pi )
) 
{   
// Wait for finish......
// Clean up
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );                                  
}
DestroyEnvironmentBlock(lpEnviroment);
}
CloseHandle(hLoggedOnUserToken);    
}
}

您使用的是哪种特定的操作系统,例如Windows 7 32位、Windows 7 64位等?此外,您是否启用了UAC?如果您确实启用了UAC,那么当您以管理员身份运行应用程序时,问题是否会消失。

根据您对这些问题的回答,我可能会提供进一步的帮助。不过我得做一些调查。

目前,如果UAC确实是您的问题,我唯一的建议是您调查使用ShellExecuteEx的可能性。在乘坐Vista UAC电梯时发现的RunElevated功能,上下可能对你有用。为了方便起见,我将把函数包括在这里。

BOOL RunElevated(
HWND hwnd, LPCTSTR pszPath,
LPCTSTR pszParameters = NULL, LPCTSTR pszDirectory = NULL)
{
SHELLEXECUTEINFO shex;
memset( &shex, 0, sizeof( shex) );
shex.cbSize = sizeof(SHELLEXECUTEINFO);
shex.fMask = 0;
shex.hwnd = hwnd;
shex.lpVerb = _T("runas");
shex.lpFile = pszPath;
shex.lpParameters = pszParameters;
shex.lpDirectory = pszDirectory;
shex.nShow = SW_NORMAL;
return ::ShellExecuteEx(&shex);
}

如果使用ShellExecuteEx不是一个选项,您也可以尝试在Vista UAC:the Definition Guide中找到的CreateProcessElevated函数。