CreateProcessAsUser() windowstations 和桌面

本文介绍了一段示例代码,该代码用于给予指定用户(如franki)对Windows系统的winsta0//default桌面完全访问权限。通过调整安全描述符和访问控制列表(ACL),实现对窗口工作站和桌面的权限管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

以下示例代码使用户名为 " franki " 完全访问权限交互 windowstation 桌面, " winsta0//default "。 对于每个对象访问控制项 (ACE) 是基于 franki 的登录 SID。 代码执行 Cmd.exe 文件。

#define RTN_OK     0
   #define RTN_ERROR 13

   #define WINSTA_ALL (WINSTA_ACCESSCLIPBOARD  | WINSTA_ACCESSGLOBALATOMS |

   WINSTA_CREATEDESKTOP    | WINSTA_ENUMDESKTOPS      |
   WINSTA_ENUMERATE        
| WINSTA_EXITWINDOWS       |
   WINSTA_READATTRIBUTES   
| WINSTA_READSCREEN        |
   WINSTA_WRITEATTRIBUTES  
| DELETE                   |
   READ_CONTROL            
| WRITE_DAC                |
   WRITE_OWNER)

   
#define DESKTOP_ALL (DESKTOP_CREATEMENU      | DESKTOP_CREATEWINDOW  |
   DESKTOP_ENUMERATE       | DESKTOP_HOOKCONTROL   |
   DESKTOP_JOURNALPLAYBACK 
| DESKTOP_JOURNALRECORD |
   DESKTOP_READOBJECTS     
| DESKTOP_SWITCHDESKTOP |
   DESKTOP_WRITEOBJECTS    
| DELETE                |
   READ_CONTROL            
| WRITE_DAC             |
   WRITE_OWNER)

   
#define GENERIC_ACCESS (GENERIC_READ    | GENERIC_WRITE |
   GENERIC_EXECUTE | GENERIC_ALL)

   
#include <windows.h>
   #include <stdio.h>


   BOOL ObtainSid(

        HANDLE hToken
,           // Handle to an process access token.
        PSID   
*psid             // ptr to the buffer of the logon sid
        );

   void RemoveSid(
        PSID 
*psid               // ptr to the buffer of the logon sid
        );

   BOOL AddTheAceWindowStation(

        HWINSTA hwinsta
,         // handle to a windowstation
        PSID    psid             
// logon sid of the process
        );

   BOOL AddTheAceDesktop(

        HDESK hdesk
,             // handle to a desktop
        PSID  psid               
// logon sid of the process
        );

   
int main(void)
   {
        HANDLE              hToken;
        HDESK               hdesk;
        HWINSTA             hwinsta;
        PROCESS_INFORMATION pi;
        PSID                psid;
        STARTUPINFO         si;

        
// 
        
// obtain an access token for the user fester
        
// 
        
if (!LogonUser(
             
"franki",
             NULL
,
             
"franki",
             LOGON32_LOGON_INTERACTIVE
,
             LOGON32_PROVIDER_DEFAULT
,
             
&hToken
             ))
             
return RTN_ERROR;

        
// 
        
// obtain a handle to the interactive windowstation
        
// 
        hwinsta 
= OpenWindowStation(
             
"winsta0",
             FALSE
,
             READ_CONTROL 
| WRITE_DAC
             );
        
if (hwinsta == NULL)
             
return RTN_ERROR;

        HWINSTA hwinstaold 
= GetProcessWindowStation();

        
// 
        
// set the windowstation to winsta0 so that you obtain the
        
// correct default desktop
        
// 
        
if (!SetProcessWindowStation(hwinsta))
             
return RTN_ERROR;

        
// 
        
// obtain a handle to the "default" desktop
        
// 
        hdesk 
= OpenDesktop(
             
"default",
             
0,
             FALSE
,
             READ_CONTROL 
| WRITE_DAC |
             DESKTOP_WRITEOBJECTS 
| DESKTOP_READOBJECTS
             );
        
if (hdesk == NULL)
             
return RTN_ERROR;

        
// 
        
// obtain the logon sid of the user fester
        
// 
        
if (!ObtainSid(hToken, &psid))
             
return RTN_ERROR;

        
// 
        
// add the user to interactive windowstation
        
// 
        
if (!AddTheAceWindowStation(hwinsta, psid))
             
return RTN_ERROR;

        
// 
        
// add user to "default" desktop
        
// 
        
if (!AddTheAceDesktop(hdesk, psid))
             
return RTN_ERROR;

        
// 
        
// free the buffer for the logon sid
        
// 
        RemoveSid(
&psid);

        
// 
        
// close the handles to the interactive windowstation and desktop
        
// 
        CloseWindowStation(hwinsta);

        CloseDesktop(hdesk);

        
// 
        
// initialize STARTUPINFO structure
        
// 
        ZeroMemory(
&si, sizeof(STARTUPINFO));
        si
.cb        = sizeof(STARTUPINFO);
        si
.lpDesktop = "winsta0/default";

        
// 
        
// start the process
        
// 
        
if (!CreateProcessAsUser(
             hToken
,
             NULL
,
             
"cmd.exe",
             NULL
,
             NULL
,
             FALSE
,
             NORMAL_PRIORITY_CLASS 
| CREATE_NEW_CONSOLE,
             NULL
,
             NULL
,
             
&si,
             
&pi
             ))
             
return RTN_ERROR;

        SetProcessWindowStation(hwinstaold); 
//set it back

        
// 
        
// close the handles
        
// 
        CloseHandle(pi
.hProcess);

        CloseHandle(pi
.hThread);

        
return RTN_OK;
   }


   BOOL ObtainSid(HANDLE hToken
, PSID *psid)

      {
        BOOL                    bSuccess 
= FALSE; // assume function will
                                                  
// fail
        DWORD                   dwIndex;
        DWORD                   dwLength 
= 0;
        TOKEN_INFORMATION_CLASS tic      
= TokenGroups;
        PTOKEN_GROUPS           ptg      
= NULL;

        __try
             {
             
// 
             
// determine the size of the buffer
        
// 
             
if (!GetTokenInformation(
             hToken
,
             tic
,
             (LPVOID)ptg
,
             
0,
             
&dwLength
             ))
                  {
                  
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                       {
                       ptg 
= (PTOKEN_GROUPS)HeapAlloc(
                            GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwLength
                  );
                       
if (ptg == NULL)
                            __leave;
                       }
                   
else
                       __leave;
         }

             
// 
             
// obtain the groups the access token belongs to
             
// 
             
if (!GetTokenInformation(
                  hToken
,
             tic
,
             (LPVOID)ptg
,
             dwLength
,
             
&dwLength
             ))
                  __leave;

             
// 
             
// determine which group is the logon sid
             
// 
             
for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
                  {
             
if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
                  
==  SE_GROUP_LOGON_ID)
                       {
                       
// 
                       
// determine the length of the sid
                       
// 
                       dwLength 
= GetLengthSid(ptg->Groups[dwIndex].Sid);

                       
// 
                       
// allocate a buffer for the logon sid
                       
// 
                       
*psid = (PSID)HeapAlloc(
                            GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwLength
                  );
                  
if (*psid == NULL)
                       __leave;

                  
// 
                  
// obtain a copy of the logon sid
                  
// 
                  
if (!CopySid(dwLength, *psid, ptg->Groups[dwIndex].Sid))
                       __leave;

                  
// 
                  
// break out of the loop because the logon sid has been
                  
// found
                  
// 
                  break;
                  }
             }

             
// 
             
// indicate success
             
// 
             bSuccess 
= TRUE;
             }
        __finally
             {
             
// 
        
// free the buffer for the token group
        
// 
             
if (ptg != NULL)
                  HeapFree(GetProcessHeap()
, 0, (LPVOID)ptg);
             }

        
return bSuccess;

   }

   void RemoveSid(PSID 
*psid)
   {
        HeapFree(GetProcessHeap()
, 0, (LPVOID)*psid);
   }

   BOOL AddTheAceWindowStation(HWINSTA hwinsta
, PSID psid)
   {

        ACCESS_ALLOWED_ACE   
*pace;
        ACL_SIZE_INFORMATION aclSizeInfo;
        BOOL                 bDaclExist;
        BOOL                 bDaclPresent;
        BOOL                 bSuccess  
= FALSE; // assume function will
                                                
//fail
        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 windowstation
             
// 
             
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 dacl from the security descriptor
             
// 
             
if (!GetSecurityDescriptorDacl(
                  psd
,
                  
&bDaclPresent,
                  
&pacl,
                  
&bDaclExist
                  ))
                  __leave;

             
// 
             
// initialize
             
// 
             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;
                   }

             
// 
             
// compute the size of the new acl
             
// 
             dwNewAclSize 
= aclSizeInfo.AclBytesInUse + (2 *
             sizeof(ACCESS_ALLOWED_ACE)) 
+ (2 * GetLengthSid(psid)) - (2 *
             sizeof(DWORD));

             
// 
             
// allocate memory for the new acl
             
// 
             pNewAcl 
= (PACL)HeapAlloc(
                  GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwNewAclSize
                  );
             
if (pNewAcl == NULL)
                  __leave;

             
// 
             
// initialize the new dacl
             
// 
             
if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
                  __leave;

             
// 
             
// if DACL is present, copy it to a new DACL
             
// 
             
if (bDaclPresent) // only copy if DACL was present
                  {
                  
// copy the ACEs to our new ACL
                  
if (aclSizeInfo.AceCount)
                       {
                       
for (i=0; i < aclSizeInfo.AceCount; i++)
                            {
                            
// get an ACE
                            
if (!GetAce(pacl, i, &pTempAce))
                                 __leave;

                            
// add the ACE to the new ACL
                            
if (!AddAce(
                  pNewAcl
,
                                 ACL_REVISION
,
                                 MAXDWORD
,
                                 pTempAce
,
                  ((PACE_HEADER)pTempAce)
->AceSize
                                 ))
                                 __leave;
                             }
                        }
                  }

             
// 
             
// add the first ACE to the windowstation
             
// 
             pace 
= (ACCESS_ALLOWED_ACE *)HeapAlloc(
                  GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
             sizeof(ACCESS_ALLOWED_ACE) 
+ GetLengthSid(psid) -
                  sizeof(DWORD
                  ));
             
if (pace == NULL)
                  __leave;

             pace
->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
             pace
->Header.AceFlags = CONTAINER_INHERIT_ACE |
                                     INHERIT_ONLY_ACE      
|

                                     OBJECT_INHERIT_ACE;
             pace
->Header.AceSize  = sizeof(ACCESS_ALLOWED_ACE) +

                                     GetLengthSid(psid) 
- sizeof(DWORD);
             pace
->Mask            = GENERIC_ACCESS;

             
if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
                  __leave;

             
if (!AddAce(
                  pNewAcl
,
                  ACL_REVISION
,
             MAXDWORD
,
                  (LPVOID)pace
,
                  pace
->Header.AceSize
                  ))
                  __leave;

             
// 
             
// add the second ACE to the windowstation
             
// 
             pace
->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
             pace
->Mask            = WINSTA_ALL;

             
if (!AddAce(
                  pNewAcl
,
                  ACL_REVISION
,
                  MAXDWORD
,
                  (LPVOID)pace
,
                  pace
->Header.AceSize
                  ))
                  __leave;

                  
// 
                  
// set new dacl for the security descriptor
                  
// 
                  
if (!SetSecurityDescriptorDacl(
                       psdNew
,
                       TRUE
,
                       pNewAcl
,
                       FALSE
                       ))
                       __leave;

                   
// 
         
// set the new security descriptor for the windowstation
         
// 
         
if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
            __leave;

         
// 
         
// indicate success
         
// 
         bSuccess 
= TRUE;
             }
        __finally
             {
             
// 
             
// free the allocated buffers
             
// 
             
if (pace != NULL)
                  HeapFree(GetProcessHeap()
, 0, (LPVOID)pace);

             
if (pNewAcl != NULL)
                  HeapFree(GetProcessHeap()
, 0, (LPVOID)pNewAcl);

             
if (psd != NULL)
                  HeapFree(GetProcessHeap()
, 0, (LPVOID)psd);

             
if (psdNew != NULL)
                  HeapFree(GetProcessHeap()
, 0, (LPVOID)psdNew);
             }

        
return bSuccess;

   }

   BOOL AddTheAceDesktop(HDESK hdesk
, PSID psid)
   {

        ACL_SIZE_INFORMATION aclSizeInfo;
        BOOL                 bDaclExist;
        BOOL                 bDaclPresent;
        BOOL                 bSuccess  
= FALSE; // assume function will
                                                
// fail
        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 security descriptor for the desktop object
             
// 
             
if (!GetUserObjectSecurity(
                  hdesk
,
                  
&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(
                            hdesk
,
                            
&si,
                            psd
,
                            dwSidSize
,
                            
&dwSdSizeNeeded
                            ))
                            __leave;
                       }
                  
else
                       __leave;
                  }

             
// 
             
// create a new security descriptor
             
// 
             
if (!InitializeSecurityDescriptor(
                  psdNew
,
                  SECURITY_DESCRIPTOR_REVISION
                  ))
               _   _leave;

             
// 
             
// obtain the dacl from the security descriptor
             
// 
             
if (!GetSecurityDescriptorDacl(
                  psd
,
                  
&bDaclPresent,
                  
&pacl,
                  
&bDaclExist
                  ))
                  __leave;

             
// 
             
// initialize
             
// 
             ZeroMemory(
&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
             aclSizeInfo
.AclBytesInUse = sizeof(ACL);

             
// 
             
// call only if NULL dacl
             
// 
             
if (pacl != NULL)
                  {
                  
// 
                  
// determine the size of the ACL info
                  
// 
                  
if (!GetAclInformation(
                       pacl
,
                       (LPVOID)
&aclSizeInfo,
                       sizeof(ACL_SIZE_INFORMATION)
,
                       AclSizeInformation
                       ))
                       __leave;
                   }

             
// 
             
// compute the size of the new acl
             
// 
        dwNewAclSize 
= aclSizeInfo.AclBytesInUse +
                            sizeof(ACCESS_ALLOWED_ACE) 
+
                            GetLengthSid(psid) 
- sizeof(DWORD);

             
// 
             
// allocate buffer for the new acl
             
// 
             pNewAcl 
= (PACL)HeapAlloc(
                  GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwNewAclSize
                  );
             
if (pNewAcl == NULL)
                  __leave;

             
// 
             
// initialize the new acl
             
// 
             
if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
                  __leave;

             
// 
             
// if DACL is present, copy it to a new DACL
             
// 
             
if (bDaclPresent) // only copy if DACL was present
                  {
                  
// copy the ACEs to our new ACL
                  
if (aclSizeInfo.AceCount)
                       {
                       
for (i=0; i < aclSizeInfo.AceCount; i++)
                            {
                            
// get an ACE
                            
if (!GetAce(pacl, i, &pTempAce))
                                 __leave;

                            
// add the ACE to the new ACL
                            
if (!AddAce(
                                 pNewAcl
,
                                 ACL_REVISION
,
                                 MAXDWORD
,
                                 pTempAce
,
                                 ((PACE_HEADER)pTempAce)
->AceSize
                                 ))
                                 __leave;
                             }
                        }
                  }

             
// 
             
// add ace to the dacl
             
// 
             
if (!AddAccessAllowedAce(
                  pNewAcl
,
                  ACL_REVISION
,
                  DESKTOP_ALL
,
                  psid
                  ))
                  __leave;

             
// 
             
// set new dacl to the new security descriptor
             
// 
             
if (!SetSecurityDescriptorDacl(
                       psdNew
,
                       TRUE
,
                       pNewAcl
,
                       FALSE
                       ))
                  __leave;

             
// 
             
// set the new security descriptor for the desktop object
             
// 
             
if (!SetUserObjectSecurity(hdesk, &si, psdNew))
                  __leave;

             
// 
             
// indicate success
             
// 
             bSuccess 
= TRUE;
             }
        __finally
            {
            
// 
            
// free buffers
            
// 
            
if (pNewAcl != NULL)
                 HeapFree(GetProcessHeap()
, 0, (LPVOID)pNewAcl);

             
if (psd != NULL)
                  HeapFree(GetProcessHeap()
, 0, (LPVOID)psd);

             
if (psdNew != NULL)
                  HeapFree(GetProcessHeap()
, 0, (LPVOID)psdNew);
             }

        
return bSuccess;
   }
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值