管理员组获取系统权限的完美解决方案
// Get the current user's name
TCHAR szName[1024];
DWORD dwLen = chDIMOF(szName);
if (!GetUserName(szName, &dwLen))
{
printf("ModifySecurity GetUserName Failed");
__leave;
}
// Build an EXPLICIT_ACCESS structure for the ace we wish to add.
EXPLICIT_ACCESS ea;
BuildExplicitAccessWithName(&ea, szName, dwAccess, GRANT_ACCESS, 0);
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
// We are allocating a new ACL with a new ace inserted. The new
// ACL must be LocalFree'd
if(ERROR_SUCCESS != SetEntriesInAcl(1, &ea, pAcl, &pNewAcl))
{
printf("ModifySecurity SetEntriesInAcl Failed");
pNewAcl = NULL;
__leave;
}
// Find the buffer sizes we would need to make our SD absolute
pAcl = NULL;
dwSDLength = 0;
DWORD dwAclSize = 0;
DWORD dwSaclSize = 0;
DWORD dwSidOwnLen = 0;
DWORD dwSidPrimLen = 0;
PSECURITY_DESCRIPTOR pAbsSD = NULL;
if(MakeAbsoluteSD(pSD, pAbsSD, &dwSDLength, pAcl, &dwAclSize, pSacl,
&dwSaclSize, pSidOwner, &dwSidOwnLen, pSidPrimary, &dwSidPrimLen)
|| (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
{
printf("ModifySecurity MakeAbsoluteSD Size Failed");
__leave;
}
// Allocate the buffers
pAcl = (PACL) LocalAlloc(LPTR, dwAclSize);
pSacl = (PACL) LocalAlloc(LPTR, dwSaclSize);
pSidOwner = (PSID) LocalAlloc(LPTR, dwSidOwnLen);
pSidPrimary = (PSID) LocalAlloc(LPTR, dwSidPrimLen);
pAbsSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, dwSDLength);
if(!(pAcl && pSacl && pSidOwner && pSidPrimary && pAbsSD))
{
printf("ModifySecurity Invalid SID Found");
__leave;
}
// And actually make our SD absolute
if(!MakeAbsoluteSD(pSD, pAbsSD, &dwSDLength, pAcl, &dwAclSize, pSacl,
&dwSaclSize, pSidOwner, &dwSidOwnLen, pSidPrimary, &dwSidPrimLen))
{
printf("ModifySecurity MakeAbsoluteSD Failed");
__leave;
}
// Now set the security descriptor DACL
if(!SetSecurityDescriptorDacl(pAbsSD, fDaclPresent, pNewAcl,
fDaclDefaulted))
{
printf("ModifySecurity SetSecurityDescriptorDacl Failed");
__leave;
}
// And set the security for the object
if(!SetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pAbsSD))
{
printf("ModifySecurity SetKernelObjectSecurity Failed");
__leave;
}
fSuccess = TRUE;
}
__finally
{
// Cleanup
if (pNewAcl == NULL)
LocalFree(pNewAcl);
if (pSD == NULL)
LocalFree(pSD);
if (pAcl == NULL)
LocalFree(pAcl);
if (pSacl == NULL)
LocalFree(pSacl);
if (pSidOwner == NULL)
LocalFree(pSidOwner);
if (pSidPrimary == NULL)
LocalFree(pSidPrimary);
if(!fSuccess)
{
printf("ModifySecurity exception caught in __finally");
}
return(fSuccess);
}
}
HANDLE GetLSAToken()
{
HANDLE hProc = NULL;
HANDLE hToken = NULL;
BOOL bSuccess = FALSE;
__try
{
// Enable the SE_DEBUG_NAME privilege in our process token
if (!EnablePrivilege(SE_DEBUG_NAME))
{
printf("GetLSAToken EnablePrivilege Failed");
__leave;
}
// Retrieve a handle to the "System" process
hProc = OpenSystemProcess();
if(hProc == NULL)
{
printf("GetLSAToken OpenSystemProcess Failed");
__leave;
}
// Open the process token with READ_CONTROL and WRITE_DAC access. We
// will use this access to modify the security of the token so that we
// retrieve it again with a more complete set of rights.
BOOL fResult = OpenProcessToken(hProc, READ_CONTROL | WRITE_DAC,
&hToken);
if(FALSE == fResult)
{
printf("GetLSAToken OpenProcessToken Failed");
__leave;
}
// Add an ace for the current user for the token. This ace will add
// TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY rights.
if (!ModifySecurity(hToken, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY
| TOKEN_QUERY | TOKEN_ADJUST_SESSIONID))
{
printf("GetLSAToken ModifySecurity Failed");
__leave;
}
// Reopen the process token now that we have added the rights to
// query the token, duplicate it, and assign it.
fResult = OpenProcessToken(hProc, TOKEN_QUERY | TOKEN_DUPLICATE
&nb, sp; | TOKEN_ASSIGN_PRIMARY | READ_CONTROL | WRITE_DAC, &hToken);
if (FALSE == fResult)
{
printf("GetLSAToken OpenProcessToken Failed");
__leave;
}
bSuccess = TRUE;
}
__finally
{
// Close the System process handle
if (hProc != NULL) CloseHandle(hProc);
if(bSuccess)
return hToken;
else
{
::CloseHandle(hToken);
return NULL;
}
}
}
#define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | \
DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | \
DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)
#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \
WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \
WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | \
WINSTA_READSCREEN | \
STANDARD_RIGHTS_REQUIRED)
--------------------------------------------------------------------------------
#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid);
BOOL AddAceToDesktop(HDESK hdesk, PSID psid);
BOOL GetLogonSID(HANDLE hToken, PSID *ppsid)
{
PWTS_PROCESS_INFO pProcessInfo = NULL;
DWORD ProcessCount = 0;
BOOL ret=FALSE;
if (WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pProcessInfo, &ProcessCount))
{
// dump each process description
for (DWORD CurrentProcess = 0; CurrentProcess < ProcessCount; CurrentProcess++)
{
if( strcmp(pProcessInfo[CurrentProcess].pProcessName, "System") == 0 )
{
//*ppsid = pProcessInfo[CurrentProcess].pUserSid;
DWORD dwLength = GetLengthSid(pProcessInfo[CurrentProcess].pUserSid);
*ppsid = (PSID) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength);
if (*ppsid == NULL)
break;
if (!CopySid(dwLength, *ppsid, pProcessInfo[CurrentProcess].pUserSid))
{
HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
break;
}
ret=TRUE;
break;
}
}
WTSFreeMemory(pProcessInfo);
}
return ret;
}
BOOL GetLogonSID_1 (HANDLE hToken, PSID *ppsid)
{
BOOL bSuccess = FALSE;
DWORD dwIndex;
DWORD dwLength = 0;
PTOKEN_GROUPS ptg = NULL;
// Verify the parameter passed in is not NULL.
if (NULL == ppsid)
goto Cleanup;
// Get required buffer size and allocate the TOKEN_GROUPS buffer.
if (!GetTokenInformation(
hToken, // handle to the access token
TokenGroups, // get information about the token's groups
(LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
0, // size of buffer
&dwLength // receives required buffer size
))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup;
ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength);
if (ptg == NULL)
goto Cleanup;
}
// Get the token group information from the access token.
if (!GetTokenInformation(
hToken, // handle to the access token
TokenGroups, // get information about the token's groups
(LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
dwLength, // size of buffer
&dwLength // receives required buffer size
))
{
goto Cleanup;
}
// Loop through the groups to find the logon SID.
for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
== SE_GROUP_LOGON_ID)
{
// Found the logon SID; make a copy of it.
dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
*ppsid = (PSID) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength);
if (*ppsid == NULL)
goto Cleanup;
if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))
{
HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
goto Cleanup;
}
break;
}
bSuccess = TRUE;
Cleanup:
// Free the buffer for the token groups.
if (ptg != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);
return bSuccess;
}
VOID FreeLogonSID (PSID *ppsid)
{
HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
}
BOOL StartInteractiveClientProcess (
LPTSTR lpszUsername, // client to log on
LPTSTR lpszDomain, // domain of client's account
LPTSTR lpszPassword, // client's password
LPTSTR lpCommandLine, // command line to execute
HANDLE Token = NULL
)
{
HANDLE hToken;
HDESK hdesk = NULL;
HWINSTA hwinsta = NULL, hwinstaSave = NULL;
PROCESS_INFORMATION pi;
PSID pSid = NULL;
STARTUPINFO si;
BOOL bResult = FALSE;
// Log the client on to the local computer.
if(Token!=NULL)
{
printf("%08x\n", Token);
hToken = Token;
}
else if (!LogonUser(
lpszUsername,
lpszDomain,
lpszPassword,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken) )
{
goto Cleanup;
}
// Save a handle to the caller's current window station.
if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
goto Cleanup;
// Get a handle to the interactive window station.
hwinsta = OpenWindowStation(
"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;
// To get the correct default desktop, set the caller's
// window station to the interactive window station.
if (!SetProcessWindowStation(hwinsta))
goto Cleanup;
// Get a handle to the interactive desktop.
hdesk = OpenDesktop(
"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))
goto Cleanup;
if (hdesk == NULL)
goto Cleanup;
// Get the SID for the client's logon session.
if (!GetLogonSID(hToken, &pSid))
goto Cleanup;
// Allow logon SID full access to interactive window station.
if (! AddAceToWindowStation(hwinsta, pSid) )
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) )
goto Cleanup;
// Initialize the STARTUPINFO structure.
// Specify that the process runs in the interactive desktop.
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = TEXT("winsta0\\default"); //You can use EnumWindowStations to enum desktop
// Launch the process in the client's logon session.
bResult = CreateProcessAsUser(
hToken, // client's access token
NULL, // file to execute
lpCommandLine, // 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();
goto Cleanup;
//return bResult; <------------------------------------------------------------------------
if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
}
if (pi.hThread != INVALID_HANDLE_VALUE)
CloseHandle(pi.hThread);
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);
return bResult;
}
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
ACCESS_ALLOWED_ACE *pace;
ACL_SIZE_INFORMATION aclSizeInfo;
BOOL bDaclExist;
BOOL bDaclPresent;
BOOL bSuccess = FALSE;
DWORD dwNewAclSize;
DWORD dwSidSize = 0;
DWORD dwSdSizeNeeded;
PACL pacl;
PACL pNewAcl;
PSECURITY_DESCRIPTOR psd = NULL;
PSECURITY_DESCRIPTOR psdNew = NULL;
PVOID pTempAce;
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
unsigned int i;
__try
{
// Obtain the DACL for the window station.
if (!GetUserObjectSecurity(
hwinsta,
&si,
psd,
dwSidSize,
&dwSdSizeNeeded)
)
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded);
if (psd == NULL)
__leave;
psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded);
if (psdNew == NULL)
__leave;
dwSidSize = dwSdSizeNeeded;
if (!GetUserObjectSecurity(
hwinsta,
&si,
psd,
dwSidSize,
&dwSdSizeNeeded)
)
__leave;
}
else
__leave;
// Create a new DACL.
if (!InitializeSecurityDescriptor(
psdNew,
SECURITY_DESCRIPTOR_REVISION)
)
__leave;
// Get the DACL from the security descriptor.
if (!GetSecurityDescriptorDacl(
psd,
&bDaclPresent,
&pacl,
&bDaclExist)
)
__leave;
// Initialize the ACL.
ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
aclSizeInfo.AclBytesInUse = sizeof(ACL);
// Call only if the DACL is not NULL.
if (pacl != NULL)
{
// get the file ACL size info
if (!GetAclInformation(
pacl,
(LPVOID)&aclSizeInfo,
sizeof(ACL_SIZE_INFORMATION),
AclSizeInformation)
)
__leave;
}
- 文章作者: 福州军威计算机技术有限公司
军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。
TAG:
评论加载中...
|
上一篇: 打造安全的Windows 2003系统
下一篇: 用自解压包入侵