设为主页 | 加入收藏 | 繁體中文

管理员组获取系统权限的完美解决方案


  // 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:
评论加载中...
内容:
评论者: 验证码: