计算机管理员密码

cba00
计算机管理员密码
导读:计算机里面的密码都是以哈希算法存储的,无法逆算。 1 Windows系统下的hash密码格式Windows系统下的hash密码格式为:用户名称:RID:LM-HASH值:NT-HASH值,例如:Administrator:500:C8825

计算机里面的密码都是以哈希算法存储的,无法逆算。

1 Windows系统下的hash密码格式

Windows系统下的hash密码格式为:用户名称:RID:LM-HASH值:NT-HASH值,例如:

Administrator:500:C8825DB10F2590EAAAD3B435B51404EE:683020925C5D8569C23AA724774CE6CC::: 表示
用户名称为:Administrator
RID为:500
LM-HASH值为:C8825DB10F2590EAAAD3B435B51404EE
NT-HASH值为:683020925C5D8569C23AA724774CE6CC

2Windows下LM Hash值生成原理

假设明文口令是“Welcome”,首先全部转换成大写“WELCOME”,再做将口令字符串大写转后后的字符串变换成二进制串:

“WELCOME” -> 57454C434F4D4500000000000000

技巧:可以将明文口令复制到UltraEdit编辑器中使用二进制方式查看即可获取口令的二进制串。

说明:如果明文口令经过大写变换后的二进制字符串不足14字节,则需要在其后添加0x00补足14字节。然后切割成两组7字节的数据,分别经 str_to_key()函数处理得到两组8字节数据:

57454C434F4D45 -str_to_key()-> 56A25288347A348A
00000000000000 -str_to_key()-> 0000000000000000

这两组8字节数据将做为DESKEY对魔术字符串“KGS!@#$%”进行标准DES加密

"KGS!@#$%" -> 4B47532140232425

56A25288347A348A -对4B47532140232425进行标准DES加密-> C23413A8A1E7665F

0000000000000000 -对4B47532140232425进行标准DES加密-> AAD3B435B51404EE

将加密后的这两组数据简单拼接,就得到了最后的LM Hash

LM Hash: C23413A8A1E7665FAAD3B435B51404EE

关于str_to_key()函数见最后附录1

3 Windows下NTLM Hash生成原理

从IBM设计的LM Hash算法存在几个弱点,微软在保持向后兼容性的同时提出了自己的挑战响应机制,NTLM Hash应运而生。假设明文口令是“123456”,首先转换成Unicode字符串,与LM Hash算法不同,这次不需要添加0x00补足14字节

"123456" -> 310032003300340035003600

从ASCII串转换成Unicode串时,使用little-endian序,微软在设计整个 *** B协议时就没考虑过big-endian 序,ntoh()、hton()函数不宜用在 *** B报文解码中。0x80之前的标准ASCII码转换成Unicode码,就是简单地从0x变成 0x00。此类标准ASCII串按little-endian序转换成Unicode串,就是简单地在原有每个字节之后添加0x00。对所获取的 Unicode串进行标准MD4单向哈希,无论数据源有多少字节,MD4固定产生128-bit的哈希值,

16字节310032003300340035003600 -进行标准MD4单向哈希-> 32ED87BDB5FDC5E9CBA88547376818D4

就得到了最后的NTLM Hash

NTLM Hash: 32ED87BDB5FDC5E9CBA88547376818D4

与LM Hash算法相比,明文口令大小写敏感,无法根据NTLM Hash判断原始明文口令是否小于8字节,摆脱了魔术字符串"KGS!@#$%"。 MD4是真正的单向哈希函数,穷举作为数据源出现的明文,难度较大。

附录1 str_to_key()函数

str_to_key()函数,的C语言描述程序:
#include
#include
#include
/
读取形如"AABBCCDDEEFF"这样的16进制数字串,主调者自己进行形参的边界检查
/
static void readhexstring ( const unsigned char src, unsigned char dst, unsigned int len )
{
unsigned int i;
unsigned char str[3];

str[2] = '\0';
for ( i = 0; i < len; i++ )
{
str[0] = src[ i 2 ];
str[1] = src[ i 2 + 1 ];
dst[i] = ( unsigned char )strtoul( str, NULL, 16 );
}
return;
} / end of readhexstring /

/
from The Samba Team's source/lib *** b/ *** bdesc
/
static void str_to_key ( const unsigned char str, unsigned char key )
{
unsigned int i;

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;
} / end of str_to_key /

int main ( int argc, char argv[] )
{
unsigned int i;
unsigned char buf_0[21];
unsigned char buf_1[24];

if ( argc != 2 )
{
fprintf( stderr, "Usage: %s \n", argv[0] );
return( EXIT_FAILURE );
}
memset( buf_0, 0, sizeof( buf_0 ) );
memset( buf_1, 0, sizeof( buf_1 ) );
i = strlen( argv[1] ) / 2;
readhexstring( argv[1], buf_0, i );
for ( i = 0; i < sizeof( buf_0 ); i++ )
{
fprintf( stderr, "%02X", buf_0[i] );
}
fprintf( stderr, "\n" );
str_to_key( buf_0, buf_1 );
str_to_key( buf_0 + 7, buf_1 + 8 );
str_to_key( buf_0 + 14, buf_1 + 16 );
for ( i = 0; i < sizeof( buf_1 ); i++ )
{
fprintf( stderr, "%02X", buf_1[i] );
}
fprintf( stderr, "\n" );
return( EXIT_SUCCESS );
} / end of main /