gpt4 book ai didi

windows - 如何执行Windows身份验证?

转载 作者:行者123 更新时间:2023-12-02 21:25:36 24 4
gpt4 key购买 nike

SQL Server,文件和打印机共享,Exchange以及许多其他应用程序都可以根据其Windows身份对用户进行身份验证。
他们怎么做到的?特别是,我该怎么做?
作为一个具体示例,请通过以下方法完成 native Windows代码:

Boolean IsCurrentUserValidForDomain(String domainName)
{
//TODO: Ask Stackoverflow to fill in the code here
}
我可以让我们开始:
Boolean IsCurrentUserValidForDomain(String domainName)
{
//Get the security token associated with the thread
TOKEN userToken;

// Get the calling thread's access token.
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, true, out userToken)
{
if (GetLastError != ERROR_NO_TOKEN)
throw new Exception("Could not get current thread security token");

// Retry against process token since no thread token exists.
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, out userToken)
throw new Exception("Could not get current process security token");
}

//We now have the security token of the running user (userToken)

//From this, we can get the SID of the user
PSID sidUser = null;

DWORD cbBuf = 0;
Boolean bsuccess = GetTokenInformation(hToken, TokenUser, null, 0, ref cbBuf);
PTOKEN_USER ptiUser = null;
while ((!bSuccess) && (GetLastError() = ERROR_INSUFFICIENT_BUFFER))
{
ReallocMem(ref ptiUser, cbBuf);
bSuccess = GetTokenInformation(hToken, TokenUser, ptiUser, cbBuf, ref cbBuf);
}
sidUser = ptiUser.User.Sid;

//Now that we have the user's SID, we can get the SID of their domain
PSID sidDomain = null;
GetWindowsAccountDomainSid(sidUser, null, ref cbBuff);
ReallocMem(sidDomain, cbBuff);
GetWindowsAccountDomainSid(sidUser, sidDomain, ref cbBuff);

//We now have
//TOKEN userToken: security token of the running user
//PSID sidUser (S-1-5-21-2154378322-3929449213-1104335884-1006)
//PSID sidDomain (S-1-5-21-2154378322-3929449213-1104335884)

//TODO: ask stackoverflow if anything i've computed so far can help
//answer the question

//TODO: Ask Stackoverflow to fill in the code here
}




注意:此处的所有内容都是“显示研究成果”。您现在可以停止阅读。我只能用它记录自己的研究工作(其中一些工作在其他情况下可能非常有用)。我还想预告一些更常见且不安全的方法(这是我陷入的陷阱)。如果我可以帮助其他任何人避免相同的陷阱,那就更好了。
背景
用户连接到SQL Server时,可以选择使用集成身份验证:

Integrated security uses the current Windows identity established on the operating system thread to access the SQL Server database


以及来自SQL Server的更多信息:

When a user connects through a Windows user account, SQL Server validates the account name and password using the Windows principal token in the operating system. This means that the user identity is confirmed by Windows. SQL Server does not ask for the password, and does not perform the identity validation.


结果:我可以登录SQL Server,而无需键入用户名和密码
如果我连接到远程网络共享,则将使用我自己的用户凭据来验证我是远程服务器上的用户。我可以浏览到远程计算机,并且该连接隐式使用我登录的用户帐户来验证访问。
结果:我无需输入用户名和密码即可连接到网络共享。
SQL Server如何验证我作为用户的身份?
文件和打印机共享如何验证我作为用户?
可以说我正在编写自己的数据库引擎,并且想支持 “Windows身份验证” 怎么办?
可以说我的SQL数据库引擎正在使用本地用户帐户在未加入域的PC上运行。我 可以获得有关它们的各种信息
本地用户
  • GetUsername:ginger
  • GetUsernameEx(NameSamCompatible):HYDROGEN\Ginger(氢是机器的名称)
  • GetTokenInformation(TokenUser):UserSID = S-1-5-21-2154378322-3929449213-1104335884-1006
  • LookupAccountSid
  • 用户名:Ginger
  • 域:HYDROGEN

  • GetWindowsAccountDomainSid:S-1-5-21-2154378322-3929449213-1104335884

  • 可以说,我的SQL数据库引擎正在使用域用户帐户的域加入PC上运行(并且有趣的是,用户来自与计算机加入域不同的域)。我 可以获得有关用户的各种信息:
  • GetUsername:forest
  • GetUsernameEx(NameSamCompatible):CONTOSO\forest(contoso是域的旧版,SAM兼容的NetBIOS名称。实际的域名是contoso.com)
  • GetTokenInformation(TokenUser):UserSID = S-1-5-21-1708537768-854245398-2146844275-3110
  • LookupAccountSid
  • 用户名:forest
  • 域:CONTOSO

  • GetWindowsAccountDomainSid:S-1-5-21-1708537768-854245398-2146844275

  • 这里是否有足够的信息来正确实现 Windows Authentication
    SQL Server如何做到这一点?资源管理器是如何做到的? Internet Explorer和IIS怎么做?
    是否没有一些流行词,例如 Ticket-Granting-Ticket我必须包括在内?
    坏主意
    我有一些不好的,不安全的想法。我想了为什么不只接受 GetUsernameEx 返回的名称
    CONTOSO\forest
    并将其分为两部分:
    Username: forest
    Domain: CONTOSO
    这样,我 会知道,该用户实际上是 CONTOSO 域中的用户 。我知道这确实是 contoso\forest ,因为Windows在登录时验证了其凭据。
    除了没有因为用户可以在其独立的,非域加入的笔记本上将其工作组的名称从 HYDROGEN更改为 CONTOSO。现在,当我阅读他们的用户名时:
    CONTOSO\forest
    我相信他们是:

    forest of the CONTOSO domain


    实际上,它们是:

    forest of a standalone machine


    好的,所以使用SID
    由于我不信任各种Windows函数返回的“域名”,因此我可以使用用户的 SID :

    domain user contoso\forest: S-1-5-21-1708537768-854245398-2146844275-3110


    独立PC上的用户无法伪造它,对吗?正确的? :(
    是的他们可以:

    local user hydrogen\ginger: S-1-5-21-1708537768-854245398-2146844275-3110


    你知道我要去哪里吗?我正在尝试 发明一种执行身份验证的方法-失败了。同时,Windows和SQL Server团队都已经在20年前解决了这个问题。戴夫·卡特勒(Dave Cutler)在1994年设计了该系统,并确切地知道我应该做什么。
    我只是不知道那是什么。
    用户SID不用于身份验证
    在研究中,我发现了一些有趣的概念。例如域的SID是成为域 Controller 的第一台计算机的计算机SID。我还发现该域中的用户是域SID的后缀:

    Machine SIDs and Domain SIDs

    | Machine SID for computer DEMOSYSTEM | S-1-5-21-3419697060-3810377854-678604692      |
    | DEMOSYSTEM\Administrator | S-1-5-21-3419697060-3810377854-678604692-500 |
    | DEMOSYSTEM\Guest | S-1-5-21-3419697060-3810377854-678604692-501 |
    | DEMOSYSTEM\CustomAccount1 | S-1-5-21-3419697060-3810377854-678604692-1000 |
    | DEMOSYSTEM\CustomAccount2 | S-1-5-21-3419697060-3810377854-678604692-1001 |

    On a workgroup system, local accounts and groups are all there are. Authentication to a remote system using a local account requires a user name and password known to the remote system, and that SIDs are not used. The only way anything resembling single sign on happens with local accounts is that if the remote system has the same user name and password that the caller is using. SIDs are not transmitted and are not used for remote authentication.


    这是重要的一点,您必须意识到重复的SID是 完全有效的。 SID在使用它们的权限内必须唯一。因此,尽管DEMOSYSTEM必须仅具有一个SID为S-1-5-21-3419697060-3810377854-678604692-1000的本地帐户,但是另一台计算机是否使用相同的SID来引用自己的本地帐户也没关系。
    这是有道理的,并强化了以下观点:授权用户而不是其SID是 凭据
    这就是为什么我的另一个想法糟透了
    SQL Server通过SID将Windows登录名存储在 syslogins表中:
    sid                                                         name            isntuser
    ---------------------------------------------------------- -------------- ---------
    0x010500000000000515000000A837D66516C0EA32733EF67F260C0000 CONTOSO\forest 1
    我的SQL数据库引擎无法读取当前用户的SID并检查它是否存在于 syslogins表中,因为可以有多个具有相同sid的用户通过TCP端口1434连接到我的数据库引擎。
    Windows将凭据存储在某处
    我正在阅读有关针对NTML和Kerberos的“传递哈希”攻击的信息。 There was one interesting snippet:

    Windows caches the hashed passwords in memory to implement Single Sign On or SSO, which is an essential feature of Windows enterprise environments.


    我只需要弄清楚如何说服Windows告诉我用户是否真的是 domain\BillG
    Chrome和Windows资源管理器中的Windows身份验证
    Chrome能够将Windows credentails透明地提供给要求它们的人。如果我要在服务器上请求,则服务器将拒绝我访问(401)并指示我应使用 Negotiate身份验证:
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Negotiate
    然后,我的客户执行一些魔术操作,然后重新发出请求,这次附加了我的身份:
    GET http://contoso.com/foo HTTP/1.1
    Authorization: Negotiate YIIFzwYGKwYBBQUCoIIFwzCCBb+gMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHgYKKwYBBAGCNwICCqKCBYkEggWFYIIFgQYJKoZIhvcSAQICAQBuggVwMIIFbKADAgEFoQMCAQ6iBwMFACAAAACjggP4YYID9DCCA/CgAwIBBaEOGwxBVkFUT1BJQS5DT02iJTAjoAMCAQKhHDAaGwRIVFRQGxJ2YWRlci5hdmF0b3BpYS5jb22jggOwMIIDrKADAgEXoQMCATCiggOeBIIDmjMA0SnAUdqmbf8+UXZHsipRqPKt2yxqQaFia8hBF3TuQVDBgqGk8yL+CoDGnvkyGqpZK3UBsS/EuXP4Z+/0y49ZyDDQnDFqcJpF5ZY87t+u/kYQy+dr42GxEYQIjb096AQzDZio0dRWqbHleS5DlR7wCEaJ+a0CG6/vLEXL6tT20aj3avFibZc++5OKhynoxtyh10tJO3iwun2usJT+p1IfTD9yVDhfplMchLBgyp803+6IUwzm0zcwcqt7R1KnCv1i+baw3e/dhkIJz8cnoh1oNuivSXf4zOqlvp8FDlQMQEGqa9OA7LBmhg1rWDTOdyB4E9oZtVG8ipHyFYzDcyvIpWOMf9S68TTE78TgEhWjVq7g6BoH+O6IW14QIItxVk1GbSd2Ke9n9We0pbMjRxiZIMqyOvvFBgU5NlUUksdlG/yv0BTai7SILbVfNPsVwHeus//UfKQenX6YEnKUVi+XutY0kjLyp6l1L3Ce/ovkpDVmmYFebfdIT8Xbya9Zksa2nF8+7OL5S7I0tZaZUBL2Bzca9VJiGioRFvpgBXxKiChv71SukROreic+ylxHOfOWwXsEa0+ISHV6Uvhd44y3UA2VKtI3xoF8+3SZ184hIZ4fbahkfrBa1Zu5FqQ9M0rxAPgmsBZ2PwuMDWWLtraK7gJsAh+DxXGAaSTiPWaRhms59mfetBmzSnkzWBCr63G8rL71TiDgevoxhv0FP5s1JmWzWsnluJ95f9fphItuiDRI0C1358LMai9B1ZFWf9CRooeMAH4YUuL4SZ0r61/zQVnWFF1ngyt/ko/9UQ3mErLFeA/9Oq6BYfI/ExhVl9VVue0irM1vk09pIdUMS9MvQdW7YCg/C9LtOiJVpYw/aEVakn74l7TM71bIfjucDddDCBNuup41bWy5Nqkci8AHEMyoVyG9BxHmTm8NZ3FSujl+MeDAANKSt3a6P2k0C/W4Mley76ZoAGf6IYXf/9THQucvQGkasUkIN6PwIZIaxEdVt1BXiVXu1ADgt2/+0UB8rzYq+kt53R16rjev4Exvt7jpHIWUxjbDTxo2CvW0+Eh+mFyMj3CS2xQlhjrU2Q9ADQqA8wf8H88Dzp4PPWPxJnB4tC+Ecd9ZYlQwal00UX6aN47+dKPYDCp4piq6dvr2BhpzpsXxyR8QOZRKqAoXXLmb4Y1eGFWiUqH56J3Wju5h+cyzhMq+otpI4s77lfIecM41HccPrTKkggFZMIIBVaADAgEXooIBTASCAUigcKId1qR+UzSz8R00q+0o2M4+2dLnNW2vPU+uLeG9SqLJgJWsgBWUGtt6TRvPLF/GoHxP+sqST8fKJf0EHfycGfH/VJR6bnfpQYCWCgWRHjfdUpll51G/xKYqJYyy5xtNQvtKkzp+IB6CVKe1q3wopAY+uDsUk9XUvaIbUtHDEcWDATwi8BKGggVunw/idxKaZjaRmRko/Nsj5p38fiBk+OCN3yKDNSFCTDn+HUiCoCbDsv03zt2EO1eTJUPxXNhqJUjZMKYodgcsLMzNhSiyySH+kvgQZci3b8LGY1sCHMXopaL0Ysu4QgPD8UDD7dIBZ0ORmGf9srdZMgKjLIoEhXOmg+y5kqJpoPAwQaooHDizKQ8bmhFX2pOp7NjXoJ/wRvTB98seUNlDXDl5ySrt7P3Xf1Ybj7PpgMuqJykou2lKxirVhYYJ
    IE和Chrome都可以转身并执行某些操作,以证明我是我的身份。没有记录Windows身份验证的方式,但是有一些提示。从 MSDN: HTTP-Based Cross-Platform Authentication via the Negotiate Protocol Part I - Network Infrastructure:
  • 登录的用户从Web服务器请求资源时,它将发送初始HTTP GET动词。
  • 运行SPNEGO token 处理程序代码的Web服务器需要身份验证,并发出“拒绝401访问,WWW身份验证:协商”响应。
  • 客户端使用SPN调用 AcquireCredentialsHandle() InitializeSecurityContext() 来构建安全上下文,以从TGS/KDC请求 session 票证。
  • TGS/KDC为客户提供包装在SPNEGO token 中的必需的Kerberos票证(假设客户机已被授权)。
  • 客户端在授权中重新发送HTTP GET请求+ Negotiate SPNEGO token :Negotiate base64(token) header 。
  • Web服务器的SPNEGO token 处理程序代码通过GSS API接受并处理 token ,对用户进行身份验证并使用请求的URL进行响应。

  • 因此,客户可以使用一些代码来生成证明自己是谁的证明。这意味着我可以通过某种方式在客户端上生成域用户证明自己是域用户的证明。
    当然,我不需要将来自Kerberos的票证打包到一个加密的,以64为基数的SPNEGO blob中。我只需要正确的API调用(以正确的顺序)即可知道我是谁。

    最佳答案

    经过澄清后,可以在Windows和Unix上使用SSPI和GSS-API轻松实现。

  • 在目标主机
  • 上注册服务的SPN

    客户观点:
  • 在您的应用程序/客户端中将C/C++与SSPI/GSS-API一起使用。
  • 获取当前用户的凭据句柄(出站/启动器)。 GetUsername...不是必需的。
  • 为给定机制创建SSPI/GSS上下文。 Kerberos或SPNEGO。

  • 服务器 View :
  • 在目标主机/服务器上将C/C++与SSPI/GSS-API一起使用。
  • 获取SPN绑定(bind)到的机器/服务帐户的凭据句柄(入站/接受者)。 GetUsername...不是必需的。

  • 客户观点:
  • 让上下文生成一个不透明的 token ,并通过套接字
  • 将其发送到服务器

    服务器 View :
  • 接受该 token 并做出响应。
    ...循环重复,直到上下文建立为止。
  • 查询已认证用户的上下文属性,例如michael-o@STACKOVERFLOW.COM
  • 处置上下文和凭证句柄

  • 客户观点:
  • 处置上下文和凭证句柄
  • 在经过身份验证的套接字上执行通信

  • 安全建议:不要依赖stoneage NTLM,请尽可能使用Kerberos。也请始终使用UPN。

    关于windows - 如何执行Windows身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30900052/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com