首页 > QQ技巧 > 2014最新WebQQ密码的加密方式分析过程

2014最新WebQQ密码的加密方式分析过程

时间:2014-09-02 14:45 作者:QQ地带 我要评论

本文作者:等TA回来  来自:WooYun知识库
 
授人以鱼,不如授人以渔,今天就分享一个 分析qq加密的过程。
 
工具:谷歌浏览器自带的的调试工具(在浏览器中按F12呼出)
 
以下是全过程,历时4个的小时。
 
提交的时候调用 onFormSubmit
 
  1. function onFormSubmit(form) 
  2.         if (form.remember_uin.checked){ 
  3.                 return ptui_onLoginEx(form, "qq.com") 
  4.         }else{                                 
  5.                 var myDate=new Date(); 
  6.                 myDate.setFullYear(1971,1,1); 
  7.                 pt.cookie.set("ptui_loginuin",  "", myDate, '/', 'ui.ptlogin2.qq.com'); 
  8.                 return ptui_onLogin(form); 
  9.         } 
 
如果用户没有勾选保存密码调用 ptui_onLogin
 
  1. function ptui_onLogin(A) { 
  2.     try { 
  3.         if (parent.ptlogin2_onLogin) { 
  4.             if (!parent.ptlogin2_onLogin()) { 
  5.                 return false 
  6.             } 
  7.         } 
  8.         if (parent.ptlogin2_onLoginEx) { 
  9.             var D = A.u.value; 
  10.             var B = A.verifycode.value; 
  11.             if (str_uintip == D) { 
  12.                 D = "" 
  13.             } 
  14.             if (!parent.ptlogin2_onLoginEx(D, B)) { 
  15.                 return false 
  16.             } 
  17.         } 
  18.     } catch(C) {} 
  19.     return ptui_checkValidate(A) 
 
接下来调用 ptui_checkValidate(A)
 
  1. function ptui_checkValidate(B) { 
  2.     var A = B.u;                                        //此处获取用户名 
  3.     var D = B.p;                                        //此处获取密码 
  4.     var E = B.verifycode;                        //此处获取验证码 
  5.     if (A.value == "" || str_uintip == A.value) { 
  6.         pt.show_err(str_no_uin); 
  7.         A.focus(); 
  8.         return false 
  9.     } 
  10.     AA.value = A.value.trim(); 
  11.     if (!pt.chkUin(A.value)) { 
  12.         pt.show_err(str_inv_uin); 
  13.         A.focus(); 
  14.         A.select(); 
  15.         return false 
  16.     } 
  17.     if (D.value == "") { 
  18.         pt.show_err(str_no_pwd); 
  19.         D.focus(); 
  20.         return false 
  21.     } 
  22.     if (E.value == "") { 
  23.         if (!isLoadVC) { 
  24.             loadVC(true); 
  25.             g_submitting = true
  26.             return false 
  27.         } 
  28.         pt.show_err(str_no_vcode); 
  29.         try { 
  30.             E.focus() 
  31.         } catch(C) {} 
  32.         if (!g_loadcheck) { 
  33.             ptui_reportAttr(78028) 
  34.         } else { 
  35.             ptui_reportAttr(78029) 
  36.         } 
  37.         return false 
  38.     } 
  39.     if (E.value.length < 4) { 
  40.         pt.show_err(str_inv_vcode); 
  41.         E.focus(); 
  42.         E.select(); 
  43.         return false 
  44.     } 
  45.     if (isLoadVC && !(/^[a-zA-Z0-9]+$/.test(E.value))) { 
  46.         pt.show_err(str_correct_vcode); 
  47.         E.focus(); 
  48.         E.select(); 
  49.         return false 
  50.     } 
  51.     D.setAttribute("maxlength", "32"); 
  52.     ajax_Submit(); 
  53.     ptui_reportNum(g_changeNum); 
  54.     g_changeNum = 0
  55.     return true 
 
然后:
 
  1. function ajax_Submit() { 
  2.     if (pt.checkRet == -1 || pt.checkRet == 3) { 
  3.         pt.show_err(pt.checkErr[window.g_lang]); 
  4.         try { 
  5.             $("p").focus() 
  6.         } catch(B) {} 
  7.         return 
  8.     } 
  9.     var A = getSubmitUrl("login"); 
  10.     pt.winName.set("login_param", encodeURIComponent(login_param)); 
  11.     pt.loadScript(A); 
  12.     return 
最后在这个函数中加密组装提交地址:
 
 
  1. function getSubmitUrl(K) { 
  2.     var E = true
  3.     var C = document.forms[0]; 
  4.     var A = (pt.isHttps ? "https://ssl.": "http://") + "ptlogin2." + g_domain + "/" + K + "?"; 
  5.     var B = document.getElementById("login2qq"); 
  6.     if (pt.regmaster == 2) { 
  7.         A = "http://ptlogin2.function.qq.com/" + K + "?regmaster=2&" 
  8.     } else { 
  9.         if (pt.regmaster == 3) { 
  10.             A = "http://ptlogin2.crm2.qq.com/" + K + "?regmaster=3&" 
  11.         } 
  12.     } 
  13.     for (var J = 0; J < C.length; J++) { 
  14.         if (K == "ptqrlogin" && (C[J].name == "u" || C[J].name  
  15. == "p" || C[J].name == "verifycode" || C[J].name == "h")) { 
  16.             continue 
  17.         } 
  18.         if (C[J].name == "ipFlag" && !C[J].checked) { 
  19.             A += C[J].name + "=-1&"; 
  20.             continue 
  21.         } 
  22.         if (C[J].name == "fp" || C[J].type == "submit") { 
  23.             continue 
  24.         } 
  25.         if (C[J].name == "ptredirect") { 
  26.             g_ptredirect = C[J].value 
  27.         } 
  28.         if (C[J].name == "low_login_enable" && (!C[J].checked)) { 
  29.             E = false
  30.             continue 
  31.         } 
  32.         if (C[J].name == "low_login_hour" && (!E)) { 
  33.             continue 
  34.         } 
  35.         if (C[J].name == "webqq_type" && !B && (!C[J].checked)) { 
  36.             continue 
  37.         } 
  38.         A += C[J].name; 
  39.         A += "="; 
  40.         if (C[J].name == "u" && pt.needAt) { 
  41.             A += pt.needAt + "&"; 
  42.             continue 
  43.         } //www.oicqzone.com
  44.         if (C[J].name == "p") { 
  45.             var M = C.p.value; 
  46.             var I = hexchar2bin(md5(M)); 
  47.             var H = md5(I + pt.uin); 
  48.             var G = md5(H + C.verifycode.value.toUpperCase()); 
  49.             A += G 
  50.         } else { 
  51.             if (C[J].name == "u1" || C[J].name == "ep") { 
  52.                 var D = C[J].value; 
  53.                 var L = ""
  54.                 if (g_appid == "1003903" && B) { 
  55.                     L = /\?/g.test(D) ? "&": "?"; 
  56.                     var F = document.getElementById("webqq_type").value; 
  57.                     L += "login2qq=" + B.value + "&webqq_type=" + F 
  58.                 } 
  59.                 A += encodeURIComponent(D + L) 
  60.             } else { 
  61.                 A += C[J].value 
  62.             } 
  63.         } 
  64.         A += "&" 
  65.     } 
  66.     A += "fp=loginerroralert&action=" + pt.action.join("-") + "-" +  
  67. (new Date() - g_begTime) + "&mibao_css=" + pt.mibao_css + "&t=" + 
  68.  pt.submitN[pt.uin] + "&g=1"; 
  69.     A += "&js_type=" + pt.js_type + "&js_ver=" + window.g_pt_version + "&login_sig=" + window.g_login_sig; 
  70.     return A 
核心的加密代码如下:
 
 
  1. if (C[J].name == "p") { 
  2.             var M = C.p.value; 
  3.             var I = hexchar2bin(md5(M)); 
  4.             var H = md5(I + pt.uin);        //pt.uin  估计是用户qq号的16进制表示  
  5.             var G = md5(H + C.verifycode.value.toUpperCase()); 
  6.             A += G 
  7.   
  8. var M = "××××××";var ver="!";var I = hexchar2bin(md5(M));var H = md5(I + pt.uin);var G = md5(H + ver.toUpperCase()); 
 
hexchar2bin算法如下:
 
  1. function hexchar2bin(str) { 
  2.     var arr = []; 
  3.     for (var i = 0; i < str.lengthii = i + 2) { 
  4.         arr.push("\\x" + str.substr(i, 2)) 
  5.     } 
  6.     arrarr = arr.join(""); 
  7.     eval("var temp = '" + arr + "'"); 
  8.     return temp 
 
最终加密过程如下:
 
  1. md5(md5(hexchar2bin(md5(pwd))+uin)+verifycode.toUpperCase()) 
  2.   
  3.  
  4. #!js 
  5. md5(md5(hexchar2bin(md5("××××××××"))+'\x00\x00\x00\x00\x01\xd3\xff\xf3')+"!EHZ") 
  6. "918AAFDF8C9481F7AC2FC1C89A4DED7B" 
此处改变了 pt.uin:
 
  1. function ptui_checkVC(A, C, B) { 
  2.     clearTimeout(checkClock); 
  3.     pt.checkRet = A
  4.     pt.uin = B
  5.     if (A == "2") { 
  6.         g_uin = "0"
  7.         pt.show_err(str_inv_uin) 
  8.     } 
  9.     if (!pt.submitN[B]) { 
  10.         pt.submitN[B] = 1 
  11.     } 
  12.     var E = new Date(); 
  13.     g_time.time7 = E
  14.     var D = { 
  15.         "12": g_time.time7 - g_time.time6 
  16.     }; 
  17.     if (!curXui) { 
  18.         ptui_speedReport(D) 
  19.     } 
  20.     g_loadcheck = false
  21.     switch (A + "") { 
  22.     case "0": 
  23.     case "2": 
  24.     case "3": 
  25.         $("verifycode").value = C || "abcd"; 
  26.         loadVC(false); 
  27.         break; 
  28.     case "1": 
  29.         $("verifycode").value = pt.needCodeTip ? str_codetip: ""; 
  30.         loadVC(true); 
  31.         break; 
  32.     default: 
  33.         break 
  34.     } 
其实找出这个算法花的时间很少,只是一直找不到 ptui_checkVC 调用的地方,后来恍然大悟,在验证qq是否需要图片验证码的时候返回的就是给js调用的,地址是:
 
  1. https://ssl.ptlogin2.qq.com/chec ... 5Q4YxDJ8Rza4-1ubGMR*aruR6Byct1dQ&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.5011255156714469 
返回内容如下:
 
  1. ptui_checkVC('0','!BGC','\x00\x00\x00\x00\x01\xd3\xff\xf3');  
 
第三个参数就是 16进制表示的qq号码
 
至此全搞定,剩下的就是编程实现。https方式访问。可以试试 libcurl   或者自己 用openssl+socket也可以

标签: webQQ
顶一下
(1)
100%
踩一下
(0)
0%

Google提供的广告