亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

SMB的NTLM認(rèn)證過(guò)程與NTLM挑戰(zhàn)的編程實(shí)現(xiàn)

系統(tǒng) 2666 0

創(chuàng)建時(shí)間:2003-05-16
文章屬性:原創(chuàng)
文章提交: flashsky (flashsky1_at_sina.com)

轉(zhuǎn)摘請(qǐng)注明作者和安全焦點(diǎn)
作者:FLASHSKY
SITE: WWW.XFOCUS.NET WWW.SHOPSKY.COM
src: http://www.xfocus.net/articles/200305/533.html
郵件:flashsky@xfocus.org
????????????????????
????//注:本文不涉及到NTLM具體的認(rèn)證算法,但是給出通過(guò)SSPI的API實(shí)現(xiàn)的過(guò)程。
????SMB協(xié)議可以說(shuō)是WIN系統(tǒng)的核心協(xié)議,這里大致給大家講解一下SMB認(rèn)證登陸的過(guò)程:
????1。協(xié)議解析棧
????CLIENT:APP----->NET/MRP/RPC API------>MRXSMB.SYS------>NETBT.SYS---->TCP/IP
??????????????????????????????????????????????????????????
????SERVER: SRV.SYS<-----------MRXSMB.SYS<----------NETBT.SYS<--------TCP/IP
??
???? 應(yīng)用程序調(diào)用NET/MPR/RPC等API將信息寫入WKSSVC管道,這個(gè)管道是一個(gè)特殊的管道,對(duì)應(yīng)的其實(shí)是一個(gè)LPC端口。
???? MRXSMB.SYS是一個(gè)SMB的小端口驅(qū)動(dòng),負(fù)責(zé)完成客戶端的SMB的封裝和實(shí)現(xiàn),如發(fā)起協(xié)商,認(rèn)證的加密/解密過(guò)程等。對(duì)于服務(wù)器端則主要
完成會(huì)話狀態(tài)的一些管理,然后將SMB包發(fā)送給下級(jí)驅(qū)動(dòng)處理。
???? NETBT.SYS是NETBIOS OVER TCP/IP的驅(qū)動(dòng),一般都是作為MRXSMB的下級(jí)驅(qū)動(dòng),不過(guò)MRXSMB也可以有其他的下級(jí)驅(qū)動(dòng),最后通過(guò)一個(gè)網(wǎng)絡(luò)驅(qū)
動(dòng)實(shí)現(xiàn)通訊,這里假設(shè)是使用TCP/IP。
???? SRV.SYS是服務(wù)器端的SMB協(xié)議驅(qū)動(dòng)程序,實(shí)現(xiàn)完成真正的SMB的協(xié)議功能,然后將結(jié)果按原路返回給客戶端。

????2。SMB的認(rèn)證協(xié)議。
????通過(guò)SMB進(jìn)行認(rèn)證客戶端一般都要先使用SMB的協(xié)商命令(0X72)發(fā)送客戶端支持的認(rèn)證協(xié)議給服務(wù)器,服務(wù)器則選擇其中的一個(gè),然后返回
給客戶端,客戶端然后再使用SMB的會(huì)話設(shè)置和X命令(0X73)進(jìn)行認(rèn)證和登陸。
????MS的SMB已經(jīng)使用的SMB認(rèn)證協(xié)議有:
??????協(xié)議????????????????????????備注
????PC NETWORK PROGRAM 1.0????????????????W2K支持????????????????
????PCLAN1.0????????????????????????W2K支持
????MICROSOFT NETWORKS 1.03????????????????W2K支持
????MICROSOFT NETWORKS 3.0????????????????W2K支持
????LANMAN1.0????????????????????????W2K支持
????DOS LM1.2X002????????????????????W2K支持
????Windows for Workgroups 3.1a ????????????W2K不支持,老的Windows for Workgroups 3.1使用此協(xié)議方式。
????LM1.2X002????????????????????????W2K支持??
????DOS LANMAN2.1????????????????????W2K支持
????LANMAN2.1????????????????????????W2K支持
????NT LM 0.12????????????????????????W2K支持
????Cairo 0.xa????????????????????????W2K支持,這是NT后MS自己開(kāi)發(fā)的一個(gè)認(rèn)證協(xié)議
????
????這里我們首先講講大家用的最多和最熟悉的NTLM認(rèn)證方式:

????3。NTLM認(rèn)證過(guò)程
????NTLM在發(fā)展的過(guò)程中也存在這兼容的一些問(wèn)題,現(xiàn)在的NTLM是支持挑戰(zhàn)方式的,但原始的W9X的NTLM則不支持挑戰(zhàn)會(huì)話方式的,所以
從協(xié)議過(guò)程來(lái)看存在2種方式,一種是支持挑戰(zhàn)加密的方式(NT,2K等),一種是不支持加密挑戰(zhàn)的方式(W9X)。
????i.????認(rèn)證過(guò)程1
?????(客戶端發(fā)起:會(huì)話協(xié)商協(xié)議)包含支持NTLM認(rèn)證的選項(xiàng)且支持挑戰(zhàn)選項(xiàng)。
????? (服務(wù)器:會(huì)話協(xié)商協(xié)議)選擇了NTLM認(rèn)證協(xié)議,且包含服務(wù)器的GUID
?????(客戶端發(fā)起:會(huì)話設(shè)置和X協(xié)議)申請(qǐng)?zhí)魬?zhàn)會(huì)話的安全BLOB
?????(服務(wù)器:會(huì)話設(shè)置和X協(xié)議)返回帶有挑戰(zhàn)KEY的安全BLOB
?????(客戶端發(fā)起:會(huì)話設(shè)置和X協(xié)議)帶會(huì)話KEY加密的口令散列的安全BLOB
?????????認(rèn)證成功:會(huì)話設(shè)置和X協(xié)議返回成功信息
????????認(rèn)證失敗:會(huì)話設(shè)置和X協(xié)議返回失敗信息,發(fā)起注銷協(xié)議包
????ii.????認(rèn)證過(guò)程2
?????(客戶端發(fā)起:會(huì)話協(xié)商協(xié)議)包含支持NTLM認(rèn)證的選項(xiàng)且不支持挑戰(zhàn)選項(xiàng)。
????? (服務(wù)器:會(huì)話協(xié)商協(xié)議)選擇了NTLM認(rèn)證協(xié)議,且包含會(huì)話KEY
?????(客戶端發(fā)起:會(huì)話設(shè)置和X協(xié)議)使用會(huì)話KEY加密的密碼散列
//注意可以指定是非加密方式的密碼明文來(lái)進(jìn)行登陸
?????認(rèn)證成功:會(huì)話設(shè)置和X協(xié)議返回成功信息
????認(rèn)證失敗:會(huì)話設(shè)置和X協(xié)議返回失敗信息,發(fā)起注銷協(xié)議包

????我們這里主要講認(rèn)證過(guò)程1,其實(shí)過(guò)程2一般為很多工具使用,因?yàn)榭梢酝ㄟ^(guò)特定的FLAG字段指定不使用挑戰(zhàn)和加密方式進(jìn)行登陸,
那么就可以方便的使用明文口令,如SMBCRACK主要使用這種方法進(jìn)行口令暴力破解,但是需要注意的一點(diǎn)是,這種屬于老的方式,是可以在
服務(wù)器端禁止的。
????客戶端APP通過(guò)寫入WKSSVC管道(LPC端口發(fā)起)相關(guān)命令和數(shù)據(jù)
????????客戶端MRXSMB.SYS的SmbCeNegotiate函數(shù)負(fù)責(zé)進(jìn)行協(xié)商包的封裝并交下級(jí)驅(qū)動(dòng)封裝
????????服務(wù)器SRV.SYS的SrvSmbNegotiate函數(shù)負(fù)責(zé)選取一個(gè)認(rèn)證協(xié)議并返回給客戶端,并返回服務(wù)器的GUID
????客戶端的MRXSMB.SYS的SmbCeReferenceSession負(fù)責(zé)進(jìn)行認(rèn)證:
模擬過(guò)程函數(shù)如下:

BYTE buf1[0x404c];
TOKEN_STATISTICS ts;
CredHandle phs;
CredHandle phc;
CtxtHandle cthc;
CtxtHandle cths;
SECURITY_STATUS?? ss;
wchar_t TargetName[]=L"HOST/192.168.0.34";
int len;

typedef struct _Credentials
{
????char * pusername;
????DWORD usernamelen;
????char * pdomainname;
????DWORD domainnamelen;
????char * ppassword;
????DWORD passwordlen;
????DWORD credtype;
????BYTE info[0x200];
}Credentials,* PCredentials;

void client1()
{
????Credentials crt;
????LUID LogonID;
????HANDLE tk;
????TimeStamp Lifetime;
????DWORD ContextAttributes;
????DWORD rlen;
????char crtinfo[]={'a',0,'d',0,'m',0,'i',0,'n',0,'i',0,'s',0,'t',0,'r',0,'a',0,'t',0,'o',0,'r',0,0,0,'p',0,'s',0,'w',0,'d',0,0,0};
????
????SecBufferDesc???? OutBuffDesc;
????SecBufferDesc???? InBuffDesc;
????SecBuffer???????? InSecBuff;
????SecBuffer???????? OutSecBuff;
????LogonID.HighPart =0;
????LogonID.LowPart = 0x7d80;

????//輸入的口令在此需要CRT
????//自動(dòng)的則不需要
????OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tk);
????GetTokenInformation(tk,TokenStatistics,&ts,sizeof(ts),&rlen);
????crt.pusername = crt.info;
????crt.usernamelen = 0xd;
????crt.pdomainname =0;
????crt.domainnamelen = 0;
????crt.ppassword = crt.info+0x1c;
????crt.passwordlen =4;
????crt.credtype = 6;
????memcpy(crt.info,crtinfo,0x22);

????ss=AcquireCredentialsHandleW
????????(NULL,L"Negotiate",SECPKG_CRED_OUTBOUND,&ts.AuthenticationId,&crt,NULL,NULL,&phc,&Lifetime);

????InBuffDesc.ulVersion = 0;
????InBuffDesc.cBuffers = 1;
????InBuffDesc.pBuffers = &InSecBuff;
????InSecBuff.BufferType =SECBUFFER_TOKEN;
????InSecBuff.cbBuffer =0;
????InSecBuff.pvBuffer = buf1;
????OutBuffDesc.ulVersion = 0;
????OutBuffDesc.cBuffers = 1;
????OutBuffDesc.pBuffers = &OutSecBuff;
????OutSecBuff.BufferType = SECBUFFER_TOKEN;
????OutSecBuff.cbBuffer =0x404c;
????OutSecBuff.pvBuffer = buf1;
????ss=InitializeSecurityContextW(
????????????&phc,
????????????NULL,
????????????TargetName,
????????????ASC_REQ_MUTUAL_AUTH|ASC_REQ_DELEGATE|ASC_REQ_STREAM|ASC_REQ_ALLOW_NON_USER_LOGONS,//0x210003
????????????0,
????????????SECURITY_NATIVE_DREP,
????????&InBuffDesc,
????????????0,
????????????&cthc,
????????????&OutBuffDesc,
????????????&ContextAttributes,
????????????&Lifetime
????????????);
????len=OutSecBuff.cbBuffer;
????
}
????解釋:
????TargetName后面的192.168.0.34是SMB服務(wù)器的名字,如果是用的IP就使用IP,用的NETBIOS名字就使用NETBIOS名字
????InitializeSecurityContextW之后的buf1里面就是BLOB數(shù)據(jù)。然后將此數(shù)據(jù)放于SMB包中的安全BLOB處進(jìn)行傳送。
????AcquireCredentialsHandle中的crt是當(dāng)使用輸入用戶與口令的時(shí)候使用的,格式是明文和UNICODE的(參考Credentials結(jié)構(gòu))。當(dāng)
系統(tǒng)使用SAM數(shù)據(jù)進(jìn)行登陸的時(shí)候,此處可以是NULL;NULL的時(shí)候和非NULL的時(shí)候生成的安全BLOB的頭內(nèi)容是不同的。
????ts.AuthenticationId是認(rèn)證的LUID,其實(shí)MRXSMB使用的是WIN32K.sys的不對(duì)外的GetProcessLuid函數(shù)來(lái)獲取的,這里使用
GetTokenInformation來(lái)進(jìn)行模擬。當(dāng)系統(tǒng)使用系統(tǒng)的SAM登陸時(shí),必須獲得此值,才知道使用的認(rèn)證ID,當(dāng)然如果你知道且能獲得其他用戶進(jìn)
程的認(rèn)證LUID,也可以使用,不僅僅非要是自己進(jìn)程的認(rèn)證LUID;

????服務(wù)器的SRV.SYS獲得此安全BLOB之后,調(diào)用SrvSmbSessionSetupAndX函數(shù)來(lái)進(jìn)行處理,實(shí)際的處理函數(shù)是BlockingSessionSetupAndX函數(shù)。
調(diào)用SrvValidateSecurityBuffer,主要工作是根據(jù)客戶端的初始BLOB生成帶會(huì)話KEY的安全BLOB返回給客戶端,模擬程序如下:

void server2()
{
????TimeStamp???????? Lifetime;
????SecBufferDesc???? OutBuffDesc;
????SecBuffer???????? OutSecBuff;
????SecBufferDesc???? InBuffDesc;
????SecBuffer???????? InSecBuff;
????DWORD ContextAttributes;
????BYTE pOut[0X40DD];
????BYTE pIn[0X50];
????
????ss=AcquireCredentialsHandleW
????????(NULL,L"Negotiate",SECPKG_CRED_INBOUND,NULL,NULL,NULL,NULL,&phs,&Lifetime);

?? OutBuffDesc.ulVersion = 0;
?? OutBuffDesc.cBuffers = 1;
?? OutBuffDesc.pBuffers = &OutSecBuff;
?? OutSecBuff.cbBuffer = 0x40dd;
?? OutSecBuff.BufferType = SECBUFFER_TOKEN;
?? OutSecBuff.pvBuffer = pOut;
?? InBuffDesc.ulVersion = 0;
?? InBuffDesc.cBuffers = 1;
?? InBuffDesc.pBuffers = &InSecBuff;
?? InSecBuff.cbBuffer = len;
?? InSecBuff.BufferType = SECBUFFER_TOKEN;
?? InSecBuff.pvBuffer = pIn;
?? memset(pIn,0,0x40dd);
?? memset(pOut,0,0x40dd);
?? memcpy(pIn,buf1,0x10);

?? ss=AcceptSecurityContext (
????????????&phs,
????????????NULL,
????????????&InBuffDesc,
????????????ASC_REQ_DELEGATE|ASC_REQ_EXTENDED_ERROR|ASC_REQ_FRAGMENT_TO_FIT, //ASC_REQ_ALLOW_NULL_SESSION
????????????0x10,//SECURITY_NATIVE_DREP,

????????????&cths,
????????????&OutBuffDesc,
????????????&ContextAttributes,
????????????&Lifetime
????????????);
????len=OutSecBuff.cbBuffer;
}

????解釋:
????ASC_REQ_ALLOW_NULL_SESSION選項(xiàng)在用戶模式下不可用,在SRV.SYS則可以使用
????實(shí)際上客戶端生成的初始BLOB只有前0X10字節(jié)(BLOB頭)是有意義的,AcceptSecurityContext執(zhí)行后的pOut緩沖里就是需要返回的
帶會(huì)話KEY的安全BLOB

????客戶端的MRXSMB.SYS獲得這個(gè)安全BLOB后就會(huì)使用此KEY進(jìn)行加密。模擬的程序如下:
void client3()
{
????TimeStamp Lifetime;
????DWORD ContextAttributes;
????SecBufferDesc???? OutBuffDesc;
????SecBufferDesc???? InBuffDesc;
????SecBuffer???????? InSecBuff;
????SecBuffer???????? OutSecBuff;

????InBuffDesc.ulVersion = 0;
????InBuffDesc.cBuffers = 1;
????InBuffDesc.pBuffers = &InSecBuff;
????InSecBuff.BufferType =SECBUFFER_TOKEN;
????InSecBuff.cbBuffer =len;
????InSecBuff.pvBuffer = buf1;
????OutBuffDesc.ulVersion = 0;
????OutBuffDesc.cBuffers = 1;
????OutBuffDesc.pBuffers = &OutSecBuff;
????OutSecBuff.BufferType = SECBUFFER_TOKEN;
????OutSecBuff.cbBuffer =0x404c;
????OutSecBuff.pvBuffer = buf1;
????ss=
(
????????????&phc,
????????????&cthc,
????????????TargetName,
????????????ASC_REQ_MUTUAL_AUTH|ASC_REQ_DELEGATE|ASC_REQ_STREAM|ASC_REQ_ALLOW_NON_USER_LOGONS,//0x210003
????????????0,
????????????SECURITY_NATIVE_DREP,
????????????&InBuffDesc,
????????????0,
????????????&cthc,
????????????&OutBuffDesc,
????????????&ContextAttributes,
????????????&Lifetime
????????????);
}
????
????在這個(gè)生成的過(guò)程中一些特性:
????我們使用同一返回的KEY,每次生成的認(rèn)證內(nèi)容都不一樣,但是每次都是可以被認(rèn)證的,那么我們可以得出一個(gè)結(jié)論,在這個(gè)認(rèn)證的
????信息里還包含有時(shí)間戳或其他隨機(jī)生成數(shù)據(jù),加密和解密的算法還使用到了這個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)也在認(rèn)證內(nèi)容中一起被發(fā)送到服務(wù)器。

服務(wù)器端進(jìn)行認(rèn)證的代碼
void server4()
{
????TimeStamp???????? Lifetime;
????SecBufferDesc???? OutBuffDesc;
????SecBuffer???????? OutSecBuff;
????SecBufferDesc???? InBuffDesc;
????SecBuffer???????? InSecBuff;
????DWORD ContextAttributes;
????

?? OutBuffDesc.ulVersion = 0;
?? OutBuffDesc.cBuffers = 1;
?? OutBuffDesc.pBuffers = &OutSecBuff;
?? OutSecBuff.cbBuffer = 0x40dd;
?? OutSecBuff.BufferType = SECBUFFER_TOKEN;
?? OutSecBuff.pvBuffer = buf1;
?? InBuffDesc.ulVersion = 0;
?? InBuffDesc.cBuffers = 1;
?? InBuffDesc.pBuffers = &InSecBuff;
?? InSecBuff.cbBuffer = len;
?? InSecBuff.BufferType = SECBUFFER_TOKEN;
?? InSecBuff.pvBuffer = buf1;


?? ss=AcceptSecurityContext (
????????????&phs,
????????????&cths,
????????????&InBuffDesc,
????????????ASC_REQ_DELEGATE|ASC_REQ_EXTENDED_ERROR|ASC_REQ_FRAGMENT_TO_FIT, //ASC_REQ_ALLOW_NULL_SESSION
????????????0x10,//SECURITY_NATIVE_DREP,
????????????&cths,
????????????&OutBuffDesc,
????????????&ContextAttributes,
????????????&Lifetime
????????????);
????if(ss==SEC_E_OK)
????????printf("ok");
????else
????????printf("error");
????
}
????
4.挑戰(zhàn)NTLM的編程實(shí)現(xiàn)
????????那么我們就可以實(shí)現(xiàn)一個(gè)純TCP/IP的SMB使用NTLM的挑戰(zhàn)方式進(jìn)行登陸了,再這之前大家需要了解SMB協(xié)議,這里由于涉及到
公司的商業(yè)利益,我不能給予大家最詳細(xì)的協(xié)議說(shuō)明,但從程序代碼和其中的注解大家應(yīng)該大致知道。這個(gè)程序大家修改一下就可以
得到類似SMBCRACK功能的口令破解的多線程支持NTLM挑戰(zhàn)方式的(這樣可以使用在標(biāo)準(zhǔn)的W2K認(rèn)可的方式,關(guān)閉了非挑戰(zhàn)和不許可明
文口令方式登陸的W2K服務(wù)器)的工具,但是由于口令計(jì)算的消耗,速度就會(huì)慢一些:
SMB.h文件:
#include <windows.h>

typedef struct _SMBNBT
{
????unsigned char nbtsmb;
????unsigned char flag;
????short smbpacketlen;
}SMBNBT,* PSMBNBT;

typedef struct _SMBINFO
{
????unsigned char magic[4];
????BYTE smbtoken;
????BYTE errcodeclass;
????BYTE dosaherrcode;
????unsigned char errcode[2];
????BYTE flagsummary;
????short flagsummary2;
????short unuse[6];
????short treeid;
????short callprocessid;
????short userid;
????short multiplexid;
????unsigned char info[2048];
}SMBINFO,* PSMBINFO;

typedef struct _SMBP
{
????SMBNBT smbnbt;
????SMBINFO smbinfo;
}SMBP,* PSMBP;

typedef struct _Credentials
{
????char * pusername;
????DWORD usernamelen;
????char * pdomainname;
????DWORD domainnamelen;
????char * ppassword;
????DWORD passwordlen;
????DWORD credtype;
????BYTE info[0x200];
}Credentials,* PCredentials;
????
客戶端程序:

#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <wincrypt.h>
#include <process.h>
#include <string.h>
#include <winbase.h>
# include <wincrypt.h>
#define SECURITY_WIN32
# include <Security.h>
#include "SMB.H"

void SmbNegotiate(SMBP * psmbp);
void SmbSessionSetupAndX1(SMBP * psmbp,wchar_t * username,wchar_t * domainname,wchar_t * password);
void SmbSessionSetupAndX2(SMBP * psmbp,unsigned char * ntlmrcv,short ntlmlen);

TOKEN_STATISTICS ts;
CredHandle phs;
CredHandle phc;
CtxtHandle cthc;
CtxtHandle cths;
SECURITY_STATUS?? ss;
wchar_t TargetName[]=L"HOST/192.168.13.34";//后面的192.168.0.34是SMB服務(wù)器的名字,如果是用的IP就使用IP,用的NETBIOS名字就使用NETBIOS名字)
wchar_t navos[]=L"windows 2000 2195";
wchar_t lanman[]=L"windows 2000 5.0";

void main(int argc,char ** argv)
{
????WSADATA WSAData;
????int i;
????SOCKET sock;
????SOCKADDR_IN addr_in;
????int len;
????char serverip[]="192.168.13.34";
????short port=445;
????WORD olen,nlen;
????unsigned char buf1[0x1000];
????SMBP smbp;

????if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0)
????{
????????printf("WSAStartup error.Error:%d\n",WSAGetLastError());
????????return;
????}

????addr_in.sin_family=AF_INET;
????addr_in.sin_port=htons(port);
????addr_in.sin_addr.S_un.S_addr=inet_addr(serverip);
????
????if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
????{
????????printf("Socket failed.Error:%d\n",WSAGetLastError());
????????return;
????}
????if(WSAConnect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in),NULL,NULL,NULL,NULL)==SOCKET_ERROR)
????{
????????printf("Connect failed.Error:%d",WSAGetLastError());
????????return;
????}
????SmbNegotiate(&smbp);
????if (send(sock,(unsigned char *)&smbp,ntohs(smbp.smbnbt.smbpacketlen)+4,0)==SOCKET_ERROR)
????{
????????????printf("Send failed.Error:%d\n",WSAGetLastError());
????????????return;
????}
????len=recv(sock,buf1,1024,NULL);
????SmbSessionSetupAndX1(&smbp,L"administrator",L"",L"1972");
????if (send(sock,(unsigned char *)&smbp,ntohs(smbp.smbnbt.smbpacketlen)+4,0)==SOCKET_ERROR)
????{
????????????printf("Send failed.Error:%d\n",WSAGetLastError());
????????????return;
????}
????len=recv(sock,buf1,1024,NULL);
????if((buf1[0]==0xff)&&(buf1[1]=='S')&&(buf1[2]=='M')&&(buf1[3]=='B'))
????????olen=0x20;
????else if((buf1[4]==0xff)&&(buf1[5]=='S')&&(buf1[6]=='M')&&(buf1[7]=='B'))
????????olen=0x24;
????else
????????return;
????smbp.smbinfo.userid =??*(WORD *)(buf1+olen-0x4);
????nlen=*(WORD *)(buf1+olen+1+2*3);//BLOB的長(zhǎng)度
????olen=olen+1+2*buf1[olen]+2;
????SmbSessionSetupAndX2(&smbp,buf1+olen,nlen);
????if (send(sock,(unsigned char *)&smbp,ntohs(smbp.smbnbt.smbpacketlen)+4,0)==SOCKET_ERROR)
????{
????????????printf("Send failed.Error:%d\n",WSAGetLastError());
????????????return;
????}
????len=recv(sock,buf1,1024,NULL);
????if((buf1[0]==0xff)&&(buf1[1]=='S')&&(buf1[2]=='M')&&(buf1[3]=='B'))
????????olen=0x20;
????else if((buf1[4]==0xff)&&(buf1[5]=='S')&&(buf1[6]=='M')&&(buf1[7]=='B'))
????????olen=0x24;
????else
????????return;
????if(buf1[olen]==0)
????????printf("error username and password\n");
????else
????????printf("login ok\n");
????WSACleanup();
????return;
}

void SmbSessionSetupAndX1(SMBP * psmbp,wchar_t * username,wchar_t * domainname,wchar_t * password)
{
????LUID LogonID;
????unsigned char buf1[0x404c];
????HANDLE tk;
????TimeStamp Lifetime;
????DWORD ContextAttributes;
????DWORD rlen;
????DWORD r1,r2,r3;
????int i;
????Credentials crt;
????SecBufferDesc???? OutBuffDesc;
????SecBufferDesc???? InBuffDesc;
????SecBuffer???????? InSecBuff;
????SecBuffer???????? OutSecBuff;
????LogonID.HighPart =0;
????LogonID.LowPart = 0x7d80;

????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 參數(shù)個(gè)數(shù)
????*(WORD *)(psmbp->smbinfo.info+1)=0Xff;//無(wú)下一個(gè)命令
????*(WORD *)(psmbp->smbinfo.info+3)=0Xb0;//下一命令偏移
????*(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;//保留

????//輸入的口令在此需要CRT
????//自動(dòng)的則不需要
????OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tk);
????GetTokenInformation(tk,TokenStatistics,&ts,sizeof(ts),&rlen);
????r1=0;
????for(i=0;i<0x30;i++)
????{
????????if(username[i]==0)
????????????break;
????????r1=r1+2;
????}
????r2=0;
????for(i=0;i<0x30;i++)
????{
????????if(domainname[i]==0)
????????????break;
????????r2=r2+2;
????}
????r3=0;
????for(i=0;i<0x30;i++)
????{
????????if(password[i]==0)
????????????break;
????????r3=r3+2;
????}
????crt.pusername = crt.info;
????crt.usernamelen = r1/2;
????if(r2>0)
????{
????????crt.pdomainname =crt.info+r1+2;
????????crt.domainnamelen = r2/2;
????????crt.ppassword = crt.pdomainname+r2+2;
????????crt.passwordlen =r3/2;
????}
????else
????{
????????crt.pdomainname =0;
????????crt.domainnamelen = 0;
????????crt.ppassword = crt.info+r1+2;
????????crt.passwordlen =r3/2;
????}
????crt.credtype = 6;
????memcpy(crt.pusername,username,r1);
????if(r2>0)
????????memcpy(crt.pdomainname,domainname,r2);
????memcpy(crt.ppassword,password,r3);
????ss=AcquireCredentialsHandleW
????????(NULL,L"Negotiate",SECPKG_CRED_OUTBOUND,&ts.AuthenticationId,&crt,NULL,NULL,&phc,&Lifetime);
????//LOGIN會(huì)影響生成
????InBuffDesc.ulVersion = 0;
????InBuffDesc.cBuffers = 1;
????InBuffDesc.pBuffers = &InSecBuff;
????InSecBuff.BufferType =SECBUFFER_TOKEN;
????InSecBuff.cbBuffer =0;
????InSecBuff.pvBuffer = buf1;
????OutBuffDesc.ulVersion = 0;
????OutBuffDesc.cBuffers = 1;
????OutBuffDesc.pBuffers = &OutSecBuff;
????OutSecBuff.BufferType = SECBUFFER_TOKEN;
????OutSecBuff.cbBuffer =0x404c;
????OutSecBuff.pvBuffer = buf1;
????ss=InitializeSecurityContextW(
????????????&phc,
????????????NULL,
????????????TargetName,
????????????ASC_REQ_MUTUAL_AUTH|ASC_REQ_DELEGATE|ASC_REQ_STREAM|ASC_REQ_ALLOW_NON_USER_LOGONS,//0x210003
????????????0,
????????????SECURITY_NATIVE_DREP,
????????????&InBuffDesc,
????????????0,
????????????&cthc,
????????????&OutBuffDesc,
????????????&ContextAttributes,
????????????&Lifetime
????????????);

????*(WORD *)(psmbp->smbinfo.info+15)=OutSecBuff.cbBuffer;??//BLOB的長(zhǎng)度
????memcpy(psmbp->smbinfo.info+27,buf1,OutSecBuff.cbBuffer);//放入BLOB
????memcpy(psmbp->smbinfo.info+28+OutSecBuff.cbBuffer,navos,36);//
????memcpy(psmbp->smbinfo.info+66+OutSecBuff.cbBuffer,lanman,32);//
????*(WORD *)(psmbp->smbinfo.info+25)=73+OutSecBuff.cbBuffer;
????psmbp->smbnbt.smbpacketlen = htons(132+ OutSecBuff.cbBuffer);
}

void SmbSessionSetupAndX2(SMBP * psmbp,unsigned char * ntlmrcv,short ntlmlen)
{
????TimeStamp Lifetime;
????DWORD ContextAttributes;
????SecBufferDesc???? OutBuffDesc;
????SecBufferDesc???? InBuffDesc;
????SecBuffer???????? InSecBuff;
????SecBuffer???????? OutSecBuff;
????unsigned char buf1[0x404c];

????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 參數(shù)個(gè)數(shù)
????*(WORD *)(psmbp->smbinfo.info+1)=0Xff;//無(wú)下一個(gè)命令
????*(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;//保留

????//輸入的口令在此需要CRT
????//自動(dòng)的則不需要
????InBuffDesc.ulVersion = 0;
????InBuffDesc.cBuffers = 1;
????InBuffDesc.pBuffers = &InSecBuff;
????InSecBuff.BufferType =SECBUFFER_TOKEN;
????InSecBuff.cbBuffer =ntlmlen;
????InSecBuff.pvBuffer = ntlmrcv;
????OutBuffDesc.ulVersion = 0;
????OutBuffDesc.cBuffers = 1;
????OutBuffDesc.pBuffers = &OutSecBuff;
????OutSecBuff.BufferType = SECBUFFER_TOKEN;
????OutSecBuff.cbBuffer =0x404c;
????OutSecBuff.pvBuffer = buf1;
????ss=InitializeSecurityContextW(
????????????&phc,
????????????&cthc,
????????????TargetName,
????????????ASC_REQ_MUTUAL_AUTH|ASC_REQ_DELEGATE|ASC_REQ_STREAM|ASC_REQ_ALLOW_NON_USER_LOGONS,//0x210003
????????????0,
????????????SECURITY_NATIVE_DREP,
????????????&InBuffDesc,
????????????0,
????????????&cthc,
????????????&OutBuffDesc,
????????????&ContextAttributes,
????????????&Lifetime
????????????);
????*(WORD *)(psmbp->smbinfo.info+15)=OutSecBuff.cbBuffer;??//BLOB的長(zhǎng)度
????memcpy(psmbp->smbinfo.info+27,buf1,OutSecBuff.cbBuffer);//放入BLOB
????memcpy(psmbp->smbinfo.info+28+OutSecBuff.cbBuffer,navos,36);//
????memcpy(psmbp->smbinfo.info+66+OutSecBuff.cbBuffer,lanman,32);//
????*(WORD *)(psmbp->smbinfo.info+25)=73+OutSecBuff.cbBuffer;
????psmbp->smbnbt.smbpacketlen = htons(132+ OutSecBuff.cbBuffer);
}

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;
????//指定了帶挑戰(zhàn)方式支持的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,langitem3,sizeof(langitem3));
????len = len+1+sizeof(langitem3);
????
????psmbp->smbinfo.info[len]=0x2;
????memcpy(psmbp->smbinfo.info+len+1,langitem1,sizeof(langitem1));
????len = len+1+sizeof(langitem1);

????psmbp->smbinfo.info[len]=0x2;
????memcpy(psmbp->smbinfo.info+len+1,langitem2,sizeof(langitem2));
????len = len+1+sizeof(langitem2);
????

????psmbp->smbinfo.info[len]=0x2;
????memcpy(psmbp->smbinfo.info+len+1,langitem4,sizeof(langitem4));
????len = len+1+sizeof(langitem4);

????
????psmbp->smbinfo.info[len]=0x2;
????memcpy(psmbp->smbinfo.info+len+1,langitem5,sizeof(langitem5));
????len = len+1+sizeof(langitem5);
????????
????psmbp->smbinfo.info[len]=0x2;
????memcpy(psmbp->smbinfo.info+len+1,langitem6,sizeof(langitem6));
????len = len+1+sizeof(langitem6);
????*/
????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);
}

SMB的NTLM認(rèn)證過(guò)程與NTLM挑戰(zhàn)的編程實(shí)現(xiàn)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 精品国产一区二区三区免费 | 91青青青 | 日本高清免费不卡在线播放 | 99精品免费观看 | 97久久综合精品久久久综合 | 久久99九九99九九精品 | 亚洲精品无码不卡在线播放he | 91成人免费观看网站 | 欧美午夜视频 | 久草精品视频在线观看 | 四虎影视入口 | 国产香蕉98碰碰久久人人 | 成人免费视频一区二区三区 | 亚洲国产成人久久一区二区三区 | 特黄特级a级黄毛片免费观看多人 | 一级免费大片 | 亚洲视频国产 | 国产在线91区精品 | 好吊妞视频一区二区 | 99久久国内精品成人免费 | 91精品国产人成网站 | 欧美十区| 夜夜欢视频 | 日韩欧美在线中文字幕 | 九七97影院理论片手机在线观看 | 东京99热 | 国产区综合另类亚洲欧美 | 天天做人人爱夜夜爽2020 | 四虎国产永久免费久久 | 九九热这里都是精品 | 亚洲九月天 | 亚洲在线免费视频 | 色综合在| 97色综合| 久久96国产精品久久久 | avtt男人天堂 | 久久精品国产99久久6动漫欧 | 国产精品亚洲一区二区三区 | 日本九九视频 | 亚洲毛片在线 | 色老头xxxwww作爱视频 |