64,653
社区成员
发帖
与我相关
我的任务
分享
HANDLE GetUserToken(LPTSTR lpszUsername)
{
HANDLE currentToken = 0;
HANDLE primaryToken = 0;
int dwSessionId = -1;
HANDLE hUserToken = 0;
HANDLE hTokenDup = 0;
PWTS_SESSION_INFO pSessionInfo = 0;
DWORD dwCount = 0;
// Get the list of all terminal sessions
::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
int dataSize = sizeof(WTS_SESSION_INFO);
// look over obtained list in search of the active session
for (DWORD i = 0; i < dwCount; ++i)
{
WTS_SESSION_INFO si = pSessionInfo[i];
LPTSTR lpUsename = NULL;
DWORD dwLen = 0;
if(!::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, si.SessionId, WTSUserName, &lpUsename, &dwLen))
{
WRITE_LOG(_T("WTSQuerySessionInformation Faill"));
continue;
}
std::string strUsername;
strUsername = lpUsename;
WRITE_LOG(strUsername);
::WTSFreeMemory(lpUsename);
if (strUsername.compare(lpszUsername) == 0)
{
// If the current session is user's ID
dwSessionId = si.SessionId;
strUsername = "Yes find the sessionid " + strUsername;
WRITE_LOG(strUsername);
break;
}
}
::WTSFreeMemory(pSessionInfo);
if (dwSessionId == -1)
{
return 0;
}
// Get token of the logged in user by the active session ID
BOOL bRet = FALSE;
////////////////////////////////////////////////////
//获取用户名的权限令牌以开启进程;
bRet = ::WTSQueryUserToken(dwSessionId, ¤tToken);
if (bRet == false)
{
std::string log;
long long i = GetLastError();
log = std::to_string(i);
log = "WTSQueryUserToken Fail" + log;
WRITE_LOG(log);
return 0;
}
bRet = ::DuplicateTokenEx(currentToken, TOKEN_IMPERSONATE |TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &primaryToken);
if (bRet == FALSE)
{
std::string log;
long long i = GetLastError();
log = std::to_string(i);
log = "GetUserToken.DuplicateTokenEx Fail, err code " + log;
WRITE_LOG(log);
return 0;
}
//////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//获取当前服务权限令牌,即SYSTEM 权限, 并设置session为获取用户名的session;
//这样做的话,进程以SYSTEM身份运行(SYSTEM 的SESSION 为0);
//但session 是以lpszUsername用户名的session;
////////////////////////////////////////////////////////////////////////
/*HANDLE hThisProcess = ::GetCurrentProcess();
HANDLE hTokenThis = NULL;
bRet = ::OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);
if (bRet == FALSE)
{
std::string log;
long long i = GetLastError();
log = std::to_string(i);
log = "OpenProcessToken Fail, err code " + log;
WRITE_LOG(log);
return 0;
}
bRet = ::DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &primaryToken);
if (bRet == FALSE)
{
std::string log;
long long i = GetLastError();
log = std::to_string(i);
log = "GetUserToken.DuplicateTokenEx Fail, err code " + log;
WRITE_LOG(log);
return 0;
}
bRet = ::SetTokenInformation(primaryToken, TokenSessionId, &dwSessionId, sizeof(DWORD));
if (bRet == FALSE)
{
std::string log;
long long i = GetLastError();
log = std::to_string(i);
log = "SetTokenInformation Fail, err code " + log;
WRITE_LOG(log);
return 0;
}*/
////////////////////////////////////////////////////////////
return primaryToken;
}
BOOL StartLoginedUserProcess (
LPTSTR lpszUsername, //logined username
LPTSTR lpCommandLine, // command line to execute
PROCESS_INFORMATION *pProcessInfo, //get new process info
HANDLE hJob
)
{
HANDLE hToken = NULL;
HANDLE hThisToken = NULL;
HDESK hdesk = NULL;
HWINSTA hwinsta = NULL, hwinstaSave = NULL;
PROCESS_INFORMATION pi = {0};
PSID pSid = NULL;
STARTUPINFO si = {0};
BOOL bResult = FALSE;
LPVOID pEnv = NULL;
std::string log;
hToken = GetUserToken(lpszUsername);
if (hToken == NULL)
{
log.clear();
long long i = GetLastError();
log = std::to_string(i);
log = "GetUserToken NULL " + log;
WRITE_LOG(log);
goto Cleanup;
}
//// Save a handle to the caller's current window station.
if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
{
log.clear();
long long i = GetLastError();
log = std::to_string(i);
log = "GetProcessWindowStation Fail;" + log;
WRITE_LOG(log);
goto Cleanup;
}
log.clear();
log = "GetProcessWindowStation suc ;" + log;
WRITE_LOG(log);
// Get a handle to the interactive window station.
hwinsta = OpenWindowStation(
_T("winsta0"), // the interactive window station
FALSE, // handle is not inheritable
READ_CONTROL | WRITE_DAC); // rights to read/write the DACL
if (hwinsta == NULL)
goto Cleanup;
log.clear();
log = "OpenWindowStation suc ;" + log;
WRITE_LOG(log);
//// To get the correct default desktop, set the caller's
//// window station to the interactive window station.
if (!SetProcessWindowStation(hwinsta))
goto Cleanup;
log.clear();
log = "SetProcessWindowStation suc ;" + log;
WRITE_LOG(log);
// //Get a handle to the interactive desktop.
hdesk = OpenDesktop(
_T("default"), // the interactive window station
0, // no interaction with other desktop processes
FALSE, // handle is not inheritable
READ_CONTROL | // request the rights to read and write the DACL
WRITE_DAC |
DESKTOP_WRITEOBJECTS |
DESKTOP_READOBJECTS);
// Restore the caller's window station.
if (!SetProcessWindowStation(hwinstaSave))
{
log.clear();
long long i = GetLastError();
log = std::to_string(i);
log = "SetProcessWindowStation Fail;" + log;
WRITE_LOG(log);
goto Cleanup;
}
if (hdesk == NULL)
goto Cleanup;
// Get the SID for the client's logon session.
if (!GetLogonSID(hToken, &pSid))
{
log.clear();
long long i = GetLastError();
log = std::to_string(i);
log = "GetLogonSID Fail;" + log;
WRITE_LOG(log);
goto Cleanup;
}
// Allow logon SID full access to interactive window station.
if (! AddAceToWindowStation(hwinsta, pSid) )
{
log.clear();
long long i = GetLastError();
log = std::to_string(i);
log = "AddAceToWindowStation Fail;" + log;
WRITE_LOG(log);
goto Cleanup;
}
// Allow logon SID full access to interactive desktop.
if (! AddAceToDesktop(hdesk, pSid) )
goto Cleanup;
// Impersonate client to ensure access to executable file.
if (! ImpersonateLoggedOnUser(hToken) )
{
log.clear();
long long i = GetLastError();
log = std::to_string(i);
log = "ImpersonateLoggedOnUser Fail;" + log;
WRITE_LOG(log);
goto Cleanup;
}
::ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = TEXT("winsta0\\default");
//// Launch the process in the client's logon session.
bResult = ::CreateProcessAsUser(
hToken, // client's access token
lpCommandLine, // file to execute
NULL, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, // creation flags
NULL, // pointer to new environment block
NULL, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
// End impersonation of client.
::RevertToSelf();
if (bResult == FALSE)
{
log.clear();
long long i = GetLastError();
log = std::to_string(i);
log = "CreateProcessAsUser Fail;" + log;
WRITE_LOG(log);
goto Cleanup;
}
if(FALSE == ::AssignProcessToJobObject(hJob, pi.hProcess))//这样能够在停止服务后,进程也退出;
{
log.clear();
std::string strID;
long long i = ::GetLastError();
strID = std::to_string(i);
log = log + "AssignProcessToJobObject Fail ,err code = " + strID;
WRITE_LOG(log);
goto Cleanup;
}
::Sleep(1000);
DWORD dwExitCode = 10;
if(::GetExitCodeProcess(pi.hProcess, &dwExitCode))
{
log.clear();
std::string strID;
long long i = dwExitCode;
strID = std::to_string(i);
log = log + "process exit code = " + strID;
WRITE_LOG(log);
}
if (pi.hProcess != INVALID_HANDLE_VALUE)
{
CloseHandle(pi.hProcess);
}
/*if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
{
WaitForSingleObject(pi.hProcess, 180000);
CloseHandle(pi.hProcess);
}*/
if (pi.hThread != INVALID_HANDLE_VALUE)
{
CloseHandle(pi.hThread);
}
//-liqj
if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
{
if(GetThreadDesktop(pi.dwThreadId) == NULL)
{
WRITE_LOG("GetThreadDesktop NULL");
}
else
{
WRITE_LOG("GetThreadDesktop No NULL");
}
if (pProcessInfo != NULL)
{
memcpy(pProcessInfo, &pi, sizeof(PROCESS_INFORMATION));
log.clear();
std::string strID;
long long i = pi.dwThreadId;
strID = std::to_string(i);
log = log + "Create Process Suc id " + strID;
WRITE_LOG(log);
}
}
else
{
memcpy(pProcessInfo, &pi, sizeof(PROCESS_INFORMATION));
log.clear();
std::string strID;
long long i = pi.dwThreadId;
strID = std::to_string(i);
log = log + "Create Process Fail id " + strID;
WRITE_LOG(log);
}
Cleanup:
if (hwinstaSave != NULL)
::SetProcessWindowStation (hwinstaSave);
// Free the buffer for the logon SID.
if (pSid)
FreeLogonSID(&pSid);
// Close the handles to the interactive window station and desktop.
if (hwinsta)
::CloseWindowStation(hwinsta);
if (hdesk)
::CloseDesktop(hdesk);
// Close the handle to the client's access token.
if (hToken != INVALID_HANDLE_VALUE)
::CloseHandle(hToken);
if (hThisToken != INVALID_HANDLE_VALUE)//liqj
::CloseHandle(hThisToken);
if (pEnv != NULL)
{
::DestroyEnvironmentBlock(pEnv);
}
return bResult;
}
/*
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (C) 1998 - 2000. Microsoft Corporation. All rights reserved.
This code sample requires the following import library:
advapi32.lib
Note: This sample does not run on Windows 2000.
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <accctrl.h>
#include <aclapi.h>
#define SD_SIZE (65536 + SECURITY_DESCRIPTOR_MIN_LENGTH)
#define SYSTEM_PID 2
#define PERR(s) fprintf(stderr, "%s(%d) %s : Error %d\n%s\n", \
__FILE__, __LINE__, (s), GetLastError(), \
GetLastErrorText())
BOOL EnableDebugPriv(void);
BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess);
LPSTR GetLastErrorText(void);
void main( int argc, char * argv[] )
{
HANDLE hProc;
HANDLE hToken;
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL bResult;
if(!EnableDebugPriv())
{
printf("You probably don't have the SE_DEBUG_NAME privilege\n");
exit(0);
}
//
// PID 2 is always(?) associated with the
// "system" process which has the context we
// are after - local system
//
if(!(hProc = OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
SYSTEM_PID)))
{
PERR("OpenProcess");
printf("You are probably not a member of the administrator group\n");
exit(0);
}
//
// Open the process token with this access
// so that we can modify the DACL and add
// TOKEN_DUPLICATE & TOKEN_ASSIGN_PRIMARY
// rights for this user
//
bResult = OpenProcessToken(
hProc,
READ_CONTROL|WRITE_DAC,
&hToken);
if (bResult == FALSE)
{
PERR("OpenProcessToken");
exit(0);
}
if(!ModifySecurity(
hToken,
TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_QUERY))
{
exit(0);
}
CloseHandle(hToken);
//
// Close that handle and get a new one with the right
// privilege level
//
bResult = OpenProcessToken(
hProc,
TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY,
&hToken);
if (FALSE == bResult)
{
PERR("OpenProcessToken");
exit(0);
}
//
// setup STARTUPINFO structure
//
memset( &si, 0, sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
if( !CreateProcessAsUser(
hToken,
NULL,
"cmd.exe",
NULL, // default process attributes
NULL, // default thread attributes
FALSE, // don't inherit handles
CREATE_NEW_CONSOLE,
NULL, // inherit environment
NULL, // same directory
&si,
&pi ) )
PERR( "CreateProcessAsUser" );
else
printf( "\"SuperUsr\" mode console started!\n" );
CloseHandle(hProc);
CloseHandle(hToken);
}
BOOL EnableDebugPriv(void)
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
if(!OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&hToken ))
{
PERR("OpenProcessToken");
return(FALSE);
}
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
PERR("LookupPrivilegeValue");
CloseHandle(hToken);
return(FALSE);
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
NULL,
NULL ))
{
PERR("AdjustTokenPrivileges");
CloseHandle(hToken);
return(FALSE);
}
CloseHandle(hToken);
return(TRUE);
}
BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess)
{
UCHAR ucSDbuf[SD_SIZE];
PSECURITY_DESCRIPTOR pSD=(PSECURITY_DESCRIPTOR)ucSDbuf;
DWORD dwSDLengthNeeded;
PACL pAcl;
PACL pNewAcl;
EXPLICIT_ACCESS explicitaccess;
BOOL fDaclPresent,fDaclDefaulted;
DWORD dwResult;
UCHAR ucAbsSDbuf[SD_SIZE];
PSECURITY_DESCRIPTOR pAbsSD=(PSECURITY_DESCRIPTOR)ucAbsSDbuf;
DWORD dwSDLength;
#define ACL_SIZE 2048
#define SID_SIZE 1024
PACL pacl,psacl;
DWORD dwAclSize=ACL_SIZE, dwSaclSize=ACL_SIZE;
PSID pSidOwner,pSidPrimary;
DWORD dwSidOwnLen=SID_SIZE,dwSidPrimLen=SID_SIZE;
if(!GetKernelObjectSecurity(
hProc,
DACL_SECURITY_INFORMATION,
pSD,
SD_SIZE,
&dwSDLengthNeeded))
{
PERR("GetKernelObjectSecurity");
return(FALSE);
}
if(!GetSecurityDescriptorDacl(
pSD,
&fDaclPresent,
&pAcl,
&fDaclDefaulted))
{
PERR("GetSecurityDescriptorDacl");
return(FALSE);
}
BuildExplicitAccessWithName(
&explicitaccess,
"administrators",
dwAccess,
GRANT_ACCESS,
0 );
if( dwResult = SetEntriesInAcl(
1,
&explicitaccess,
pAcl,
&pNewAcl ) )
{
SetLastError(dwResult);
PERR("SetEntriesInAcl");
return( FALSE );
}
pacl = malloc(ACL_SIZE);
psacl = malloc(ACL_SIZE);
pSidOwner = malloc(SID_SIZE);
pSidPrimary = malloc(SID_SIZE);
dwSDLength = SD_SIZE;
if(!MakeAbsoluteSD(
pSD,
pAbsSD,
&dwSDLength,
pacl, &dwAclSize,
psacl, &dwSaclSize,
pSidOwner, &dwSidOwnLen,
pSidPrimary, &dwSidPrimLen))
{
PERR("MakeAbsoluteSD");
return(FALSE);
}
if(!SetSecurityDescriptorDacl(
pAbsSD,
fDaclPresent,
pNewAcl,
fDaclDefaulted))
{
PERR("SetSecurityDescriptorDacl");
return(FALSE);
}
if(!SetKernelObjectSecurity(
hProc,
DACL_SECURITY_INFORMATION,
pAbsSD))
{
PERR("SetKernelObjectSecurity");
return(FALSE);
}
return (TRUE);
}
LPSTR GetLastErrorText()
{
#define MAX_MSG_SIZE 256
static char szMsgBuf[MAX_MSG_SIZE];
DWORD dwError, dwRes;
dwError = GetLastError ();
dwRes = FormatMessage (
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
szMsgBuf,
MAX_MSG_SIZE,
NULL);
if (0 == dwRes) {
fprintf(stderr, "FormatMessage failed with %d\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
return szMsgBuf;
}