PageRenderTime 81ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php

https://gitlab.com/ealexis.t/trends
PHP | 726 lines | 380 code | 90 blank | 256 comment | 33 complexity | 30bf67a7d6390d916d1e9101efd767d8 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * This authentication is for Exchange servers. We support version 1 & 2.
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. /**
  12. * Handles NTLM authentication.
  13. *
  14. * @author Ward Peeters <ward@coding-tech.com>
  15. */
  16. class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Esmtp_Authenticator
  17. {
  18. const NTLMSIG = "NTLMSSP\x00";
  19. const DESCONST = 'KGS!@#$%';
  20. /**
  21. * Get the name of the AUTH mechanism this Authenticator handles.
  22. *
  23. * @return string
  24. */
  25. public function getAuthKeyword()
  26. {
  27. return 'NTLM';
  28. }
  29. /**
  30. * Try to authenticate the user with $username and $password.
  31. *
  32. * @param Swift_Transport_SmtpAgent $agent
  33. * @param string $username
  34. * @param string $password
  35. *
  36. * @return bool
  37. */
  38. public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
  39. {
  40. if (!function_exists('mcrypt_module_open')) {
  41. throw new LogicException('The mcrypt functions need to be enabled to use the NTLM authenticator.');
  42. }
  43. if (!function_exists('openssl_random_pseudo_bytes')) {
  44. throw new LogicException('The OpenSSL extension must be enabled to use the NTLM authenticator.');
  45. }
  46. if (!function_exists('bcmul')) {
  47. throw new LogicException('The BCMatch functions must be enabled to use the NTLM authenticator.');
  48. }
  49. try {
  50. // execute AUTH command and filter out the code at the beginning
  51. // AUTH NTLM xxxx
  52. $response = base64_decode(substr(trim($this->sendMessage1($agent)), 4));
  53. // extra parameters for our unit cases
  54. $timestamp = func_num_args() > 3 ? func_get_arg(3) : $this->getCorrectTimestamp(bcmul(microtime(true), '1000'));
  55. $client = func_num_args() > 4 ? func_get_arg(4) : $this->getRandomBytes(8);
  56. // Message 3 response
  57. $this->sendMessage3($response, $username, $password, $timestamp, $client, $agent);
  58. return true;
  59. } catch (Swift_TransportException $e) {
  60. $agent->executeCommand("RSET\r\n", array(250));
  61. return false;
  62. }
  63. }
  64. protected function si2bin($si, $bits = 32)
  65. {
  66. $bin = null;
  67. if ($si >= -pow(2, $bits - 1) && ($si <= pow(2, $bits - 1))) {
  68. // positive or zero
  69. if ($si >= 0) {
  70. $bin = base_convert($si, 10, 2);
  71. // pad to $bits bit
  72. $bin_length = strlen($bin);
  73. if ($bin_length < $bits) {
  74. $bin = str_repeat('0', $bits - $bin_length).$bin;
  75. }
  76. } else {
  77. // negative
  78. $si = -$si - pow(2, $bits);
  79. $bin = base_convert($si, 10, 2);
  80. $bin_length = strlen($bin);
  81. if ($bin_length > $bits) {
  82. $bin = str_repeat('1', $bits - $bin_length).$bin;
  83. }
  84. }
  85. }
  86. return $bin;
  87. }
  88. /**
  89. * Send our auth message and returns the response.
  90. *
  91. * @param Swift_Transport_SmtpAgent $agent
  92. *
  93. * @return string SMTP Response
  94. */
  95. protected function sendMessage1(Swift_Transport_SmtpAgent $agent)
  96. {
  97. $message = $this->createMessage1();
  98. return $agent->executeCommand(sprintf("AUTH %s %s\r\n", $this->getAuthKeyword(), base64_encode($message)), array(334));
  99. }
  100. /**
  101. * Fetch all details of our response (message 2).
  102. *
  103. * @param string $response
  104. *
  105. * @return array our response parsed
  106. */
  107. protected function parseMessage2($response)
  108. {
  109. $responseHex = bin2hex($response);
  110. $length = floor(hexdec(substr($responseHex, 28, 4)) / 256) * 2;
  111. $offset = floor(hexdec(substr($responseHex, 32, 4)) / 256) * 2;
  112. $challenge = $this->hex2bin(substr($responseHex, 48, 16));
  113. $context = $this->hex2bin(substr($responseHex, 64, 16));
  114. $targetInfoH = $this->hex2bin(substr($responseHex, 80, 16));
  115. $targetName = $this->hex2bin(substr($responseHex, $offset, $length));
  116. $offset = floor(hexdec(substr($responseHex, 88, 4)) / 256) * 2;
  117. $targetInfoBlock = substr($responseHex, $offset);
  118. list($domainName, $serverName, $DNSDomainName, $DNSServerName, $terminatorByte) = $this->readSubBlock($targetInfoBlock);
  119. return array(
  120. $challenge,
  121. $context,
  122. $targetInfoH,
  123. $targetName,
  124. $domainName,
  125. $serverName,
  126. $DNSDomainName,
  127. $DNSServerName,
  128. $this->hex2bin($targetInfoBlock),
  129. $terminatorByte,
  130. );
  131. }
  132. /**
  133. * Read the blob information in from message2.
  134. *
  135. * @param $block
  136. *
  137. * @return array
  138. */
  139. protected function readSubBlock($block)
  140. {
  141. // remove terminatorByte cause it's always the same
  142. $block = substr($block, 0, -8);
  143. $length = strlen($block);
  144. $offset = 0;
  145. $data = array();
  146. while ($offset < $length) {
  147. $blockLength = hexdec(substr(substr($block, $offset, 8), -4)) / 256;
  148. $offset += 8;
  149. $data[] = $this->hex2bin(substr($block, $offset, $blockLength * 2));
  150. $offset += $blockLength * 2;
  151. }
  152. if (count($data) == 3) {
  153. $data[] = $data[2];
  154. $data[2] = '';
  155. }
  156. $data[] = $this->createByte('00');
  157. return $data;
  158. }
  159. /**
  160. * Send our final message with all our data.
  161. *
  162. * @param string $response Message 1 response (message 2)
  163. * @param string $username
  164. * @param string $password
  165. * @param string $timestamp
  166. * @param string $client
  167. * @param Swift_Transport_SmtpAgent $agent
  168. * @param bool $v2 Use version2 of the protocol
  169. *
  170. * @return string
  171. */
  172. protected function sendMessage3($response, $username, $password, $timestamp, $client, Swift_Transport_SmtpAgent $agent, $v2 = true)
  173. {
  174. list($domain, $username) = $this->getDomainAndUsername($username);
  175. //$challenge, $context, $targetInfoH, $targetName, $domainName, $workstation, $DNSDomainName, $DNSServerName, $blob, $ter
  176. list($challenge, , , , , $workstation, , , $blob) = $this->parseMessage2($response);
  177. if (!$v2) {
  178. // LMv1
  179. $lmResponse = $this->createLMPassword($password, $challenge);
  180. // NTLMv1
  181. $ntlmResponse = $this->createNTLMPassword($password, $challenge);
  182. } else {
  183. // LMv2
  184. $lmResponse = $this->createLMv2Password($password, $username, $domain, $challenge, $client);
  185. // NTLMv2
  186. $ntlmResponse = $this->createNTLMv2Hash($password, $username, $domain, $challenge, $blob, $timestamp, $client);
  187. }
  188. $message = $this->createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse);
  189. return $agent->executeCommand(sprintf("%s\r\n", base64_encode($message)), array(235));
  190. }
  191. /**
  192. * Create our message 1.
  193. *
  194. * @return string
  195. */
  196. protected function createMessage1()
  197. {
  198. return self::NTLMSIG
  199. .$this->createByte('01') // Message 1
  200. .$this->createByte('0702'); // Flags
  201. }
  202. /**
  203. * Create our message 3.
  204. *
  205. * @param string $domain
  206. * @param string $username
  207. * @param string $workstation
  208. * @param string $lmResponse
  209. * @param string $ntlmResponse
  210. *
  211. * @return string
  212. */
  213. protected function createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse)
  214. {
  215. // Create security buffers
  216. $domainSec = $this->createSecurityBuffer($domain, 64);
  217. $domainInfo = $this->readSecurityBuffer(bin2hex($domainSec));
  218. $userSec = $this->createSecurityBuffer($username, ($domainInfo[0] + $domainInfo[1]) / 2);
  219. $userInfo = $this->readSecurityBuffer(bin2hex($userSec));
  220. $workSec = $this->createSecurityBuffer($workstation, ($userInfo[0] + $userInfo[1]) / 2);
  221. $workInfo = $this->readSecurityBuffer(bin2hex($workSec));
  222. $lmSec = $this->createSecurityBuffer($lmResponse, ($workInfo[0] + $workInfo[1]) / 2, true);
  223. $lmInfo = $this->readSecurityBuffer(bin2hex($lmSec));
  224. $ntlmSec = $this->createSecurityBuffer($ntlmResponse, ($lmInfo[0] + $lmInfo[1]) / 2, true);
  225. return self::NTLMSIG
  226. .$this->createByte('03') // TYPE 3 message
  227. .$lmSec // LM response header
  228. .$ntlmSec // NTLM response header
  229. .$domainSec // Domain header
  230. .$userSec // User header
  231. .$workSec // Workstation header
  232. .$this->createByte('000000009a', 8) // session key header (empty)
  233. .$this->createByte('01020000') // FLAGS
  234. .$this->convertTo16bit($domain) // domain name
  235. .$this->convertTo16bit($username) // username
  236. .$this->convertTo16bit($workstation) // workstation
  237. .$lmResponse
  238. .$ntlmResponse;
  239. }
  240. /**
  241. * @param string $timestamp Epoch timestamp in microseconds
  242. * @param string $client Random bytes
  243. * @param string $targetInfo
  244. *
  245. * @return string
  246. */
  247. protected function createBlob($timestamp, $client, $targetInfo)
  248. {
  249. return $this->createByte('0101')
  250. .$this->createByte('00')
  251. .$timestamp
  252. .$client
  253. .$this->createByte('00')
  254. .$targetInfo
  255. .$this->createByte('00');
  256. }
  257. /**
  258. * Get domain and username from our username.
  259. *
  260. * @example DOMAIN\username
  261. *
  262. * @param string $name
  263. *
  264. * @return array
  265. */
  266. protected function getDomainAndUsername($name)
  267. {
  268. if (strpos($name, '\\') !== false) {
  269. return explode('\\', $name);
  270. }
  271. list($user, $domain) = explode('@', $name);
  272. return array($domain, $user);
  273. }
  274. /**
  275. * Create LMv1 response.
  276. *
  277. * @param string $password
  278. * @param string $challenge
  279. *
  280. * @return string
  281. */
  282. protected function createLMPassword($password, $challenge)
  283. {
  284. // FIRST PART
  285. $password = $this->createByte(strtoupper($password), 14, false);
  286. list($key1, $key2) = str_split($password, 7);
  287. $desKey1 = $this->createDesKey($key1);
  288. $desKey2 = $this->createDesKey($key2);
  289. $constantDecrypt = $this->createByte($this->desEncrypt(self::DESCONST, $desKey1).$this->desEncrypt(self::DESCONST, $desKey2), 21, false);
  290. // SECOND PART
  291. list($key1, $key2, $key3) = str_split($constantDecrypt, 7);
  292. $desKey1 = $this->createDesKey($key1);
  293. $desKey2 = $this->createDesKey($key2);
  294. $desKey3 = $this->createDesKey($key3);
  295. return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3);
  296. }
  297. /**
  298. * Create NTLMv1 response.
  299. *
  300. * @param string $password
  301. * @param string $challenge
  302. *
  303. * @return string
  304. */
  305. protected function createNTLMPassword($password, $challenge)
  306. {
  307. // FIRST PART
  308. $ntlmHash = $this->createByte($this->md4Encrypt($password), 21, false);
  309. list($key1, $key2, $key3) = str_split($ntlmHash, 7);
  310. $desKey1 = $this->createDesKey($key1);
  311. $desKey2 = $this->createDesKey($key2);
  312. $desKey3 = $this->createDesKey($key3);
  313. return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3);
  314. }
  315. /**
  316. * Convert a normal timestamp to a tenth of a microtime epoch time.
  317. *
  318. * @param string $time
  319. *
  320. * @return string
  321. */
  322. protected function getCorrectTimestamp($time)
  323. {
  324. // Get our timestamp (tricky!)
  325. bcscale(0);
  326. $time = number_format($time, 0, '.', ''); // save microtime to string
  327. $time = bcadd($time, '11644473600000'); // add epoch time
  328. $time = bcmul($time, 10000); // tenths of a microsecond.
  329. $binary = $this->si2bin($time, 64); // create 64 bit binary string
  330. $timestamp = '';
  331. for ($i = 0; $i < 8; ++$i) {
  332. $timestamp .= chr(bindec(substr($binary, -(($i + 1) * 8), 8)));
  333. }
  334. return $timestamp;
  335. }
  336. /**
  337. * Create LMv2 response.
  338. *
  339. * @param string $password
  340. * @param string $username
  341. * @param string $domain
  342. * @param string $challenge NTLM Challenge
  343. * @param string $client Random string
  344. *
  345. * @return string
  346. */
  347. protected function createLMv2Password($password, $username, $domain, $challenge, $client)
  348. {
  349. $lmPass = '00'; // by default 00
  350. // if $password > 15 than we can't use this method
  351. if (strlen($password) <= 15) {
  352. $ntlmHash = $this->md4Encrypt($password);
  353. $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain));
  354. $lmPass = bin2hex($this->md5Encrypt($ntml2Hash, $challenge.$client).$client);
  355. }
  356. return $this->createByte($lmPass, 24);
  357. }
  358. /**
  359. * Create NTLMv2 response.
  360. *
  361. * @param string $password
  362. * @param string $username
  363. * @param string $domain
  364. * @param string $challenge Hex values
  365. * @param string $targetInfo Hex values
  366. * @param string $timestamp
  367. * @param string $client Random bytes
  368. *
  369. * @return string
  370. *
  371. * @see http://davenport.sourceforge.net/ntlm.html#theNtlmResponse
  372. */
  373. protected function createNTLMv2Hash($password, $username, $domain, $challenge, $targetInfo, $timestamp, $client)
  374. {
  375. $ntlmHash = $this->md4Encrypt($password);
  376. $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain));
  377. // create blob
  378. $blob = $this->createBlob($timestamp, $client, $targetInfo);
  379. $ntlmv2Response = $this->md5Encrypt($ntml2Hash, $challenge.$blob);
  380. return $ntlmv2Response.$blob;
  381. }
  382. protected function createDesKey($key)
  383. {
  384. $material = array(bin2hex($key[0]));
  385. $len = strlen($key);
  386. for ($i = 1; $i < $len; ++$i) {
  387. list($high, $low) = str_split(bin2hex($key[$i]));
  388. $v = $this->castToByte(ord($key[$i - 1]) << (7 + 1 - $i) | $this->uRShift(hexdec(dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xf)), $i));
  389. $material[] = str_pad(substr(dechex($v), -2), 2, '0', STR_PAD_LEFT); // cast to byte
  390. }
  391. $material[] = str_pad(substr(dechex($this->castToByte(ord($key[6]) << 1)), -2), 2, '0');
  392. // odd parity
  393. foreach ($material as $k => $v) {
  394. $b = $this->castToByte(hexdec($v));
  395. $needsParity = (($this->uRShift($b, 7) ^ $this->uRShift($b, 6) ^ $this->uRShift($b, 5)
  396. ^ $this->uRShift($b, 4) ^ $this->uRShift($b, 3) ^ $this->uRShift($b, 2)
  397. ^ $this->uRShift($b, 1)) & 0x01) == 0;
  398. list($high, $low) = str_split($v);
  399. if ($needsParity) {
  400. $material[$k] = dechex(hexdec($high) | 0x0).dechex(hexdec($low) | 0x1);
  401. } else {
  402. $material[$k] = dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xe);
  403. }
  404. }
  405. return $this->hex2bin(implode('', $material));
  406. }
  407. /** HELPER FUNCTIONS */
  408. /**
  409. * Create our security buffer depending on length and offset.
  410. *
  411. * @param string $value Value we want to put in
  412. * @param int $offset start of value
  413. * @param bool $is16 Do we 16bit string or not?
  414. *
  415. * @return string
  416. */
  417. protected function createSecurityBuffer($value, $offset, $is16 = false)
  418. {
  419. $length = strlen(bin2hex($value));
  420. $length = $is16 ? $length / 2 : $length;
  421. $length = $this->createByte(str_pad(dechex($length), 2, '0', STR_PAD_LEFT), 2);
  422. return $length.$length.$this->createByte(dechex($offset), 4);
  423. }
  424. /**
  425. * Read our security buffer to fetch length and offset of our value.
  426. *
  427. * @param string $value Securitybuffer in hex
  428. *
  429. * @return array array with length and offset
  430. */
  431. protected function readSecurityBuffer($value)
  432. {
  433. $length = floor(hexdec(substr($value, 0, 4)) / 256) * 2;
  434. $offset = floor(hexdec(substr($value, 8, 4)) / 256) * 2;
  435. return array($length, $offset);
  436. }
  437. /**
  438. * Cast to byte java equivalent to (byte).
  439. *
  440. * @param int $v
  441. *
  442. * @return int
  443. */
  444. protected function castToByte($v)
  445. {
  446. return (($v + 128) % 256) - 128;
  447. }
  448. /**
  449. * Java unsigned right bitwise
  450. * $a >>> $b.
  451. *
  452. * @param int $a
  453. * @param int $b
  454. *
  455. * @return int
  456. */
  457. protected function uRShift($a, $b)
  458. {
  459. if ($b == 0) {
  460. return $a;
  461. }
  462. return ($a >> $b) & ~(1 << (8 * PHP_INT_SIZE - 1) >> ($b - 1));
  463. }
  464. /**
  465. * Right padding with 0 to certain length.
  466. *
  467. * @param string $input
  468. * @param int $bytes Length of bytes
  469. * @param bool $isHex Did we provided hex value
  470. *
  471. * @return string
  472. */
  473. protected function createByte($input, $bytes = 4, $isHex = true)
  474. {
  475. if ($isHex) {
  476. $byte = $this->hex2bin(str_pad($input, $bytes * 2, '00'));
  477. } else {
  478. $byte = str_pad($input, $bytes, "\x00");
  479. }
  480. return $byte;
  481. }
  482. /**
  483. * Create random bytes.
  484. *
  485. * @param $length
  486. *
  487. * @return string
  488. */
  489. protected function getRandomBytes($length)
  490. {
  491. $bytes = openssl_random_pseudo_bytes($length, $strong);
  492. if (false !== $bytes && true === $strong) {
  493. return $bytes;
  494. }
  495. throw new RuntimeException('OpenSSL did not produce a secure random number.');
  496. }
  497. /** ENCRYPTION ALGORITHMS */
  498. /**
  499. * DES Encryption.
  500. *
  501. * @param string $value
  502. * @param string $key
  503. *
  504. * @return string
  505. */
  506. protected function desEncrypt($value, $key)
  507. {
  508. $cipher = mcrypt_module_open(MCRYPT_DES, '', 'ecb', '');
  509. mcrypt_generic_init($cipher, $key, mcrypt_create_iv(mcrypt_enc_get_iv_size($cipher), MCRYPT_DEV_RANDOM));
  510. return mcrypt_generic($cipher, $value);
  511. }
  512. /**
  513. * MD5 Encryption.
  514. *
  515. * @param string $key Encryption key
  516. * @param string $msg Message to encrypt
  517. *
  518. * @return string
  519. */
  520. protected function md5Encrypt($key, $msg)
  521. {
  522. $blocksize = 64;
  523. if (strlen($key) > $blocksize) {
  524. $key = pack('H*', md5($key));
  525. }
  526. $key = str_pad($key, $blocksize, "\0");
  527. $ipadk = $key ^ str_repeat("\x36", $blocksize);
  528. $opadk = $key ^ str_repeat("\x5c", $blocksize);
  529. return pack('H*', md5($opadk.pack('H*', md5($ipadk.$msg))));
  530. }
  531. /**
  532. * MD4 Encryption.
  533. *
  534. * @param string $input
  535. *
  536. * @return string
  537. *
  538. * @see http://php.net/manual/en/ref.hash.php
  539. */
  540. protected function md4Encrypt($input)
  541. {
  542. $input = $this->convertTo16bit($input);
  543. return function_exists('hash') ? $this->hex2bin(hash('md4', $input)) : mhash(MHASH_MD4, $input);
  544. }
  545. /**
  546. * Convert UTF-8 to UTF-16.
  547. *
  548. * @param string $input
  549. *
  550. * @return string
  551. */
  552. protected function convertTo16bit($input)
  553. {
  554. return iconv('UTF-8', 'UTF-16LE', $input);
  555. }
  556. /**
  557. * Hex2bin replacement for < PHP 5.4.
  558. *
  559. * @param string $hex
  560. *
  561. * @return string Binary
  562. */
  563. protected function hex2bin($hex)
  564. {
  565. if (function_exists('hex2bin')) {
  566. return hex2bin($hex);
  567. } else {
  568. return pack('H*', $hex);
  569. }
  570. }
  571. /**
  572. * @param string $message
  573. */
  574. protected function debug($message)
  575. {
  576. $message = bin2hex($message);
  577. $messageId = substr($message, 16, 8);
  578. echo substr($message, 0, 16)." NTLMSSP Signature<br />\n";
  579. echo $messageId." Type Indicator<br />\n";
  580. if ($messageId == '02000000') {
  581. $map = array(
  582. 'Challenge',
  583. 'Context',
  584. 'Target Information Security Buffer',
  585. 'Target Name Data',
  586. 'NetBIOS Domain Name',
  587. 'NetBIOS Server Name',
  588. 'DNS Domain Name',
  589. 'DNS Server Name',
  590. 'BLOB',
  591. 'Target Information Terminator',
  592. );
  593. $data = $this->parseMessage2($this->hex2bin($message));
  594. foreach ($map as $key => $value) {
  595. echo bin2hex($data[$key]).' - '.$data[$key].' ||| '.$value."<br />\n";
  596. }
  597. } elseif ($messageId == '03000000') {
  598. $i = 0;
  599. $data[$i++] = substr($message, 24, 16);
  600. list($lmLength, $lmOffset) = $this->readSecurityBuffer($data[$i - 1]);
  601. $data[$i++] = substr($message, 40, 16);
  602. list($ntmlLength, $ntmlOffset) = $this->readSecurityBuffer($data[$i - 1]);
  603. $data[$i++] = substr($message, 56, 16);
  604. list($targetLength, $targetOffset) = $this->readSecurityBuffer($data[$i - 1]);
  605. $data[$i++] = substr($message, 72, 16);
  606. list($userLength, $userOffset) = $this->readSecurityBuffer($data[$i - 1]);
  607. $data[$i++] = substr($message, 88, 16);
  608. list($workLength, $workOffset) = $this->readSecurityBuffer($data[$i - 1]);
  609. $data[$i++] = substr($message, 104, 16);
  610. $data[$i++] = substr($message, 120, 8);
  611. $data[$i++] = substr($message, $targetOffset, $targetLength);
  612. $data[$i++] = substr($message, $userOffset, $userLength);
  613. $data[$i++] = substr($message, $workOffset, $workLength);
  614. $data[$i++] = substr($message, $lmOffset, $lmLength);
  615. $data[$i] = substr($message, $ntmlOffset, $ntmlLength);
  616. $map = array(
  617. 'LM Response Security Buffer',
  618. 'NTLM Response Security Buffer',
  619. 'Target Name Security Buffer',
  620. 'User Name Security Buffer',
  621. 'Workstation Name Security Buffer',
  622. 'Session Key Security Buffer',
  623. 'Flags',
  624. 'Target Name Data',
  625. 'User Name Data',
  626. 'Workstation Name Data',
  627. 'LM Response Data',
  628. 'NTLM Response Data',
  629. );
  630. foreach ($map as $key => $value) {
  631. echo $data[$key].' - '.$this->hex2bin($data[$key]).' ||| '.$value."<br />\n";
  632. }
  633. }
  634. echo '<br /><br />';
  635. }
  636. }