Simple lightweight NTLM in PHP | Playing on the frontier

Example usage

// Using Guzzle$client = newClient();
$request = newRequest('get', '');
$user_name = 'user_name';
$password = 'password';
$target_name = 'target_name';
$host_name = 'host_name';

$encoding_converter = newMbstringEncodingConverter();
$random_byte_generator = newNativeRandomByteGenerator();
$hasher_factory = HasherFactory::createWithDetectedSupportedAlgorithms();

$negotiate_message_encoder = newNegotiateMessageEncoder($encoding_converter);
$challenge_message_decoder = newChallengeMessageDecoder();

$keyed_hasher_factory = KeyedHasherFactory::createWithDetectedSupportedAlgorithms();

$nt1_hasher = newNtV1Hasher($hasher_factory, $encoding_converter);
$nt2_hasher = newNtV2Hasher($nt1_hasher, $keyed_hasher_factory, $encoding_converter);

$authenticate_message_encoder = newNtlmV2AuthenticateMessageEncoder(

$negotiate_message = $negotiate_message_encoder->encode(

// Send negotiate message$request->setHeader('Authorization', sprintf('NTLM %s', base64_encode($negotiate_message)));
$response = $client->send($request);

// Decode returned challenge message$authenticate_headers = $response->getHeaderAsArray('WWW-Authenticate');
foreach ($authenticate_headersas$header_string) {
    $ntlm_matches = preg_match('/NTLM( (.*))?/', $header_string, $ntlm_header);

    if ( < $ntlm_matches && isset($ntlm_header[2])) {
        $raw_server_challenge = base64_decode($ntlm_header[2]);
$server_challenge = $challenge_message_decoder->decode($raw_server_challenge);

$authenticate_message = $authenticate_message_encoder->encode(

// Send authenticate message$request->setHeader('Authorization', sprintf('NTLM %s', base64_encode($authenticate_message)));


  • NTLM client message encoding and decoding
  • Multiple text-encoding native-extensions supported
  • LM, NTv1, and NTv2 hashing algorithms supported


  1. Get Composer
  2. Add robinpowered/php-ntlm to your Composer required dependencies: composer require robinpowered/php-ntlm
  3. Include the Composer autoloader


PHP-NTLM is licensed under the Apache License, Version 2.0.


  • 64-bit PHP runtime (NTLM negotiation bit flags extend beyond the 32-bit integer size)
  • PHP >=7.1.0

Simple lightweight ntlm in php | playing on the frontier

Many months ago I made a PHP script that could read NTLM authentication information from your browser. What’s NTLM? Basically, if you’re using Microsoft Windows, your browser can automatically send your windows login information to a website (if you agree to it). This means that without needing to enter additional username or passwords, you can be authenticated at the website you’re visiting. This is quite convenient especially for company intranets. NTLM should work with all major browsers (Internet Explorer, Firefox and Opera).

Похожее:  ru:auth:ldap_ad [DokuWiki]

The PHP code I wrote is simple and can be inserted into the top of any PHP script. The key output is $user $domain $workstation, which is the information advertised by the user. Be warned though, the script does NOT authenticate the user and merely assumes that the user is who they say they are. This is akin to a user entering only a username with no password required. I plan to add password/hash verification possibly in conjuction with samba in the future.

A limitation is that the PHP script relies on apache_request_headers() which is only available if you run PHP as a apache module. (Update 2022, newer code doesn’t have this issue)


// loune 25/3/2006, updated 22/08/2009
// For more information see:
// This script is obsolete, you should see

// NTLM specs

$headers = apache_request_headers();

if (!isset($headers[‘Authorization’])){
header(‘HTTP/1.1 401 Unauthorized’);
header(‘WWW-Authenticate: NTLM’);

$auth = $headers[‘Authorization’];

if (substr($auth,0,5) == ‘NTLM ‘) {
$msg = base64_decode(substr($auth, 5));
if (substr($msg, 0, 8) != “NTLMSSPx00”)
die(‘error header not recognised’);

if ($msg[8] == “x01”) {
$msg2 = “NTLMSSPx00x02x00x00x00”.
“x00x00x00x00”. // target name len/alloc
“x00x00x00x00”. // target name offset
“x01x02x81x00”. // flags
“x00x00x00x00x00x00x00x00”. // challenge
“x00x00x00x00x00x00x00x00”. // context
“x00x00x00x00x00x00x00x00”; // target info len/alloc/offset

header(‘HTTP/1.1 401 Unauthorized’);
header(‘WWW-Authenticate: NTLM ‘.trim(base64_encode($msg2)));
else if ($msg[8] == “x03”) {
function get_msg_str($msg, $start, $unicode = true) {
$len = (ord($msg[$start 1]) * 256) ord($msg[$start]);
$off = (ord($msg[$start 5]) * 256) ord($msg[$start 4]);
if ($unicode)
return str_replace(“”, ”, substr($msg, $off, $len));
return substr($msg, $off, $len);
$user = get_msg_str($msg, 36);
$domain = get_msg_str($msg, 28);
$workstation = get_msg_str($msg, 44);

print “You are $user from $domain/$workstation”;

Похожее:  nuxt-auth - npm


If you try the script in Firefox (on windows), you will notice that you get prompted for a username and password when encountering an NTLM challenge. This is because sending your windows credentials to any unscrupulous website poses a real security risk. To make it automatically use your windows credentials for sites you trust, you can add the website to a whitelist.

The whitelist is located at Firefox’s about:config (type that into the address bar), which allows the editing of all of the browser’s preferences. Find the preference entry network.automatic-ntlm-auth.trusted-uris, double click on it and type the hostname of the site (ie that you want in your whitelist. Multiple entries are seperated by commas. After doing that, Firefox should send your windows creds automatically.

Update 20/09/2009. The above script is outdated, anyone wishing to use NTLM should see the new post: Part 2 – Now with hash checking

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 5,00 из 5)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *