📄 ntlm挑战模式散列认证加密协议过程,算法实现与一些想法.txt
字号:
*(WORD *)(creaded+0x26)=ulen;
*(DWORD *)(creaded+0x28)=0x40+dlen;
*(WORD *)(creaded+0x2c)=dlen;
*(WORD *)(creaded+0x2e)=dlen;
*(DWORD *)(creaded+0x30)=0x40+dlen+ulen;
*(WORD *)(creaded+0x34)=0x10;
*(WORD *)(creaded+0x36)=0x10;
*(DWORD *)(creaded+0x38)=0x40+ulen+dlen+dlen+0x30;
*(DWORD *)(creaded+0x3C)=0XE0888215;
//放如用户名等信息
memcpy(creaded+0x40,domainname,dlen);
memcpy(creaded+0x40+dlen,username,ulen);
memcpy(creaded+0x40+dlen+ulen,domainname,dlen);
psmbp->smbinfo.smbtoken =0x73;
memset(psmbp->smbinfo.info,0,0x200);
psmbp->smbinfo.flagsummary2 = 0xc807;
*(DWORD *)(psmbp->smbinfo.info+21) = 0x800000D4;
//指定使用加密的FLAG
psmbp->smbinfo.info[0]=0xc;//WORD 参数个数
*(WORD *)(psmbp->smbinfo.info+1)=0Xff;//无下一个命令
*(WORD *)(psmbp->smbinfo.info+3)=0X12e;//下一命令偏移
*(WORD *)(psmbp->smbinfo.info+5)=0X4104;//最大缓冲
*(WORD *)(psmbp->smbinfo.info+7)=0X32;//最大的MPX
*(WORD *)(psmbp->smbinfo.info+9)=0X0;//虚拟通道
*(DWORD *)(psmbp->smbinfo.info+11)=0X0;//虚拟通道
*(DWORD *)(psmbp->smbinfo.info+17)=0X0;//保留
passtoowf(password,passwordhash); //口令到散列
challagetorkey(romkey,challage,enkey); //把挑战和任意一个本地随机KEY通过MD5计算出加密KEY
memset(cread,0,0x40);
memcpy(cread,romkey,0x8); //BLOB中放入本地随机KEY,好让服务器知道能计算出加密KEY
hashtocread(enkey,passwordhash,cread); //通过加密KEY计算NTLM的加密形式
memcpy(creaded+0x40+ulen+dlen+dlen,cread,0x40);
*(WORD *)(psmbp->smbinfo.info+15)=0x80+ulen+dlen+dlen; //BLOB的长度
memcpy(psmbp->smbinfo.info+27,creaded,0x80+ulen+dlen+dlen);//放入BLOB
memcpy(psmbp->smbinfo.info+28+0x80+ulen+dlen+dlen,navos,36);//
memcpy(psmbp->smbinfo.info+66+0x80+ulen+dlen+dlen,lanman,32);//
*(WORD *)(psmbp->smbinfo.info+25)=73+0x80+ulen+dlen+dlen;
psmbp->smbnbt.smbpacketlen = htons(132+ 0x80+ulen+dlen+dlen);
}
void SmbNegotiate(SMBP * psmbp)
{
unsigned char magic[4]={0xff,'S','M','B'};
short len;
char langitem1[]="PC NETWORK PROGRAM 1.0";
char langitem2[]="LANMAN1.0";
char langitem3[]="Windows for Workgroups 3.1a";
char langitem4[]="LM1.2X002";
char langitem5[]="LANMAN2.1";
char langitem6[]="NT LM 0.12";
char langitem7[]="PCLAN1.0";
char langitem8[]="MICROSOFT NETWORKS 1.03";
char langitem9[]="MICROSOFT NETWORKS 3.0";
char langitem10[]="DOS LM1.2X002";
char langitem11[]="DOS LANMAN2.1";
char langitem12[]="Cairo 0.xa";
memset(psmbp,0,sizeof(SMBP));
psmbp->smbnbt.nbtsmb = 0;
psmbp->smbnbt.flag = 0;
memcpy(psmbp->smbinfo.magic, magic,4);
psmbp->smbinfo.smbtoken = 0x72;
psmbp->smbinfo.errcodeclass = 0x0;
psmbp->smbinfo.dosaherrcode = 0x0;
psmbp->smbinfo.errcode[0] = 0x0;
psmbp->smbinfo.errcode[1] = 0x0;
psmbp->smbinfo.flagsummary = 0x18;
psmbp->smbinfo.flagsummary2 = 0xc853;
//指定了带挑战方式支持的FLAG
psmbp->smbinfo.callprocessid = 0xfeff;
psmbp->smbinfo.multiplexid = 0;
psmbp->smbinfo.info[0]=0x0;
len=3+2*(psmbp->smbinfo.info[0]);
psmbp->smbinfo.info[len]=0x2;
memcpy(psmbp->smbinfo.info+len+1,langitem6,sizeof(langitem6));
len = len+1+sizeof(langitem6);
*(WORD *)(psmbp->smbinfo.info+1) =len-3-2*(psmbp->smbinfo.info[0]);
psmbp->smbnbt.smbpacketlen = htons(len+0x20);
}
void challagetorkey(unsigned char * romkey,unsigned char * challage,unsigned char * enkey)
{
unsigned char LM[0x58];
md5init(LM);
*(DWORD *)LM=0x200;
memcpy(LM+0X18,challage,8);
memcpy(LM+0X20,romkey,8);
*(DWORD *)(LM+0x28)=0x80;
*(DWORD *)(LM+0x50)=0x80;
md5final(LM);
memcpy(enkey,LM+8,8);
}
void hashtocread(unsigned char * enkey,unsigned char * hash,unsigned char * cread)
{
unsigned char LmPass[0x10];
unsigned char rc4keylist[0x102];
LSA_UNICODE_STRING lmhash;
unsigned char desecb[128];
unsigned char lm[0x28];
unsigned char key[0x8];
unsigned char rc4key[0x10];
//加密KEY加密NTLM
initLMP(hash,LmPass);
deskey(LmPass,desecb);
des(lm,enkey,desecb,1);
initLMP(hash+7,LmPass);
deskey(LmPass,desecb);
des(lm+8,enkey,desecb,1);
memset(key,0,8);
memcpy(key,hash+0xe,2);
initLMP(key,LmPass);
deskey(LmPass,desecb);
des(lm+0x10,enkey,desecb,1);
memcpy(cread+0x18,lm,0x18);
//计算NTLM的RC4形式
lmhash.Length=0x10;
lmhash.MaximumLength=0x10;
lmhash.Buffer= hash;
initMDP(&lmhash,rc4key);
hmacmd5(rc4key,enkey);
memcpy(cread+0x30,rc4key,0x10);
rc4_key(rc4keylist,rc4key,0x10);
//由于并未使用此字段认证,下面的函数未实现,就以RC4KEY做其放进去了
// rc4_424(rc4keylist,rc4rom,0x10);
}
void rc4_key(unsigned char * rc4keylist,unsigned char * rc4key,int keylen)
{
int i,j;
DWORD a1=0x03020100;
unsigned char c1,c2,c3;
for(i=0;i<0x40;i++)
{
*(DWORD *)(rc4keylist+4*i)=a1;
a1+=0x04040404;
}
rc4keylist[0x100]=0;
rc4keylist[0x101]=0;
j=0;
i=0;
c3=0;
for(j=0;j<0x100;j++)
{
c1=rc4keylist[j];
c2=rc4key[i];
c3=(c3+c2+c1)%256;
rc4keylist[j]=rc4keylist[c3];
rc4keylist[c3]=c1;
i++;
if(i==keylen)
i=0;
}
}
void hmacmd5(unsigned char * rc4key,unsigned char * enkey)
{
unsigned char Lm1[0x58];
unsigned char Lm2[0x58];
unsigned char k1[0x40];
unsigned char k2[0x40];
int i;
md5init(Lm1);
md5init(Lm2);
memset(k1,0,0x40);
memset(k2,0,0x40);
memcpy(k1,rc4key,0x10);
memcpy(k2,rc4key,0x10);
for(i=0;i<0x10;i++)
{
*(DWORD *)(k1+4*i)=(*(DWORD *)(k1+4*i))^0x36363636;
*(DWORD *)(k2+4*i)=(*(DWORD *)(k2+4*i))^0x5c5c5c5c;
}
*(DWORD *)Lm1=0x200;
memcpy(Lm1+0X18,k1,0x40);
md5final(Lm1);
*(DWORD *)Lm2=0x200;
memcpy(Lm2+0X18,k2,0x40);
md5final(Lm2);
*(DWORD *)Lm1=0x400;
memcpy(Lm1+0X18,challage,0x8);
memcpy(Lm1+0X20,romkey,0x8);
memset(Lm1+0X28,0x80,1);
memset(Lm1+0X29,0,0x2f);
*(DWORD *)(Lm1+0x50)=0x280;
md5final(Lm1);
memcpy(Lm2+0X18,Lm1+8,0x10);
*(DWORD *)Lm2=0x400;
memset(Lm2+0X28,0x80,1);
memset(Lm2+0X29,0,0x2f);
*(DWORD *)(Lm2+0x50)=0x280;
md5final(Lm2);
memcpy(rc4key,Lm2+8,0x10);
}
void passtoowf(wchar_t * password,unsigned char * paswdowf)
{
int len;
int i;
LSA_UNICODE_STRING pass;
LSA_UNICODE_STRING opass;
char magic1[8]="KGS!@#$%";
unsigned char desecb[128];
unsigned char upassword[0x10];
unsigned char LmPass[0x10];
len=0;
for(i=0;i<0x20;i++)
{
if(password[i]==0 )
break;
len=len+2;
}
if(len>28)
{
printf("password <=14");
return;
}
pass.Length=len;
pass.MaximumLength=len;
pass.Buffer=password;
opass.MaximumLength=0xf;
opass.Buffer=upassword;
memset(upassword,0,0x10);
RtlUpcaseUnicodeStringToOemString(&opass,&pass,0);
initLMP(upassword,LmPass);
deskey(LmPass,desecb);
des(paswdowf+0x10,magic1,desecb,1);
initLMP(upassword+7,LmPass);
deskey(LmPass,desecb);
des(paswdowf+0x18,magic1,desecb,1);
initMDP(&pass,paswdowf);
}
void initMDP(PLSA_UNICODE_STRING pass,unsigned char * LM)
{
unsigned char LM1[0x58];
unsigned char s[2]="0";
md4init(LM1);
memcpy(LM1+0x18,pass->Buffer,pass->Length);
memset(LM1+0x18+pass->Length,0x80,1);
memset(LM1+0x18+pass->Length+1,0,0x37-pass->Length);
*(DWORD *)(LM1+0x50)=8*(pass->Length);
memset(LM1+0x51,0x0,7);
*(DWORD *)(LM1+0x10)=0x200;
md4(LM1);
memcpy(LM,LM1,16);
}
void md4init(unsigned char * LM)
{
*(DWORD *)(LM)=0x67452301;
*(DWORD *)(LM+4)=0xefcdab89;
*(DWORD *)(LM+8)=0x98badcfe;
*(DWORD *)(LM+0xc)=0x10325476;
*(DWORD *)(LM+0x10)=0;
*(DWORD *)(LM+0x14)=0;
}
void md4(unsigned char * LM)
{
DWORD d1,d2,d3,d4;
DWORD a1,a2,a3;
//第1轮
d1=*(DWORD *)(LM);
d2=*(DWORD *)(LM+4);
d3=*(DWORD *)(LM+8);
d4=*(DWORD *)(LM+0xc);
a1=*(DWORD *)(LM+0x18);
a2=(((d4^d3)&d2)^d4)+a1+d1;
a2=(a2<<3)|(a2>>0x1d);
a1=*(DWORD *)(LM+0x1c);
a3=(((d3^d2)&a2)^d3)+a1;
d4=d4+a3;
d4=(d4<<7)|(d4>>0x19);
a1=*(DWORD *)(LM+0x20);
a3=(((d2^a2)&d4)^d2)+a1;
d3=d3+a3;
d3=(d3<<0xb)|(d3>>0x15);
a1=*(DWORD *)(LM+0x24);
a3=(((d4^a2)&d3)^a2)+a1;
d2=d2+a3;
d2=(d2<<0x13)|(d2>>0xd);
a1=*(DWORD *)(LM+0x28);
a3=(((d4^d3)&d2)^d4)+a1;
a2=a2+a3;
a2=(a2<<3)|(a2>>0x1d);
a1=*(DWORD *)(LM+0x2c);
a3=(((d3^d2)&a2)^d3)+a1;
d4=d4+a3;
d4=(d4<<7)|(d4>>0x19);
a1=*(DWORD *)(LM+0x30);
a3=(((d2^a2)&d4)^d2)+a1;
d3=d3+a3;
d3=(d3<<0xb)|(d3>>0x15);
a1=*(DWORD *)(LM+0x34);
a3=(((d4^a2)&d3)^a2)+a1;
d2=d2+a3;
d2=(d2<<0x13)|(d2>>0xd);
a1=*(DWORD *)(LM+0x38);
a3=(((d4^d3)&d2)^d4)+a1;
a2=a2+a3;
a2=(a2<<3)|(a2>>0x1d);
a1=*(DWORD *)(LM+0x3c);
a3=(((d3^d2)&a2)^d3)+a1;
d4=d4+a3;
d4=(d4<<7)|(d4>>0x19);
a1=*(DWORD *)(LM+0x40);
a3=(((d2^a2)&d4)^d2)+a1;
d3=d3+a3;
d3=(d3<<0xb)|(d3>>0x15);
a1=*(DWORD *)(LM+0x44);
a3=(((d4^a2)&d3)^a2)+a1;
d2=d2+a3;
d2=(d2<<0x13)|(d2>>0xd);
a1=*(DWORD *)(LM+0x48);
a3=(((d4^d3)&d2)^d4)+a1;
a2=a2+a3;
a2=(a2<<0x3)|(a2>>0x1d);
a1=*(DWORD *)(LM+0x4c);
a3=(((d3^d2)&a2)^d3)+a1;
d4=d4+a3;
d4=(d4<<7)|(d4>>0x19);
a1=*(DWORD *)(LM+0x50);
a3=(((d2^a2)&d4)^d2)+a1;
d3=d3+a3;
d3=(d3<<0xb)|(d3>>0x15);
a1=*(DWORD *)(LM+0x54);
a3=(((d4^a2)&d3)^a2)+a1;
d2=d2+a3;
d2=(d2<<0x13)|(d2>>0xd);
//第2轮
a1=*(DWORD *)(LM+0x18);
a3=(((d3|d2)&d4)|(d3&d2))+a1+0x5a827999;
a2=a2+a3;
a2=(a2<<3)|(a2>>0x1d);
a1=*(DWORD *)(LM+0x28);
a3=(((d2|a2)&d3)|(d2&a2))+0x5a827999;
d4=d4+a1+a3;
d4=(d4<<5)|(d4>>0x1b);
a1=*(DWORD *)(LM+0x38);
a3=(((d4|a2)&d2)|(d4&a2))+a1+0x5a827999;
d3=d3+a3;
d3=(d3<<9)|(d3>>0x17);
a1=*(DWORD *)(LM+0x48);
a3=(((d4|d3)&a2)|(d4&d3))+a1+0x5a827999;
d2=d2+a3;
d2=(d2<<0xd)|(d2>>0x13);
a1=*(DWORD *)(LM+0x1c);
a3=(((d3|d2)&d4)|(d3&d2))+a1+0x5a827999;
a2=a2+a3;
a2=(a2<<3)|(a2>>0x1d);
a1=*(DWORD *)(LM+0x2c);
a3=(((d2|a2)&d3)|(d2&a2))+0x5a827999;
d4=d4+a1+a3;
d4=(d4<<5)|(d4>>0x1b);
a1=*(DWORD *)(LM+0x3c);
a3=(((d4|a2)&d2)|(d4&a2))+a1+0x5a827999;
d3=d3+a3;
d3=(d3<<9)|(d3>>0x17);
a1=*(DWORD *)(LM+0x4c);
a3=(((d4|d3)&a2)|(d4&d3))+a1+0x5a827999;
d2=d2+a3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -