NTLM

 

NTLM HTTP认证

过程如下:

    1: C  --> S   GET ...

    2: C <--  S   401 Unauthorized

                 WW-Authenticate: NTLM

    3: C  --> S   GET ...

                 Authorization: NTLM <base64-encoded type-1-message>

    4: C <--  S   401 Unauthorized

                 WWW-Authenticate: NTLM <base64-encoded type-2-message>

    5: C  --> S   GET ...

                 Authorization: NTLM <base64-encoded type-3-message>

    6: C <--  S   200 Ok

从交互过程可以发现,client会发送type-1消息和type-3消息给server,而server会发送type-2消息给client

Type-1消息包括机器名、Domain

Type-2消息包括server发出的NTLM challenge

Type-3消息包括用户名、机器名、Domain、以及两个根据server发出的challenge计算出的response,这里response是基于challenge和当前用户的登录密码计算而得

 

SMB协议可以说是WIN系统的核心协议,这里大致给大家讲解一下SMB认证登陆的过程:
          1。协议解析栈
          CLIENT:APP----->NET/MRP/RPC
      API------>MRXSMB.SYS------>NETBT.SYS---->TCP/IP
                                                                
          SERVER:
      SRV.SYS<-----------MRXSMB.SYS<----------NETBT.SYS<--------TCP/IP
        
           应用程序调用NET/MPR/RPC等API将信息写入WKSSVC管道,这个管道是一个特殊的管道,对应的其实是一个LPC端口。
           MRXSMB.SYS是一个SMB的小端口驱动,负责完成客户端的SMB的封装和实现,如发起协商,认证的加密/解密过程等。对于服务器端则主要
      完成会话状态的一些管理,然后将SMB包发送给下级驱动处理。
           NETBT.SYS是NETBIOS OVER
      TCP/IP的驱动,一般都是作为MRXSMB的下级驱动,不过MRXSMB也可以有其他的下级驱动,最后通过一个网络驱
      动实现通讯,这里假设是使用TCP/IP。
           SRV.SYS是服务器端的SMB协议驱动程序,实现完成真正的SMB的协议功能,然后将结果按原路返回给客户端。

          2。SMB的认证协议。
          通过SMB进行认证客户端一般都要先使用SMB的协商命令(0X72)发送客户端支持的认证协议给服务器,服务器则选择其中的一个,然后返回
      给客户端,客户端然后再使用SMB的会话设置和X命令(0X73)进行认证和登陆。
          MS的SMB已经使用的SMB认证协议有:
            协议                        备注
          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使用此协议方式。
          LM1.2X002                        W2K支持  
          DOS LANMAN2.1                    W2K支持
          LANMAN2.1                        W2K支持
          NT LM 0.12                        W2K支持
          Cairo 0.xa                        W2K支持,这是NT后MS自己开发的一个认证协议
         
          这里我们首先讲讲大家用的最多和最熟悉的NTLM认证方式:

          3。NTLM认证过程
          NTLM在发展的过程中也存在这兼容的一些问题,现在的NTLM是支持挑战方式的,但原始的W9X的NTLM则不支持挑战会话方式的,所以
      从协议过程来看存在2种方式,一种是支持挑战加密的方式(NT,2K等),一种是不支持加密挑战的方式(W9X)。
          i.    认证过程1
      ?    (客户端发起:会话协商协议)包含支持NTLM认证的选项且支持挑战选项。
      ?     (服务器:会话协商协议)选择了NTLM认证协议,且包含服务器的GUID
      ?    (客户端发起:会话设置和X协议)申请挑战会话的安全BLOB
      ?    (服务器:会话设置和X协议)返回带有挑战KEY的安全BLOB
      ?    (客户端发起:会话设置和X协议)带会话KEY加密的口令散列的安全BLOB
      ?        认证成功:会话设置和X协议返回成功信息
              认证失败:会话设置和X协议返回失败信息,发起注销协议包
          ii.    认证过程2
      ?    (客户端发起:会话协商协议)包含支持NTLM认证的选项且不支持挑战选项。
      ?     (服务器:会话协商协议)选择了NTLM认证协议,且包含会话KEY
      ?    (客户端发起:会话设置和X协议)使用会话KEY加密的密码散列
      //注意可以指定是非加密方式的密码明文来进行登陆
      ?    认证成功:会话设置和X协议返回成功信息
          认证失败:会话设置和X协议返回失败信息,发起注销协议包

          我们这里主要讲认证过程1,其实过程2一般为很多工具使用,因为可以通过特定的FLAG字段指定不使用挑战和加密方式进行登陆,
      那么就可以方便的使用明文口令,如SMBCRACK主要使用这种方法进行口令暴力破解,但是需要注意的一点是,这种属于老的方式,是可以在
      服务器端禁止的。
          客户端APP通过写入WKSSVC管道(LPC端口发起)相关命令和数据
              客户端MRXSMB.SYS的SmbCeNegotiate函数负责进行协商包的封装并交下级驱动封装
              服务器SRV.SYS的SrvSmbNegotiate函数负责选取一个认证协议并返回给客户端,并返回服务器的GUID
          客户端的MRXSMB.SYS的SmbCeReferenceSession负责进行认证:
      模拟过程函数如下:

      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
          //自动的则不需要
          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服务器的名字,如果是用的IP就使用IP,用的NETBIOS名字就使用NETBIOS名字
          InitializeSecurityContextW之后的buf1里面就是BLOB数据。然后将此数据放于SMB包中的安全BLOB处进行传送。
         
      AcquireCredentialsHandle中的crt是当使用输入用户与口令的时候使用的,格式是明文和UNICODE的(参考Credentials结构)。当
      系统使用SAM数据进行登陆的时候,此处可以是NULL;NULL的时候和非NULL的时候生成的安全BLOB的头内容是不同的。
         
      ts.AuthenticationId是认证的LUID,其实MRXSMB使用的是WIN32K.sys的不对外的GetProcessLuid函数来获取的,这里使用
      GetTokenInformation来进行模拟。当系统使用系统的SAM登陆时,必须获得此值,才知道使用的认证ID,当然如果你知道且能获得其他用户进
      程的认证LUID,也可以使用,不仅仅非要是自己进程的认证LUID;

         
      服务器的SRV.SYS获得此安全BLOB之后,调用SrvSmbSessionSetupAndX函数来进行处理,实际的处理函数是BlockingSessionSetupAndX函数。
      调用SrvValidateSecurityBuffer,主要工作是根据客户端的初始BLOB生成带会话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选项在用户模式下不可用,在SRV.SYS则可以使用
         
      实际上客户端生成的初始BLOB只有前0X10字节(BLOB头)是有意义的,AcceptSecurityContext执行后的pOut缓冲里就是需要返回的
      带会话KEY的安全BLOB

          客户端的MRXSMB.SYS获得这个安全BLOB后就会使用此KEY进行加密。模拟的程序如下:
      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
                  );
      }
         
          在这个生成的过程中一些特性:
          我们使用同一返回的KEY,每次生成的认证内容都不一样,但是每次都是可以被认证的,那么我们可以得出一个结论,在这个认证的
          信息里还包含有时间戳或其他随机生成数据,加密和解密的算法还使用到了这个数据,这个数据也在认证内容中一起被发送到服务器。

      服务器端进行认证的代码
      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.挑战NTLM的编程实现
              那么我们就可以实现一个纯TCP/IP的SMB使用NTLM的挑战方式进行登陆了,再这之前大家需要了解SMB协议,这里由于涉及到
      公司的商业利益,我不能给予大家最详细的协议说明,但从程序代码和其中的注解大家应该大致知道。这个程序大家修改一下就可以
      得到类似SMBCRACK功能的口令破解的多线程支持NTLM挑战方式的(这样可以使用在标准的W2K认可的方式,关闭了非挑战和不许可明
      文口令方式登陆的W2K服务器)的工具,但是由于口令计算的消耗,速度就会慢一些:
      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服务器的名字,如果是用的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的长度
          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 参数个数
          *(WORD *)(psmbp->smbinfo.info+1)=0Xff;//无下一个命令
          *(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
          //自动的则不需要
          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会影响生成
          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的长度
          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 参数个数
          *(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;//保留

          //输入的口令在此需要CRT
          //自动的则不需要
          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的长度
          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;
          //指定了带挑战方式支持的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);
      }

转载于:https://www.cnblogs.com/ahuo/archive/2008/09/03/1282745.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/476510.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT和DALLE-2级联后,输出效果震撼了…

源&#xff5c;机器之心 文&#xff5c;张倩、袁铭怿生成式 AI 正在变革内容的生产方式。在过去的一周&#xff0c;相信大家都被 ChatGPT 刷了屏。这个强大的对话 AI 仅用 5 天时间用户量就突破了 100 万。大家用各种方式测试着它的能力上限&#xff0c;其中一种测试方式就是让…

域用户频繁被锁定怎么解决_Oracle11g用户频繁锁定并且解锁后不允许登录

原因有可能是oracle的密码过期机制导致的&#xff1a;一、由于Oracle中默认在default概要文件中设置了“PASSWORD_LIFE_TIME180天”所导致。解决办法&#xff1a;1、查看用户用的哪种profile策略&#xff0c;一般是default&#xff1a;select username,profile from dba_users;…

LeetCode 1290. 二进制链表转整数

1. 题目 给你一个单链表的引用结点 head。 链表中每个结点的值不是 0 就是 1。 已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 示例 1&#xff1a; 输入&#xff1a;head [1,0,1] 输出&#xff1a;5 解释&#xff1a;二进制数 (101…

jmeter性能测试报告_用 JMeter 做接口测试的优劣浅析

2018年由软件质量报道做的调查报告表明&#xff0c;受调查的测试人员中约有40.67%的人使用JMeter作为接口测试的自动化测试工具(排在商业化或者开源工具中的第一)&#xff0c;剩下的为Postman(28%)&#xff0c;以及SoapUI(17.33%)。不过值得关注的是另外还有44.13%的采用了自研…

关于Hibernate

Hibernate是对象/关系映射&#xff08;ORM&#xff09;的解决方案。就是将java对象与对象关系映射至关系型数据库中的表格与表格之间的关系。 hibernate各个组件的关系 核心组件&#xff1a; Configuration类&#xff1a;用于读取Hibernian配置文件&#xff0c;并生成Sessio&am…

研究了一堆英语学习软件,发现了一个美国宝藏口语App,国内也能用!

图片来源&#xff1a;爱奇艺《一年一度喜剧大会》最近看《二喜》看到逗逗的这句话&#xff0c;我真的太同感了——一个人不知道做什么的时候&#xff0c;好像总会想到学英语这件事。“英语好”确实可以成为一剂强心针——更好的学业机会和更好的职业选择。《当代国人英语学习调…

jdbctemplate 开启事务_Spring(四):事务管理

事务首先&#xff0c;我们要知道事务是什么构成单一逻辑工作单元的操作集合称为事务事务的ACID特性原子性&#xff1a;不可分割的最小操作单位&#xff0c;要么同时成功&#xff0c;要么同时失败一致性&#xff1a;事务操作前后&#xff0c;数据总量不变隔离性&#xff1a;多个…

LeetCode 58. 最后一个单词的长度

1. 题目 给定一个仅包含大小写字母和空格 ’ ’ 的字符串 s&#xff0c;返回其最后一个单词的长度。 如果字符串从左向右滚动显示&#xff0c;那么最后一个单词就是最后出现的单词。 如果不存在最后一个单词&#xff0c;请返回 0 。 说明&#xff1a;一个单词是指仅由字母组…

prompt终于在机器人领域杀疯了

编&#xff5c;杜伟、陈萍源&#xff5c;机器之心谷歌机器人团队等在机器人领域构建了一个多任务 transformer 模型&#xff0c;显著改进了对新任务、环境和对象的零样本泛化。我们知道&#xff0c;机器学习&#xff08;ML&#xff09;多个子领域&#xff08;如 NLP 和 CV&…

python打开excel数据库_使用python导入excel文件中的mssql数据库数据

我试图用python导入excel文件中的mssql数据库数据。我的数据在excel表格中的顺序不正确。e、 g它显示第1列数据&#xff0c;然后是第3列&#xff0c;第2列&#xff0c;然后是第4列&#xff0c;依此类推。我使用以下脚本&#xff1a;import pyodbcimport csvconnection pyodbc.…

雷鸟安装的插件

lightning日历功能 同步lightning和google日历的插件&#xff1a;provider_for_google_calendar 使用可以参考&#xff1a;http://jackbin.blogspot.com/2008/02/lightning-5.html 导入OE邮件时用了ImportExportTools转载于:https://www.cnblogs.com/cerxp/archive/2008/09/28/…

LeetCode 66. 加一

1. 题目 给定一个由整数组成的非空数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这个整数不会以零开头。 示例 1: 输入: [1,2,3] 输出: [1,2,4] 解…

ChatGPT的前世今生

作者&#xff5c;符尧等整理&#xff5c;李rumor最近有幸看到了一篇十分深度剖析GPT系列模型的文章&#xff0c;读到后赶紧与作者联系&#xff0c;没想到他们很快就翻译成了中文&#xff0c;在这里分享给大家。英文原版:https://franxyao.github.io/blog.html作者&#xff1a;符…

文件管理(一)

文件是同一类型元素的有序集合&#xff0c;是内存与外设间传输数据的渠道。一些外设如显示器、键盘、打印机等都可以看作文件&#xff0c;但最常用的还是磁盘文件&#xff0c;这也是本章我们主要讨论的对象。 Delphi继承了Object Pascal的文件管理功能&#xff0c;并有很大的发…

LeetCode 95. 不同的二叉搜索树 II(递归)

1. 题目 给定一个整数 n&#xff0c;生成所有由 1 … n 为节点所组成的二叉搜索树。 示例: 输入: 3 输出: [[1,null,3,2],[3,2,null,1],[3,1,null,null,2],[2,1,3],[1,null,2,null,3] ] 解释: 以上的输出对应以下 5 种不同结构的二叉搜索树&#xff1a;1 3 3 …

离谱!以AI数据标注为名,偷拍女性上厕所?

源&#xff5c;新智元文&#xff5c;好困 David你绝对想不到&#xff0c;自己在家上厕所的「实时动态」&#xff0c;不仅被拿去给AI做了训练数据&#xff0c;而且还被发到了网上&#xff01;最近&#xff0c;《麻省理工科技评论》在一篇万字长文调查中&#xff0c;就曝光了这样…

treemap怎么保证有序_干货!208道面试题教你怎么通过面试!

[如您对本文感兴趣&#xff0c;请点击标题下方蓝色“拓达IT训练营”添加关注&#xff0c;每天都有精彩实用文章呈现给您]一、Java 基础1.JDK 和 JRE 有什么区别&#xff1f;2. 和 equals 的区别是什么&#xff1f;3.两个对象的 hashCode()相同&#xff0c;则 equals()也一定为 …

看美女无数

看美女无数——代腾飞 2008年9月30日 于成都漫漫长假&#xff0c;却不知如何渡大千世界&#xff0c;却找不到去处只好独自骑着车儿压马路 来来往往&#xff0c;美女无数虽闭城不出&#xff0c;却也大饱眼福知足&#xff0c;知足 坐看春熙路&#xff0c;看美女购物熙来攘往&am…

LeetCode 107. 二叉树的层次遍历 II(队列)

1. 题目 给定一个二叉树&#xff0c;返回其节点值自底向上的层次遍历。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 例如&#xff1a; 给定二叉树 [3,9,20,null,null,15,7],3/ \9 20/ \15 7 返回其自底向上的层次遍历为…

什么是document对象?如何获取文档对象上的元素?_dom对象

DOM对象1. DOM树当网页被加载时&#xff0c;浏览器会创建页面的文档对象模型&#xff08;Document Object Model&#xff09;&#xff0c;通过 HTML DOM对象&#xff0c;可访问 JavaScript HTML 文档的所有元素。HTML DOM 模型被构造为对象的树。节点(Node)&#xff1a;HTML文档…