Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
NTLMv2 Authentication with nginx.
<?php
define('PROXY', 'proxy');
define('PORT', 8080);
if (!function_exists('getallheaders'))
{
function getallheaders()
{
$headers = [];
foreach ($_SERVER as $name => $value)
{
if (substr($name, 0, 5) == 'HTTP_')
{
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}
}
$headers = getAllHeaders(); // Equivalent to apache_request_headers() to get the headers of the request.
if(!isset($headers['Authorization'])) // Check Authorization Header
{
header('HTTP/1.1 401 Unauthorized'); // Return Unauthorized Http-Header (NTLM protocol)
header('WWW-Authenticate: NTLM'); // Authenticcation Information (NTLM protocol)
}
else
{
if(substr($headers['Authorization'],0,4) == 'NTLM') // Check whether Authorization Header is valid
{
$message = base64_decode(substr($headers['Authorization'], 5)); // Get NTLM Message from Authrization header
if(substr($message, 0, 8) == "NTLMSSP\x00") // Check whether NTLM Message is valid
{
if($message[8] == "\x01") // Check whether it's type-1-NTLM Message
{
// $message holds the base64 encoded type-1-NTLM message
$ch = curl_init(); // Use cURL to connect to web via proxy
curl_setopt($ch, CURLOPT_URL, "http://www.google.com");
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: {$headers['Authorization']}"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# curl_setopt($ch, CURLOPT_VERBOSE, 1);
# curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_PROXY, PROXY);
curl_setopt($ch, CURLOPT_PROXYPORT, PORT);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$header = substr($result, 0, $info['header_size']);
$body = substr($result, $info['header_size'], $info['download_content_length']-$info['header_size']);
$c_headers = explode("\r\n", $header);
for($i = 0; $i < (count($c_headers) - 2); $i++)
{
header($c_headers[$i]);
if(substr($c_headers[$i], 0, 16) == "WWW-Authenticate")
{
echo 'Type 2';
// Thats your type-2-message header Format: WWW-Authenticate: NTLM <base64-type-2-message>
}
}
var_dump($result);
var_dump($c_header);
}
else if ($message[8] == "\x03") // Check whether it's type-3-NTLM Message
{
$ch = curl_init(); // Use cURL to connect to web via proxy
curl_setopt($ch, CURLOPT_URL, "http://www.google.com");
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: {$headers['Authorization']}"));
curl_setopt($ch, CURLOPT_PROXY, PROXY);
curl_setopt($ch, CURLOPT_PROXYPORT, PORT);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if($info['CURLINFO_HTTP_CODE'] == 200)
{
echo 'Type 3';
// Authenticated
// $msg holds the base64 encoded type-3-NTLM message (which includes username, domain, workstation)
}
}
}
}
}
?>

intel352 commented Sep 1, 2016

How is this "with nginx"? Rather should be "with PHP", as otherwise you'd be configuring some nginx config to handle NTLM...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment