From 00704e185038ce32ed6b068c6f879f35b047260a Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sat, 4 Dec 2004 12:21:28 +0000 Subject: [PATCH] implemented LM password hashes --- lam/lib/createntlm.php | 321 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 lam/lib/createntlm.php diff --git a/lam/lib/createntlm.php b/lam/lib/createntlm.php new file mode 100644 index 00000000..4a833760 --- /dev/null +++ b/lam/lib/createntlm.php @@ -0,0 +1,321 @@ +permute($key, $this->perm1, 56); + + $c = array(); + $d = array(); + for ($i = 0; $i < 28; $i++) { + $c[$i] = $pk1[$i]; + $d[$i] = $pk1[28 + $i]; + } + + for ($i = 0; $i < 16; $i++) { + $c = $this->lshift($this->sc[$i], $c); + $d = $this->lshift($this->sc[$i], $d); + + $cd = $c; + for ($k = 0; $k < sizeof($d); $k++) $cd[] = $d[$k]; + $ki[$i] = $this->permute($cd, $this->perm2, 48); + } + + $pd1 = $this->permute($in, $this->perm3, 64); + + $l = array(); + $r = array(); + for ($i = 0; $i < 32; $i++) { + $l[$i] = $pd1[$i]; + $r[$i] = $pd1[32 + $i]; + } + + for ($i = 0; $i < 16; $i++) { + $er = $this->permute($r, $this->perm4, 48); + if ($forw) $erk = $this->mxor($er, $ki[$i]); + else $erk = $this->mxor($er, $ki[15 - $i]); + + for ($j = 0; $j < 8; $j++) { + for ($k = 0; $k < 6; $k++) { + $b[$j][$k] = $erk[($j * 6) + $k]; + } + } + for ($j = 0; $j < 8; $j++) { + $m = array(); + $n = array(); + $m = ($b[$j][0] << 1) | $b[$j][5]; + $n = ($b[$j][1] << 3) | ($b[$j][2] << 2) | ($b[$j][3] << 1) | $b[$j][4]; + + for ($k = 0; $k < 4; $k++) { + $b[$j][$k]=($this->sbox[$j][$m][$n] & (1 << (3-$k)))?1:0; + } + } + + for ($j = 0; $j < 8; $j++) { + for ($k = 0; $k < 4; $k++) { + $cb[($j * 4) + $k] = $b[$j][$k]; + } + } + $pcb = $this->permute($cb, $this->perm5, 32); + $r2 = $this->mxor($l, $pcb); + for ($k = 0; $k < 32; $k++) $l[$k] = $r[$k]; + for ($k = 0; $k < 32; $k++) $r[$k] = $r2[$k]; + } + $rl = $r; + for ($i = 0; $i < sizeof($l); $i++) $rl[] = $l[$i]; + return $this->permute($rl, $this->perm6, 64); + } + + function str_to_key($str) { + $key[0] = $str[0] >> 1; + $key[1] = (($str[0]&0x01)<<6) | ($str[1]>>2); + $key[2] = (($str[1]&0x03)<<5) | ($str[2]>>3); + $key[3] = (($str[2]&0x07)<<4) | ($str[3]>>4); + $key[4] = (($str[3]&0x0F)<<3) | ($str[4]>>5); + $key[5] = (($str[4]&0x1F)<<2) | ($str[5]>>6); + $key[6] = (($str[5]&0x3F)<<1) | ($str[6]>>7); + $key[7] = $str[6]&0x7F; + for ($i = 0; $i < 8; $i++) { + $key[$i] = ($key[$i] << 1); + } + return $key; + } + + function smb_hash($in, $key, $forw){ + $key2 = $this->str_to_key($key); + + for ($i = 0; $i < 64; $i++) { + $inb[$i] = ($in[$i/8] & (1<<(7-($i%8)))) ? 1:0; + $keyb[$i] = ($key2[$i/8] & (1<<(7-($i%8)))) ? 1:0; + $outb[$i] = 0; + } + $outb = $this->dohash($inb, $keyb, $forw); + for ($i = 0; $i < 8; $i++) { + $out[$i] = 0; + } + for ($i = 0; $i < 65; $i++) { + if ( $outb[$i] ) { + $out[$i/8] |= (1<<(7-($i%8))); + } + } + return $out; + } + + function E_P16($in) { + $p14 = array_values(unpack("C*",$in)); + $sp8 = array(0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25); + $p14_1 = array(); + $p14_2 = array(); + for ($i = 0; $i < 7; $i++) { + $p14_1[$i] = $p14[$i]; + $p14_2[$i] = $p14[$i + 7]; + } + $p16_1 = $this->smb_hash($sp8, $p14_1, true); + $p16_2 = $this->smb_hash($sp8, $p14_2, true); + $p16 = $p16_1; + for ($i = 0; $i < sizeof($p16_2); $i++) { + $p16[] = $p16_2[$i]; + } + return $p16; + } + + /** + * Calculates the LM hash of a given password. + * + * @param string $password password + * @return string hash value + */ + function lmhash($password = "") { + $password = strtoupper($password); + $password = substr($password,0,14); + $password = str_pad($password, 14, chr(0)); + $p16 = $this->E_P16($password); + for ($i = 0; $i < sizeof($p16); $i++) { + $p16[$i] = sprintf("%02X", $p16[$i]); + } + return join("", $p16); + } + +} + +?> +