前面说在系统登陆桌面运行程序必须取得TCB特权,今天研究了一下,这话说的有点儿绝对了。在网上搜索了一下,大名鼎鼎的Phrack上的有一篇文章介绍 如何操作Physical Memory给了我启发。问题的关键不在于TCB特权,而在于ADMIN帐号没有权限操作""Winlogon"内核对象。从下面这张图可以看出 SYSTEM帐号和ADMIN帐号在""Winlogon"内核对象上的权限区别:
那么在""Winlogon"内核对象上给ADMIN帐号加上相应的访问权限是不是就可以了呢?答案是肯定的。添加权限的代码如下:
BOOL GrantAccessRights(HANDLE hWinlogonDesktop)
{
PACL OldDacl=NULL, NewDacl=NULL;
PSECURITY_DESCRIPTOR SecDesc=NULL;
EXPLICIT_ACCESS Access;
BOOL retval = FALSE;
DWORD Res = GetSecurityInfo(hWinlogonDesktop, SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, &OldDacl,
NULL, &SecDesc);
if (Res != ERROR_SUCCESS)
return FALSE;
Access.grfAccessPermissions = ACTRL_PERM_1|ACTRL_PERM_2;
Access.grfAccessMode = GRANT_ACCESS;
Access.grfInheritance = NO_INHERITANCE;
Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
// change these informations to grant access to a group or other user
Access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
Access.Trustee.TrusteeType = TRUSTEE_IS_USER;
Access.Trustee.ptstrName = "CURRENT_USER";
// create the new ACL
if (ERROR_SUCCESS != SetEntriesInAcl(1, &Access, OldDacl, &NewDacl))
goto cleanup;
// update ACL
retval = ERROR_SUCCESS == SetSecurityInfo(hWinlogonDesktop, SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, NewDacl,
NULL);
cleanup:
if (NewDacl)
LocalFree(NewDacl);
if (SecDesc)
LocalFree(SecDesc);
return retval;
}
那么在""Winlogon"内核对象上给ADMIN帐号加上相应的访问权限是不是就可以了呢?答案是肯定的。添加权限的代码如下:
BOOL GrantAccessRights(HANDLE hWinlogonDesktop)
{
PACL OldDacl=NULL, NewDacl=NULL;
PSECURITY_DESCRIPTOR SecDesc=NULL;
EXPLICIT_ACCESS Access;
BOOL retval = FALSE;
DWORD Res = GetSecurityInfo(hWinlogonDesktop, SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, &OldDacl,
NULL, &SecDesc);
if (Res != ERROR_SUCCESS)
return FALSE;
Access.grfAccessPermissions = ACTRL_PERM_1|ACTRL_PERM_2;
Access.grfAccessMode = GRANT_ACCESS;
Access.grfInheritance = NO_INHERITANCE;
Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
// change these informations to grant access to a group or other user
Access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
Access.Trustee.TrusteeType = TRUSTEE_IS_USER;
Access.Trustee.ptstrName = "CURRENT_USER";
// create the new ACL
if (ERROR_SUCCESS != SetEntriesInAcl(1, &Access, OldDacl, &NewDacl))
goto cleanup;
// update ACL
retval = ERROR_SUCCESS == SetSecurityInfo(hWinlogonDesktop, SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, NewDacl,
NULL);
cleanup:
if (NewDacl)
LocalFree(NewDacl);
if (SecDesc)
LocalFree(SecDesc);
return retval;
}