- 论坛徽章:
- 0
|
研究下Windows下的认证程序下的客户端,原来是在标准802.1x的数据包后加入了以下数据:
/////////////////////////////////////////////////////////////////////////////////////
static byte RuijieExtra[144] = { //Ruijie OEM Extra by soar @ [url]http://bbs.53ucity.com/
////////////////////////////////////////////////////////////////////////////
//
// OEM Extra
// 0 --> 22
0x00,0x00,0x13,0x11, // Encode( 0x00,0x00,0x13,0x11 ) Ruijie OEM Mark
0x01, // Encode( 0x01/00 )
0x00,0x00,0x00,0x00, // Encode( IP )
0x00,0x00,0x00,0x00, // Encode( SubNetMask )
0x00,0x00,0x00,0x00, // Encode( NetGate )
0x00,0x00,0x00,0x00, // Encode( DNS )
0x00,0x00, // Checksum( )
// 23 --> 58
0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2E,0x65,0x78,0x65,0x00,0x00,0x00, // ASCII 8021x.exe
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
0x00,0x00,0x00,0x00,
// 59 --> 77
0x02,0x32,0x00,0x00, // 8021x.exe File Version (2.5.00)
0x00, // unknow flag
0x00,0x00,0x13,0x11,0x00,0x28,0x1A,0x28,0x00,0x00,0x13,0x11,0x17,0x22, // Const strings
// 78 --> 118
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,// 32bits spc. Random strings
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, // 32bits spc. Random strings
0x00,0x00,0x13,0x11,0x18,0x06,0x00,0x00,0x00, // Const strings
// 119
0x00, // DHCP and first time flag
// V2.56 (and upper?) added
// 120 -->
//0x1A,0x0E,0x00,0x00,0x13,0x11,0x2D,0x08, // Const strings
// 128 --> 141
//0x00,0x00,0x00,0x00,0x00,0x00, // True NIC MAC
//0x1A,0x08,0x00,0x00,0x13,0x11,0x2F,0x02 // Const strings
};
/////////////////////////////////////////////////////////////////////////////////////
其中 32 为的随机数在发送用户名和密码时为客户端的验证 MD5 Hash ,关于这 32 位数字的生成方法如下(VC++ MFC):
//
//
///////////////////////////////////////////////////////////////////
//
//
// Ruijie 8021x.exe 客户端验证及其完整性验证(版本 V2.45 /2.50 /2.56 )
//
// 有些变态用了 8 次 MD5 算法检校 0x00401000h --> 0x00421000h 程序段
// (每段长0x4000h),每分段前加入了服务器返回的 MD5 串,最后得到的
// 8组 MD5 Hash 再和服务器返回的 MD5 串做运算生成 0x90h 的表 TableC
// 再作一次 MD5 运算。
//
//////////////////////////////////////////////////////////////////
//
// 严正声明:
// 本算法仅供学习和研究 8021x 认证客户端程序之用,
// 严禁他用,其他用途产生的后果本人一概不以负责 !
//
// -- by soar @ 2006/07/01
// [url]http://bbs.53ucity.com/
//////////////////////////////////////////////////////////////////
//
//
//产生特殊随机字符串
CString CMentoSupplicantDlg::Randstr(bool flag)
{
CString strFormat,strRandom;
int a,b,c,d,e;
unsigned t;
strFormat="%X%X%X%X%X%X9884773d9f46acafd7839eb38789088ac9534";
if (flag){strFormat="%X%X%X%X%X%X388498639f49ebaca773dfd78789088ac9534";}
t=time(NULL);
srand(t);
a=rand();
b=rand();
c=rand();
d=rand();
e=rand();
strRandom.Format(strFormat,a,b,c,d,e,t);
return strRandom;
}
//验证算法
void CMentoSupplicantDlg::Clog()
{
int i,j=0;
int nLength = 0; //number of bytes read from the file
int nBufferSize=0x4000; //checksum the file in blocks of bytes
CFileVersionInfo fvi;
CString strRJVersionInfo;
if (fvi.Create(strRJFileN)){
bool notfindflag=true;
strRJVersionInfo=fvi.GetFileVersion();
strRJVersionInfo.Replace(" ","");
if (strRJVersionInfo.Find("2,45,0,0")==0){
nBufferSize=0x3E00;
notfindflag=false;
//PrintOutput("V2,45,0,0");
}
if (strRJVersionInfo.Find("2,50,0,0")==0){
nBufferSize=0x4000;
notfindflag=false;
//PrintOutput("2,50,0,0");
}
if (strRJVersionInfo.Find("2,51,0,0")==0){
nBufferSize=0x4200;
notfindflag=false;
//PrintOutput("2,51,0,0");
}
if (strRJVersionInfo.Find("2,56,0,0")==0){
nBufferSize=0x4A00;
notfindflag=false;
//PrintOutput("2,56,0,0");
}
if (notfindflag){
PrintOutput(" ** 不支持的Ruijie客户端版本!。");
}
}
//
BYTE Buffer1[0x5000]; //buffer for data read from the file
BYTE Buffer2[0x5000]; //buffer for data to MD5 Checksum
BYTE md5rev[16]; //buffer for receive MD5 from the Server
BYTE *md5Dig1,*md5Dig2;
ULONGLONG lActual;
static byte TableC[0x90]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// Authentication Server MD5 Hash
for (i=0;i<16;i++)
md5rev=bMD5Source[24+i];
// Tranform to TableC
TableC[0]=md5rev[0];
for (i=1;i<8;i++){
TableC[i*18-1]=md5rev[i*2-1];
TableC[i*18]=md5rev[i*2];}
TableC[143]=md5rev[15];
// Check 8021x.exe, Exist ?
if (CFile::GetStatus(strRJFileN,FileStatus)==FALSE){
//PrintOutput(" >> 无法找到“8021x.exe”!!!");
//PrintOutput(" 请复制到本程序目录下,");
//PrintOutput(" 否则无法生成Ruijie客户端信息。");
//return a 32 bits Random string
strMD5Hash=Randstr(false);
return;
}
// Open the 8021.exe for reading.
CFile File(strRJFileN, CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary);
try
{
//checksum the file in blocks of xxxx bytes
lActual=File.Seek (0x1000,CFile::begin);
while ((nLength = File.Read( Buffer1, nBufferSize )) > 0 && j<8)
{
for (i=0;i<16;i++){
Buffer2=md5rev;}
for (i=0;i<nBufferSize;i++){
Buffer2[i+16]=Buffer1;}
//Return each block MD5 Hash
md5Dig1=ComputeHash(Buffer2,nBufferSize+16);
for (i=0;i<16;i++){
TableC[18*j+i+1]=md5Dig1;}
j++;
}//end of while
// PrintOutput( "MD5_1to8_Done!");
md5Check=ComputeHash(TableC,144);
//not the best work....
CString strTemp,strFormat;
strMD5Hash="";
for (i=0;i<16;i++){
if (md5Check) {//if outside
if (md5Check>0x0f){
strFormat="%x";}
else{
strFormat="0%x";}
strTemp.Format(strFormat,md5Check);
strMD5Hash=strMD5Hash+strTemp;}
else{//if outside
strMD5Hash=strMD5Hash+"00";}//end of if outside
}//end of for
PrintOutput(" >> Ruijie “8021x.exe” 验证 MD5: ");
PrintOutput(" "+strMD5Hash);
return;
}//end of try
//catche Exception error for debug only
catch (CFileException* e )
{
#ifdef _DEBUG
afxDump << "File could not be opened " << e->m_cause << "\n";
#endif
throw e;
}//end of catch
}//end of fuction
//
//
/////////////////////////////////////////////////////////////////////////
//
//
Windows 下的客户端已经成功通过认证服务器的完整性检查和 Ruijie 发送的数据一致^_^ |
|