php-ntlm icon indicating copy to clipboard operation
php-ntlm copied to clipboard

Simple NTLMv2 without hash/auth/verify

Open orachas opened this issue 7 years ago • 4 comments

I am a longtime user of your original NTLM script in my workflow application. I just need to pull the Windows username from a Type 3 response, and I don't care about secure authentication, hashes, etc.

I am hearing from coworkers that our Win10 upgrade will only allow NTLMv2 in an HTTP session, and that your original script won't work. I don't see in the ntlm.html protocol document how the Type 3 message in HTTP auth differs from v1 to v2. I have read elsewhere that the Type 3 is encrypted with the client's password hash (unsure on this).

Can I simply extract the username in v2 without using your setuid binary or otherwise involving an Active Directory server?

Many, many thanks for any information you might provide.

orachas avatar Sep 21 '17 17:09 orachas

I pulled your Type 2 message from the new code and put it in the old version. It works on Win7.

However, under Win10, it fails completely with "WWW-Authenticate: NTLM" - I do get a Type 1 message with "WWW-Authenticate: Negotiate" but it fails after I send any Type 2.

orachas avatar Sep 22 '17 17:09 orachas

Yes you should be able to use the v2 code for getting the username without verifying the password. I haven't got Win 10, so I can't test and see what's wrong with it. It's been a while since I touched the script but I suspect win 10 might be using a new hashing method that the script doesn't support. When I get a bit of time, I might install win 10 on a VM and test it out.

loune avatar Sep 27 '17 04:09 loune

My webapps were tested in Win10 with your original code several months ago, and everything worked. Then I got a helpful message that "There is a policy setting for minimum session security for NTLM SSP based clients, and [my app] doesn’t meet the NTLMv2 session security requirement... [Our] advice would be to either ensure it’s using NTLMv2 and compatible with security requirements or upgrade to SPNEGO, which is a more current protocol."

It is pretty annoying that PHP still uses HTTP/1.0 in plenty of places, but I'm getting the NTLM rug ripped out from underneath me.

I've written a replacement that forces the user to provide their NT login and password, then checks it as an LDAP login against the local domain controller. This is inconvenient because I need TLS everywhere now. Here is that basic code, in case anybody finds it useful:

# cat /var/www/html/ntlm.php <?php if($_SERVER['REMOTE_ADDR'] != '127.0.0.1') // stunnel die('App must now be accessed over https/TLS.');

if(!session_start()) die('App cookie error.');

if(!isset($_SESSION['NTLM_user'])) { error_reporting(0);

function auth () { header('WWW-Authenticate: Basic realm="MyApp"'); header('HTTP/1.0 401 Unauthorized'); die('Your windows account and password are now required.'); }

if(!isset($_SERVER['PHP_AUTH_USER'])) auth(); if(!$ds = ldap_connect('127.0.0.1', 12485)) auth(); if(!$r = ldap_bind($ds, $_SERVER['PHP_AUTH_USER'] . '@mydomain.com', $_SERVER['PHP_AUTH_PW'])) auth();

$_SESSION['NTLM_user'] = strtoupper($_SERVER['PHP_AUTH_USER']);

unset($_SERVER['PHP_AUTH_PW']);

ldap_unbind($ds); }

$NTLM_user = $_SESSION['NTLM_user'];

?>

I'm using stunnel on all sides (the verify options are really flexible, and it can chroot() the TLS engine). Here is the stunnel conf that goes to the domain controller:

# cat /etc/stunnel/ms-ldap-ssl.conf sslVersion = TLSv1.2 FIPS = no debug = debug options = NO_SSLv2 options = NO_SSLv3 curve = secp521r1 options = SINGLE_DH_USE options = SINGLE_ECDH_USE options = CIPHER_SERVER_PREFERENCE

; UNIX-only high-security isolation, not available on MS-Windows setuid = nobody setgid = nobody chroot = /var/empty

; Under inetd mode, no accept rules or service definitions, just a connect. client = yes connect = domaincontroller.mydomain.com:636 verify = 2 CAfile = /etc/stunnel/mydomain.pem

; best ciphers https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ ciphers=ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

orachas avatar Sep 27 '17 15:09 orachas

Hi @loune , I'm using your original NTLM Script like orachas, to get the Windows username. And it worked fine, thanks! Now Win10 is coming, and it doesn't work. Did you find a way to get only the username from a Win10 Client?

sadmarvin84 avatar Apr 25 '19 09:04 sadmarvin84