Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Pen-Test
[Top] [All Lists]

Re: pwdump 2 & 3

Subject: Re: pwdump 2 & 3
Date: Sun, 30 Jan 2005 23:33:00 +0100
Your explanation is quite interesting, but I see a conflict with the information mentioned in:
"Windows Passwords: Everything You Need To Know"
http://202.181.238.2/hk/teched2004/ppt/Day_2_Rm402/WIN495(1500-1615).ppt


According to the above mentioned presentation, the information in the cache is:
MD5(NTLM(password)+userID+Domain)


Can you provide any feedback on that?

Well, I am afraid that Microsoft is wrong :-)

To demonstrate this, I wrote the following utility in PERL (CACHE-COMPUTE.PL).

In short :
- Go onto a Windows NT4 Workstation (it will not work against Windows 2000+, since a different password storage scheme is used).
- Use LSADUMP to dump NL$x entries.
- Fill the "username" and "password" in CACHE-COMPUTE with data from a user that is in cache (for example, the currently logged in user).
- You should match one line of the LSADUMP output with CACHE-COMPUTE output.


On my computer :
- username = testuser
- password = thisisatest
- CACHE-COMPUTE output = 7a0420497cf92869352c51578c1945fc
- LSADUMP =
NL$8
 72 F1 8D 6A 2A 4F E1 6C 7B 99 A7 02 2A 0E CD 40  r..j*O.l{...*..@
 7A 04 20 49 7C F9 28 69 35 2C 51 57 8C 19 45 FC  z. I|.(i5,QW..E.
 01 01 00                                         ...

Regards,
- Nicolas RUFF
-----------------------------------
Security Consultant
EdelWeb (http://www.edelweb.fr/)
Mail: nicolas.ruff (at) edelweb.fr
-----------------------------------


#!/usr/bin/perl

# CACHE-COMPUTE.PL
# A little utility to compute cache values for Windows NT4
#
# I really don't like PERL ...
# ... but it is hard to find a MD4 module for Python
# (c) Nicolas RUFF / EdelWeb / released on Jan 2005

use Crypt::DES;
use Digest::MD4;

@odd_parity = (
  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
);

# Shamelessly copied from Authen::NTLM-1.02
# Added des_set_odd_parity() from SSLEAY
sub str_to_key
{
  my ($str) = @_;
  my $i;
  my @key;
  my $out;
  my @str = map {ord($_)} split(//, $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;
  foreach $i (0..7)
  {
    $key[$i] = 0xff&($key[$i]<<1);
    # des_set_odd_parity()
    $key[$i] = $odd_parity[ $key[$i] ];
  }

  return \@key;
}

# --------------------------------------------------
# Input data
# --------------------------------------------------
# username = "testuser" (Unicode)
$username  = "t\x00e\x00s\x00t\x00u\x00s\x00e\x00r\x00";
$password  = "thisisatest";

# --------------------------------------------------
# Compute LM hash
# In this sample : "8A6D8380CAC58F22 01FC5A6BE7BC6929"
# --------------------------------------------------

$password  = uc($password);

$password_part1 = pack( "a7", substr($password, 0, 7) );
$key1           = str_to_key( $password_part1 );
$deskey1        = pack( "C8", @$key1 );

$password_part2 = pack( "a7", substr($password, 7, 7) );
$key2           = str_to_key( $password_part2 );
$deskey2        = pack( "C8", @$key2 );

# Magic string (see LM specs)
$lmplaintext    = pack( "H16", "4B47532140232425" );

$des1        = new Crypt::DES $deskey1;
$lmhash1     = $des1->encrypt($lmplaintext);
print "LM part1 : ", unpack("H16", $lmhash1), "\n";

$des2        = new Crypt::DES $deskey2;
$lmhash2     = $des2->encrypt($lmplaintext);
print "LM part2 : ", unpack("H16", $lmhash2), "\n";

# --------------------------------------------------
# Compute cache value
# In this sample : NL$8 =
# 72 F1 8D 6A 2A 4F E1 6C 7B 99 A7 02 2A 0E CD 40
# 7A 04 20 49 7C F9 28 69 35 2C 51 57 8C 19 45 FC [*]
# 01 01 00
# --------------------------------------------------

$string = $lmhash1 . $lmhash2 . $username;

$ctx = new Digest::MD4;
$ctx->reset();
print "Output : ", Digest::MD4->hexhash($string), "\n";

<Prev in Thread] Current Thread [Next in Thread>