📄 ntlmlib.cpp
字号:
#include<windows.h>
#include<stdlib.h>
#include<stdio.h>
#include"NTLMLib.h"
#include"d3des.h"
#include"md4.h"
static CODE MagicPlain={0x4B,0x47,0x53,0x21,0x40,0x23,0x24,0x25};
//将7字节的明文lpSrc转换成8字节的散列密文;
BOOL StringToKey(LPCSTR lpSrc,LPSTR lpKey)
{
BOOL T=FALSE;
int i;
if(lpSrc&&lpKey)
{
for(i=0;i<8;i++)
{
switch(i)
{
case 0:
lpKey[i]=(BYTE)lpSrc[i]&0xfe;
break;
case 7:
lpKey[i]=((BYTE)lpSrc[i-1]&0x7f)<<1;
break;
default:
lpKey[i]=(((BYTE)lpSrc[i]>>(i+1))|(((BYTE)lpSrc[i-1]&((1<<(i+1))-1))<<(7-i)))<<1;
}
}
T=TRUE;
}
return T;
}
//转换lpStr字符串中的内容到LMHASH结构中去;
BOOL StringToLMHash(LPLMHASH lpHash,LPCSTR lpStr)
{
BOOL T=FALSE;
int len,i;
BYTE data[14];
if(lpStr&&lpHash)
{
len=strlen(lpStr);
if(len>=0&&len<15)
{
for(i=0;i<len;i++)
{
if(lpStr[i]>='a'&&lpStr[i]<='z')
{
data[i]=(BYTE)(lpStr[i]-'a'+'A');
}
else
{
data[i]=(BYTE)lpStr[i];
}
}
if(i<14)
{
ZeroMemory(data+i,14-i);
}
StringToKey((LPSTR)data,(LPSTR)lpHash->code[0]);
StringToKey((LPSTR)(data+7),(LPSTR)lpHash->code[1]);
for(i=0;i<2;i++)
{
deskey(lpHash->code[i],EN0);
des(MagicPlain,lpHash->code[i]);
}
T=TRUE;
}
}
return T;
}
//将长度是len的原文lpSrc用MD4算法加密成16字节的密文ret返回;
void md4(MD4 ret,LPCBYTE lpSrc,int len)
{
MD4_CTX context;
if(ret&&len>=0)
{
MD4Init(&context);
MD4Update(&context,(unsigned char *)lpSrc,len);
MD4Final(ret,&context);
}
}
//转换lpStr字符串中的内容到NTLMHASH结构中去;
BOOL StringToNTLMHash(LPNTLMHASH lpHash,LPCSTR lpStr)
{
BOOL T=FALSE;
LPBYTE lpData;
int len;
if(lpHash)
{
len=lpStr?strlen(lpStr):0;
if(len>0)
{
lpData=new BYTE[len<<1];
if(lpData)
{
mbstowcs((wchar_t *)lpData,lpStr,len);
md4(lpHash->code,lpData,len<<1);
delete[] lpData;
T=TRUE;
}
}
else
{
md4(lpHash->code,NULL,0);
T=TRUE;
}
}
return T;
}
//对密码szPwd用服务器给定的钥匙challenge得到回应串ret;AuthMode是验证类型,可以是NTLMAuth或LMAuth;
BOOL LMAuthen(RESPONSE ret,LPCSTR szPwd,CODE challenge,AuthMode mode)
{
BOOL T=FALSE;
int i,j;
BYTE key[21];
BYTE data[8];
if(ret&&szPwd&&challenge)
{
ZeroMemory(key,sizeof(key));
switch(mode)
{
case LMAuth:
{
LMHASH hash;
if(StringToLMHash(&hash,szPwd))
{
memcpy(key,hash.code[0],sizeof(hash));
T=TRUE;
}
}
break;
case NTLMAuth:
{
NTLMHASH hash;
if(StringToNTLMHash(&hash,szPwd))
{
memcpy(key,hash.code,sizeof(hash));
T=TRUE;
}
}
break;
}
if(T)
{
for(i=0,j=0;i<21;i+=7,j+=8)
{
StringToKey((char *)key+i,(char *)data);
deskey((unsigned char *)data,EN0);
des((unsigned char *)challenge,(unsigned char *)(ret+j));
}
}
}
return T;
}
//将16进制数据lpCode按可见方式输出到szHex缓冲中,形成可输出字符串;
void CodeToHex(LPSTR szHex,LPCBYTE lpCode,int len)
{
int n,i;
if(szHex&&lpCode&&len>0)
{
n=len*2;
for(i=0;i<len;i++)
{
sprintf(szHex,"%02X",lpCode[i]);
szHex+=2;
}
}
}
//将可见的16进制字符串转换成数据形式,len是lpCode的最大缓冲长度,返回实际转换的字节数;
int HexToCode(LPBYTE lpCode,int len,LPCSTR szHex)
{
int n=0;
int slen;
char * stopped;
char buf[3];
if(szHex&&lpCode&&len>0)
{
slen=strlen(szHex)&~1;
if(slen>0)
{
buf[2]=0;
do
{
buf[0]=szHex[0];
buf[1]=szHex[1];
szHex+=2;
lpCode[n]=(BYTE)strtoul(buf,&stopped,16);
if(!stopped||stopped-buf<2)
{
break;
}
n++;
slen-=2;
}
while(n<len&&slen>0);
}
}
return n;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -