Windows密码加密解密机制

最后更新于 2024-12-31 637 字 预计阅读时间: 3 分钟


Windows密码加密机制

在Windows中的密码加密一般采用NTLM hash加密存储

NTLM Hash = md4(unicode(hex(password)))

from Crypto.Hash import MD4
password = "password"
utf16_bytes = password.encode('utf-16-le')  # 'utf-16-le' 是小端字节顺序
md4_hash = MD4.new()
md4_hash.update(utf16_bytes)
ntlm_hash = md4_hash.hexdigest()
print("NTLM 哈希值 (MD4):")
print(ntlm_hash)

"""
NTLM 哈希值 (MD4):
8846f7eaee8fb117ad06bdd830b7586c
"""

在system32/config下有两个注册表转储文件SAM和SYSTEM分别存储着HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users和HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa的内容

HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users存储着用户ID和对应ID的密码NTLM hash的加密值

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa中的JD,Skew1,GBG,Data子项的类名经过变换得到syskey即解密SAM文件的密钥组成部分。

不过值得注意的是在注册表编辑器中看不见这四项的类名,用RegQueryInfoKey函数可以得到。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void main()
{
	char* c[]={"JD","Skew1","GBG","Data",NULL};
	char box[16]={0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3, 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 };
	char key[33]={0};
	int pos=0;
	for(int i=0;c[i]!=NULL;i++)
	{
		char cc[80]="SYSTEM\\CurrentControlSet\\Control\\Lsa\\\0\0\0\0\0\0\0\0\0\0\0\0";
		HKEY hkey=0;
		RegOpenKeyEx(HKEY_LOCAL_MACHINE,strcat(cc,c[i]),0,0x19,&hkey);
		char tmp[16]={0};
		unsigned long len=16;
		DWORD d=0;
		RegQueryInfoKey(hkey,tmp,&len,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);
		for(int ii=0;ii<8;ii++)
		{
			key[pos]=tmp[ii];
			pos++;
		}
		printf("%s\n",tmp);
		RegCloseKey(hkey);
	}
	BYTE tmp[16]={0};
	BYTE tmp2[16]={0};
	for(int i=0;i<16;i++)
	{
		int pos=i*2+2;
		char c=key[pos];
		key[pos]='\0';
		tmp[i]=strtol(key+i*2,NULL,16);
		key[pos]=c;
	}
	for(int i=0;i<16;i++)
	{
		tmp2[i]=tmp[box[i]];
	}
        printf("%s","syskey:");
	for(int i=0;i<16;i++)
	{
		printf("%02x",tmp2[i]);
	}
;
}

得到syskey后从HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account的F

计算得到

rc4_key = MD5(F[0x70:0x80] + var1+ syskey + var2)

其中

  • var1="!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0"
  • var2="0123456789012345678901234567890123456789\0"

rc4_key 在和F中的最后0x20字节做rc4运算得到sampsecretsessionkey,可以用sampsecretsessionkey进行SAM的解密过程

Windows密码解密机制

用上述的sampsecretsessionkey和用户的SID,和密码类型的字符串(NTLM hash为NTPASSWORD,LM hash的为LMPASSWORD)进行MD5后得到密钥,对SAM进行两次DES和rc4解密得到对应hash值。由于不同用户和不同机器的SID和syskey不同。

  • 同一机器下不同用户相同密码情况下加密后的hash不同
  • 不同机器下相同用户SID相同密码情况下加密后的hash不同
此作者没有提供个人介绍。
最后更新于 2024-12-31