apache 使用NTLM检查LDAP/Active Directory中的用户凭据

lstz6jyr  于 2023-06-24  发布在  Apache
关注(0)|答案(1)|浏览(172)

我有一个Apache PHP服务器,我试图使用现有的活动目录实现权限。
我们选择了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;
    }
}
ddrv8njm

ddrv8njm1#

我们选择了NTLM来自动验证Windows用户,这部分似乎工作,我正在检索用户名和NTLM挑战的答案。
无法通过LDAP绑定验证NTLM响应。
我的意思是,从技术上讲,您可能可以将挑战和响应中继到SASL NTLM绑定,但这实际上与您的安全团队通常希望防止发生的“NTLM中继攻击”相同。如果启用了必要的强化选项,则将为特定服务SPN发出NTLM响应,并且该响应将被LDAP服务器拒绝。因此,即使在理论上是可能的,依赖于它继续是可能的也是非常不明智的(甚至比首先使用NTLM更不明智)。
我在这里读到一个可以传输挑战和用户NTLM响应作为“NETLOGON_NETWORK_INFO”,但我找不到任何文档的方式这样做。
是的,但这样做需要现有的“Netlogon安全通道”,并且 that 需要计算机帐户。
通常的方法是安装桑巴舞(特别是Winbind组件)并将Web服务器加入域(这是建立Netlogon通道的地方),此时您将能够使用ntlm_auth CLI工具以“官方”方式验证NTLM挑战,方法是让Winbind通过Netlogon协议将它们中继到DC。
(You实际上不需要在你的web服务器上安装“用户身份验证”部分(pam_winbind/nsswitch),以防你担心用户会通过SSHing进入服务器;你只需要守护进程。)
但是,我强烈建议不要做任何涉及NTLM的事情。你有 Active Directory, Active Directory从2000年起就有Kerberos**。**HTTP支持Kerberos身份验证,就像它支持NTLM一样,你甚至不需要自己滚动它-你所需要的只是mod_auth_gssapi Apache模块(或旧的mod_auth_kerb)和一个keytab,Web服务器将完成所有工作;你可以在PHP脚本中从$_SERVER["REMOTE_USER"]中获取用户名。
(Kerberos票据的验证甚至不需要联系KDC,也没有任何服务运行,也没有特殊的特权通道;只是一个keytab,其中包含webapp的服务用户帐户的密码。)

相关问题