在带有 UAC 的 Vista 上使用带有 Windows AccessCheck() 的 SSPI (NTLM) Api
Posted
技术标签:
【中文标题】在带有 UAC 的 Vista 上使用带有 Windows AccessCheck() 的 SSPI (NTLM) Api【英文标题】:Using SSPI (NTLM) Api's With Windows AccessCheck() On Vista With UAC 【发布时间】:2008-10-22 13:38:29 【问题描述】:总结 客户端 (Windows XP SP3) 服务器(Windows Vista Business SP1)/作为本地系统服务运行
API 序列 客户端 - AcquireCredentialsHandle 客户端 - 初始化安全上下文 服务器 - Acquirecredentialhandle 服务器 - AcceptSecurityContext 客户端/服务器 - CompleteAuthnToken 服务器 - ImpersonateSecurityContext 服务器 - AccessCheckAndAuditAlarm (MAXIMUM_allowed) 服务器 - 然后我将请求的访问权限与允许的访问权限进行比较。
我对使用 createprivateobjectsecurityex 创建的私有安全对象调用访问检查。打开 Uac 后,我从 accesscheck 中获得了成功,但没有任何特权被保留。关闭 uac 后,我可以通过 GantedAccess 参数中的所有权限恢复成功
详情 该应用程序有两个组件,一个客户端和一个服务器。它 使用 tcp 通过不安全的网络进行通信。到认证 我使用上面列出的 sspi api 的传入连接,以及 冒充主叫用户。一旦主叫用户被冒充,我 使用 Accesscheckandauditalarm,如果失败,我将恢复为 访问检查。打开 UAC 后,我从 accesscheckandauditalarm 但没有任何访问权限在 grandedaccess 参数,但如果 uac 关闭,它会按预期工作。 我检查了服务器进程的完整性级别并设置了 到高,我查看了模拟令牌的完整性级别 用于模拟主叫用户,设置为中。我有 尝试将调用用户的完整性级别设置为高, 成功,但访问检查仍然返回不正确的结果。 想我可能有一个链接令牌我尝试了链接令牌 调用 GetTOkenInformation(TokenLInkedToken) 结果为 0x520。 任何关于我下一步可能尝试的想法将不胜感激。
验证后的代码。
SECURITY_STATUS ss = SEC_E_OK;
HANDLE _hToken = NULL;
ss = QuerySecurityContextToken((PCtxtHandle)pContext,&_hToken);
if(SEC_E_OK != ss)
return ss;
CAccessToken impToken;
impToken.Attach(_hToken);
if(CWin32::IsVista())
/*TOKEN_LINKED_TOKEN linkedToken;
DWORD nLen = 0;
BOOL bRet = GetTokenInformation(_hToken,
(TOKEN_INFORMATION_CLASS)TokenLinkedToken,&linkedToken,sizeof(linkedToken), &nLen);
if(bRet)
CloseHandle(impToken.Detach());
impToken.Attach(linkedToken.LinkedToken);
else
TRACE(_T("GetTokenInfo Failed 0x%x\n"),GetLastError());
*/
PSID pHighIntegritySid = NULL;
BOOL bConvertSid = FALSE;
bConvertSid = ConvertStringSidToSid(SDDL_ML_HIGH,
&pHighIntegritySid);
if (bConvertSid)
TOKEN_MANDATORY_LABEL TML = 0;
TML.Label.Attributes = SE_GROUP_INTEGRITY |
SE_GROUP_INTEGRITY_ENABLED;
TML.Label.Sid = pHighIntegritySid;
BOOL bSetTokenRet = SetTokenInformation(_hToken,
(TOKEN_INFORMATION_CLASS)TokenIntegrityLevel,&TML,sizeof(TML) +
GetLengthSid(pHighIntegritySid));
LocalFree(pHighIntegritySid);
if(!bSetTokenRet)
nReturn = GetLastError();
DBGOUT(DebugOut::LOG_COMP_AUTH_LAYER,DebugOut::LOG_DETAIL_ERROR,
_T("Failed to set Token information %x\n"),nReturn);
return nReturn;
bool bRet = impToken.Impersonate();
if(false == bRet)
return GetLastError();
_GetTokenSecurityLevel(impToken.GetHandle());
::MapGenericMask(&nRights, GetGENERIC_MAPPING());
DWORD nAccessGranted = 0;
BOOL bAccessStatus = FALSE;
BOOL bGenerateOnClose = FALSE;
BOOL bAccessCheckRet = FALSE;
bAccessCheckRet = ::AccessCheckAndAuditAlarm(_T("Purgos
Security"),impToken.GetHandle(),_T("Purgos"),m_csObjectName.GetBuffer(0),
const_cast<SECURITY_DESCRIPTOR*>(m_ObjectSD.GetPSECURITY_DESCRIPTOR())/
*privObjectSD.GetPSECURITY_DESCRIPTOR())*/,MAXIMUM_ALLOWED,GetGENERIC_MAPPI NG(),FALSE,&nAccessGranted,&bAccessStatus,&bGenerateOnClose);
【问题讨论】:
【参考方案1】:为所有相关方找到解决方案。
问题在于被验证的用户是本地帐户,并且默认情况下本地帐户具有过滤令牌,其中 BUILTIN\Administrators 组具有拒绝 ACL。我正在检查 BUILTIN\Administrators 组的权限。所以不得不设置注册表设置或使用域帐户。
瑞恩
【讨论】:
以上是关于在带有 UAC 的 Vista 上使用带有 Windows AccessCheck() 的 SSPI (NTLM) Api的主要内容,如果未能解决你的问题,请参考以下文章
Vista UAC下应用程序标注为“需要管理员权限”的四种方法