实战NTLM
项目描述:2个域,A和BA的域服务器连接外网,同时装有isa2004防火墙,开web代理,信任域B需要域B的一台机器上穿透代理连接外网服务器(不是http服务器)完成代穿透后,卡在isa上;使用443意外端口得话,isa返回502错,使用443端口则返回407错结论:需要通过isa得域验证,且isa只允许443端口的ssl连接;isa支持windows集成身份验证(NTLM和Kerberos)
进入本文主题:NTLM验证一、NTLM验证过程简介1、客户端向代理服务器(支持NTLM)发送请求,内容包括本机的机器名和域名2、代理服务器收到后,根据域名去对应域服务器获取客户机的域信息,并返回一个8byte的挑战码给客户端3、客户端收到挑战码后,使用域帐户密码作为密钥进行加密,把结果密文发送给代理服务器4、代理服务器也根据挑战码加密,和收到的密文进行比对,确定验证是否成功
二、具体过程NTLM 要在客户端和服务器内进行3次交互,来决定是否通过验证1、C-->S客户端发给代理服务器的第一包,发起NTLM验证CONNECT life-online.com.cn:443 HTTP/1.1/r/nHost: life-online.com.cn:443/r/nProxy-Authorization: NTLM TlRMTVNTUAABAAAAA7IAAAcABwAoAAAACAAIACAAAABsaW54aWFuZ2ppbGxpb24=/r/n/r/nlife-online.com.cn:443 是目标地址和端口;具体语法参考http协议TlRMTVNTUAABAAAAA7IAAAcABwAoAAAACAAIACAAAABsaW54aWFuZ2ppbGxpb24=是经过base64编码的信息,我们的主要讨论对象结构如下:struct NtlmType1{ unsigned char protocol[8]; // 协议头,一定是”NTLMSSP/0“ int iType; // 0x01,标识为与代理服务器的第一次交互 type1 int iFlags; // 0xb203,很多资料都用这个;不过似乎没一定意义;抓包里qq和ie的都不同 short sDomLen; // 帐户域名长度 short sDupDomLen; // 帐户域名长度 int iDomOff; // 帐户域名偏移量 short sHostLen; // 帐户主机名长度 short sDupHostLen; // 帐户主机名长度 int iHostOff; // 帐户主机名偏移量
//ULONGLONG ullUnknown; // 8byte不知用途的数据;ie和qq抓包都发现有,不包含也没问题可以忽略 char* cpHost; //帐户主机名,不包含'/0' char* cpDomain; //帐户域名,不包含'/0'}2、S-->C代理服务器收到Type1数据后,返回的响应以下为截取出来对NTLM验证有意义的部分,具体如何解析请参考http协议HTTP/1.1 407 Proxy Authentication Required ( * )/r/nProxy-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAADgAAAABggACl7jkRBKFtVIAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=/r/nConnection: Keep-Alive/r/nProxy-Connection: Keep-Alive/r/nbase64后的响应数据TlRMTVNTUAACAAAAAAAAADgAAAABggACl7jkRBKFtVIAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=
结构如下:typedef struct NTLMType2 //response pack from proxy server{ unsigned char baProtocol[8]; // 协议头,一定是”NTLMSSP/0“ int iType; // 0x02,标识为与代理服务器的第二次交互 type2
//返回包里的域名信息,可以忽略,注意的是,域名是以unicode形式存放的 short sDomLen; // 帐户域名长度 short sDupDomLen; // 帐户域名长度 int iDomOff; // 帐户域名偏移量
int iFlags; // 用途未知
unsigned char baNonce[8]; // 挑战码,代理服务器随机生成,需要客户端加密回送 byte zero[8]; //8byte 0 //后面还有些信息,有些是没用,有些是不明白干啥用的}3、C-->S最重要的部分到了,根据挑战码,生成2个24byte的响应数据用于代理服务器进行验证CONNECT life-online.com.cn:443 HTTP/1.1/r/nHost: life-online.com.cn:443/r/nProxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGIAAAAYABgAegAAAA4ADgBAAAAABAAEAE4AAAAQABAAUgAAAAAAAACSAAAAAYIAAGoAaQBsAGwAaQBvAG4AbAB4AGwAaQBuAHgAaQBhAG4AZwCT+c2dmc2TfrM+rqO9RgVfQM6qkOFCdzrX1oPf8oSCzV6KWGJ59fbIVUeydXh5/+o=/r/nbase64编码串TlRMTVNTUAADAAAAGAAYAGIAAAAYABgAegAAAA4ADgBAAAAABAAEAE4AAAAQABAAUgAAAAAAAACSAAAAAYIAAGoAaQBsAGwAaQBvAG4AbAB4AGwAaQBuAHgAaQBhAG4AZwCT+c2dmc2TfrM+rqO9RgVfQM6qkOFCdzrX1oPf8oSCzV6KWGJ59fbIVUeydXh5/+o=结构如下:typedef struct NTLMType3{ unsigned char baProtocol[8]; // 协议头,一定是”NTLMSSP/0“ int iType; // 0x03,标识为与代理服务器的第三次交互 type3 short sLmRespLen; // 加密的客户端散列长度,总是24字节(0x18) short sDupLmRespLen; // 加密的客户端散列长度,总是24字节(0x18) int iLmRespOff; // 加密的客户端散列偏移量 short sNtRespLen; // 加密的NT散列长度,总是24字节(0x18) short sDupNtRespLen; // 加密的NT散列长度,总是24字节(0x18) int iNtRespOff; // 加密的NT散列偏移量 short sDomLen; // 帐户域名长度 short sDupDomLen; // 帐户域名长度 int iDomOff; // 帐户域名偏移量 short sUserLen; // 帐户用户名长度 short sDupUserLen; // 帐户用户名长度 int iUserOff; // 帐户用户名偏移量 short sHostLen; // 帐户主机名长度 short sDupHostLen; // 帐户主机名长度 int iHostOff; // 帐户主机名偏移量 //rc4 散列,目前未作为验证需要 short sRc4Len; // rc4编码长度 short sDupRc4Len; // rc4编码长度 int iRc4Off; // rc4编码偏移量 int iFlags; // 0x8201,很多资料都用这个;不过似乎没一定意义;抓包里qq和ie的都不同
//ULONGLONG ullUnknown; // 8byte不知用途的数据;ie和qq抓包都发现有,不包含也没问题,可以忽略 byte dom[]; // 帐户域名,unicode编码,不包含'/0' byte user[]; // 帐户用户名,unicode编码,不包含'/0' byte host[]; // 帐户主机名,unicode编码,不包含'/0' byte lm_resp[]; // 加密的客户端散列 byte nt_resp[]; // 加密的NT散列}挑战码使用说明1、客户端把域帐户密码填充为14byte,不足补02、把这14byte数据看作2个56bit的des密钥3、用这2个密钥对一个8byte的数据(0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 )分别加密,得到16byte数据,看作一个散列码注:这8字节怎么得出来的我也不知道,似乎应该是随机生成出来的,以后有空试验下4、把域帐户密码进行unicode和md4处理,也生成一个16byte的散列码5、2个散列码都充0补足21byte作为3个des密钥,对挑战码进行加密,得到2个24byte的最终响应数据
4、S-->CHTTP/1.1 200 Connection established返回码200表示成功其他返回码含义,参考http协议
参考内容:http://www.innovation.ch/personal/ronald/ntlm.html#hasheshttp://www.faqs.org/rfcs/rfc2616.htmlhttp://samba.kn.vutbr.cz/samba/docs/man/Samba-Developers-Guide/pwencrypt.htmlhttp://www.xfocus.net/releases/200305/a541.htmlhttp://muffin.doit.org/docs/rfc/tunneling_ssl.htmlhttp://www.openssl.org/