代码之家  ›  专栏  ›  技术社区  ›  Neil

使用NTLM检查LDAP/active directory中的用户凭据

  •  0
  • Neil  · 技术社区  · 3 年前

    我有一个apachephp服务器,我正试图在其中使用现有的活动目录来实现权限。

    我们选择NTLM来自动对windows用户进行身份验证,这一部分似乎正在工作,我正在检索用户名和NTLM挑战的答案。

    我正在使用PHP ldap函数与active directory通信(与服务帐户),到目前为止,我可以检索用户组并检查用户名是否存在,但我无法作为用户进行连接以验证密码: $success = @ldap_bind($ad, "$username@$domain}", $password) or die('Could not bind to AD.');

    在这里,我可以使用明文密码进行连接,但只有所谓的“NTLM响应安全缓冲区”。

    有可能将NTLM和LDAP链接起来吗?如何链接? 是PHP吗 ldap_bind 根本不支持NTLM?


    我读过 here 可以将质询和用户NTLM响应作为“NETLOGON_NETWORK_INFO”进行传输,但我找不到任何相关文档。

    我还发现 a laravel library 声称要这么做,但查看代码,我发现了我已经测试过的内容: @ldap_bind 需要明文密码。

    我的问题可能类似于 this unanswered question ,但很少有结果将LDAP和NTLM关联起来。


    以下是我接手该项目时服务器上的NTLM实现:

    $headers = apache_request_headers();
    
    if (@$_SERVER['HTTP_VIA'] != NULL) {
        //echo "Proxy bypass!";
    }
    elseif(!isset($headers['Authorization']) || $headers['Authorization'] == NULL) {
        header( "HTTP/1.0 401 Unauthorized" );
        header( "WWW-Authenticate: NTLM" );
        exit;
    }
    
    if(isset($headers['Authorization']) && substr($headers['Authorization'],0,5) == 'NTLM ') {
        $chaine    = substr($headers['Authorization'], 5);
        $chained64 = base64_decode($chaine);
    
        if(ord($chained64[8]) == 1) {
            $retAuth   = "NTLMSSP".chr(000).chr(002).chr(000).chr(000).chr(000).chr(000).chr(000).chr(000);
            $retAuth   .= chr(000).chr(040).chr(000).chr(000).chr(000).chr(001).chr(130).chr(000).chr(000);
            $retAuth   .= chr(000).chr(002).chr(002).chr(002).chr(000).chr(000).chr(000).chr(000).chr(000);
            $retAuth   .= chr(000).chr(000).chr(000).chr(000).chr(000).chr(000).chr(000);
            $retAuth64 = trim(base64_encode($retAuth));
    
            header( "HTTP/1.0 401 Unauthorized" );
            header( "WWW-Authenticate: NTLM $retAuth64" );
            exit;
        }   
        if(ord($chained64[8]) == 3) {
            //LM Response Security Buffer: 
            $lenght_LMRSB = (ord($chained64[15])*256 + ord($chained64[14]));
            $offset_LMRSB = (ord($chained64[17])*256 + ord($chained64[16]));
            $LMRSB = str_replace("\0","",substr($chained64, $offset_LMRSB, $lenght_LMRSB));
        
            //NTLM Response Security Buffer:
            $lenght_NTLMRSB = (ord($chained64[23])*256 + ord($chained64[22]));
            $offset_NTLMRSB = (ord($chained64[25])*256 + ord($chained64[24]));
            $NTLMRSB = str_replace("\0","",substr($chained64, $offset_NTLMRSB, $lenght_NTLMRSB));
    
            //Domain:
            $lenght_domain = (ord($chained64[31])*256 + ord($chained64[30]));
            $offset_domain = (ord($chained64[33])*256 + ord($chained64[32]));   
            $domain = str_replace("\0","",substr($chained64, $offset_domain, $lenght_domain));
    
            //Login:
            $lenght_login = (ord($chained64[39])*256 + ord($chained64[38]));
            $offset_login = (ord($chained64[41])*256 + ord($chained64[40]));
            $login = str_replace("\0","",substr($chained64, $offset_login, $lenght_login));
    
            echo "$LMRSB<br>";
            echo "$NTLMRSB<br>";
    
            //HERE i would like to verify credentials against my active directory before accepting the username as a real logged user
            $_SESSION["utilisateur"] = $login;
        }
    }
    
    0 回复  |  直到 3 年前
        1
  •  2
  •   grawity_u1686    3 年前

    我们选择NTLM来自动对windows用户进行身份验证,这一部分似乎正在工作,我正在检索用户名和NTLM挑战的答案。

    无法通过LDAP绑定验证NTLM响应。

    我的意思是,严格来说你 可能 可以将挑战和响应中继到SASL NTLM绑定,但这实际上与您的安全团队通常想要的“NTLM中继攻击”类型相同 防止 防止发生。如果已启用必要的强化选项,则将为特定服务SPN发出NTLM响应,LDAP服务器将拒绝该响应。因此,即使这在理论上是可能的,依赖它继续成为可能也是非常不明智的(甚至比最初使用NTLM更不明智)。

    我在这里读到,可以将质询和用户NTLM响应作为“NETLOGON_NETWORK_INFO”进行传输,但我找不到任何相关文档。

    是的,但这样做需要一个现有的“Netlogon安全通道”,并且 那个 需要一个计算机帐户。

    通常的方法是安装Samba(特别是Winbind组件),然后将web服务器连接到域(这就是建立Netlogon通道的原因),这时您就可以使用 ntlm_auth CLI工具,通过让Winbind通过Netlogon协议将NTLM质询中继到DC,以“官方”方式验证NTLM质询。

    (你实际上不需要在你的网络服务器上安装“用户身份验证”部分(pam_winbind/nssswitch),以防你担心用户SSHing进入服务器;您只需要守护程序。)

    然而,我会 非常强烈 建议不要做任何涉及NTLM的事情。你有 Active Directory, 并且Active Directory具有Kerberos 自2000年以来。 HTTP支持Kerberos身份验证,就像它支持NTLM一样,而且您甚至不需要自己滚动它。您只需要 mod_auth_gssapi Apache模块(或较旧的模块 mod_auth_kerb )和一个keytab,并且web服务器将完成所有的工作;您可以从中获取用户名 $_SERVER["REMOTE_USER"] 在PHP脚本中。

    (Kerberos票证的验证甚至不需要联系KDC,也没有任何服务正在运行,也没有特殊的特权通道;只有一个包含Web应用程序服务用户帐户密码的密钥选项卡。)

    推荐文章