您的位置:首页 > 理论基础 > 计算机网络

web前端利用HSTS(新的Web安全协议HTTP Strict Transport Security)漏洞的超级Cookie(HSTS Super Cookie)

2015-04-13 20:12 806 查看
web前端如果想实现cookie跨站点,跨浏览器,清除浏览器cookie该cookie也不会被删除这似乎有点难,下面的教程让你完全摆脱document.cookie1、服务器端设置HSTS如PHP:<?php header("
Strict-Transport-Security: max-age=31536000; includeSubDomains
");?>
includeSubDomains必不可少,因为Super Cookie要用到很多子域名(Super Cookie必备条件,最好32个)。

demo用到的子域名:*-hsts-lab.radicalresearch.co.uk       如 1-
hsts-lab.radicalresearch.co.uk
,2-[/code]
hsts-lab.radicalresearch.co.uk
等,demo用到32个子域名 到32[/code]
-
hsts-lab.radicalresearch.co.uk
,为什么用到这么多子域名,下面会谈到。
<?php   //根据请求输出不同header   //header("Strict-Transport-Security: max-age=31536000; includeSubDomains")或者header("Strict-Transport-Security: max-age=0; includeSubDomains")
//下面这个1是必须输出的值,cb回调函数里会用到
echo 1;
?>
2、开
启或关闭HSTS
子域名设置HSTS 状态头:

https://13-hsts-lab.radicalresearch.co.uk/hsts/set/1

在浏览器里打开上面URL,如下图:


上面会有个Strict-Transport-Security的头,max-age=31436000 注意此时max-age不为0,表示HSTS开启了

再打开
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0
[/code]
此时max-age=0,HSTS失效被关闭了
这个
13-hsts-lab.radicalresearch.co.uk
子域名服务器返回的不同HSTS开启状态是根据url中
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0
标红的0/1进行输出不同的状态头的: 0关1开服务器根据url判断HSTS输出哪种Strict-Transport-Security头如HSTS开启:
<?php header("
Strict-Transport-Security: max-age=31536000; includeSubDomains
");?>
HSTS关闭:
<?php header("
Strict-Transport-Security: max-age=0; includeSubDomains
");?>这里面还有个关键点是,开启和关闭HSTS必须要用
https协议,即在浏览器里打开的时候
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0,协议必须是https,这跟HSTS的特性有关。
下面会有解释。所有子域名(1-32)服务器端除了输出 header
Strict-Transport-Security是否开启外,还都输出1值
3、Super Cookie利用的关键点:
如果我们事先设置了第13个子域名的HSTS的状态开启了,并且在当前浏览器访问过该子域名、或者脚本动态加载过,如浏览器访问过
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/1 http:// href="http://13-hsts-lab.radicalresearch.co.uk/hsts/get" target=_blank>13-hsts-lab.radicalresearch.co.uk/hsts/get
我们会发现http会自动被浏览器重定向到 https:
//13-hsts-lab.radicalresearch.co.uk/hsts/get
这里特别关键,如果这理解不了,那么HSTS Super Cookie 就无法理解了。相反如果
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0 你设置
HSTS关闭,你再通过http打开该子域名下的任何资源,是不会有任何https跳转的。我们再来访问下http://beta.tfxiq.com/sc.html,打开控制台下的network,会发现很多跳转丢失:这里跳转丢失的原因是因为该子域名下HSTS服务器端开启了,因为你之前用https访问过该域名,并且开启了HSTS,那么后续的所有访问都会被强制跳转到https; 跳转丢失的response也是没有任何返回的,代码就利用到了这一点。[b]4、实现原理:拿http://beta.tfxiq.com/sc.html[/b]为例,当前chrome客户端要保存一个71009647的 cookie值, 71009647的36进制为:169ze7(页面显示值),二进制00000100001110111000010101101111,前面4位黑的0是为了凑全32位。保存cookie:按照12进制值00000100001110111000010101101111从左到右的顺序,url最右边的/0或者/1按顺序对应12进制步骤1: 在
https://1-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤2: 在
https://2-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤3: 在
https://3-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤4: 在
https://4-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤5: 在
https://5-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤6: 在
https://6-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤7: 在
https://7-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤8: 在
https://8-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤9: 在
https://9-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤10: 在
https://10-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤11: 在
https://11-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤12: 在
https://12-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤13: 在
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤14: 在
https://14-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤15: 在
https://15-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤16: 在
https://16-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤17: 在
https://17-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤18: 在
https://18-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤19: 在
https://19-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤20: 在
https://20-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤21: 在
https://21-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤22: 在
https://22-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤23: 在
https://23-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤24: 在
https://24-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤25: 在
https://25-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤26: 在
https://26-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤27: 在
https://27-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤28: 在
https://28-hsts-lab.radicalresearch.co.uk/hsts/set/0
关闭当前子域名HSTS步骤29: 在
https://29-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤30: 在
https://30-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤31: 在
https://31-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS步骤32: 在
https://32-hsts-lab.radicalresearch.co.uk/hsts/set/1
开启当前子域名HSTS上面32个步骤,都是根据二进制00000100001110111000010101101111从左到右的顺序,设置了HSTS对应的开启状态,0:关,1:开保存cookie的 url必须协议是https,原因上面提过,再提一遍,因为开启了HSTS协议,并且通过https加载过该子域名下的任何资源,当再通过http访问任何资源,会发生页面跳转,跳转到https安全协议对应的url.当然代码在beta.tfxiq.com/superCookie.js中是通过循环动态在head中插入一个script 来模拟浏览器子域名开启和关闭HSTS的[b]读取cookie:[/b]步骤1: 在
http://1-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['1'](!1)
这个域名HSTS关闭,不跳转,response结果为上面php脚本输出的1,cb回调函数里的参数值取1的反值,相当于0,对应00000100001110111000010101101111的左边第一位0步骤2: 在
http://2-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['2'](!1)
上同 对应00000100001110111000010101101111的左边第二位0步骤3: 在
http://3-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['3'](
!1
) 上同 对应00000100001110111000010101101111的左边第三位0步骤4: 在
http://4-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['4'](
!1
) 上同 对应00000100001110111000010101101111的左边第四位0步骤5: 在
http://5-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['5'](
!null
) 上同 对应00000100001110111000010101101111的左边第五位0步骤6: 在
http://6-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['6'](!null)
这个域名HSTS开启,访问跳转到安全协议,response没有数据,cb回调函数里的参数的值为null ,js取反相当于1, 对应00000100001110111000010101101111的左边第六位1步骤7: 在
http://7-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['7'](
!
1) 这个域名HSTS关闭,不跳转,response结果为上面php脚本输出的1,cb回调函数里的参数值取1的反值,相当于0,对应00000100001110111000010101101111的左边第七位0....等等...步骤32: 在
http://32-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window['hsts']._['32'](!null)
这个域名HSTS开启,访问跳转,response没有数据,cb回调函数里的参数的值为null ,js取反相当于1, 对应00000100001110111000010101101111的右边第一位所有response值都是取反的最后 汇总response的 数据 等于二进制00000100001110111000010101101111上面32个步骤在superCookie.js中也是通过循环在head中加载script,我们会发现设置Cookie和读取Cookie返回的二进制是一致的,都是00000100001110111000010101101111,00000100001110111000010101101111再转换成71009647,71009647再转换成页面显示的36进制:169ze7使用32个站点的原因是相当于32位二进制,可以识别20亿个客户端。缺点:1、每次读取cookie都需要访问32次子域名,存取cookie的时候也要加载32次script,开销大、读取cookie速度慢2、作为一个安全漏洞,以后各大浏览器厂商估计会修复这个bug优点:跨站点、浏览器关闭或者清除cookie也删除不了该 HSTS super cookie上面的解释有点啰嗦,简洁的说是 利用HSTS的漏洞,32个子域名为数据库(每个子域名代表1或者0,组合起来就是一个unique值),进行数据的存入和读出。superCookie.js
 (function(n, t, i, r, u) {n[i] = n[i] || new function() {function y(n) {var t = (e.index++).toString(36);return e[t] = function() {return delete e[t], n.apply(null, arguments);}, "window['" + i + "']._['" + t + "']";}function p(t, i) {var u, r;if (n.push({i:t,b:i}), n.length >= f) {for (u = 0, r = 0; r < f; ++r) n[r].b && (u |= 1 << n[r].i);return u & 2147483647;}return !1;}function h(n, t, i) {var r = p(t, i);r !== !1 && n(r);}function c(t) {return n.push(!0) >= f ? (t(), !0) :!1;}function w(t) {n = [];for (var i = 0; i < f; i++) a(i, h.bind(this, t, i), h.bind(this, t, i, !1));}function b(t, i) {var u, r;for (n = [], u = t | -2147483648, r = 0; r < f; r++) {d(u >> r & 1, r, c.bind(this, i), c.bind(this, i));}}function k(n) {var t = f - 1;a(t, l.bind(this, n, t), l.bind(this, n, t, !1));}function l(n, t, i) {n(!!i);}function a(n, t, i) {var r = "http://" + n.toString(16) + o + s + "/hsts/get";v(r, t, i);}function d(n, t, i, r) {var u = "https://" + t.toString(16) + o + s + "/hsts/set/" + n;v(u, i, r);}function v(n, i, f) {i && (n += (n.indexOf("?") === -1 ? "?" :"&") + "cb=" + y(i));var e = t.createElement(r), o = t.getElementsByTagName(r)[0], s = o.getAttribute(u);e.setAttribute(u, s);e.onerror = f;e.async = 1;e.src = n;o.parentNode.insertBefore(e, o);}var o = "-hsts-lab.", s = "radicalresearch.co.uk", f = 32, n = [], e = {index:0};return {_:e,test:k,read:w,write:b};}();})(window, document, "hsts", "script", "nonce"),function(n, t, i) {function u(n) {for (var i = t.getElementById("hstsValue"); i.firstChild; ) i.removeChild(i.firstChild);i.appendChild(t.createTextNode(n));}function r(n) {for (var i = t.getElementById("hstsState"); i.firstChild; ) i.removeChild(i.firstChild);i.appendChild(t.createTextNode(n));}function f() {r("reading...");n[i].read(function(n) {r("Your tracking id was read.");u(n.toString(36));});}function e() {r("writing...");//var t = Math.floor(Math.random() * 2147483647);var t=71009647;n[i].write(t, function() {r("Your tracking id was set.");u(t.toString(36));});}n.location.protocol !== "http:" ? n.location.replace(n.location.href.replace(/^[^:]+:/, "http:")) :(r("checking..."),n[i].test(function(n) {n ? f() :e();}));}(window, document, "hsts");
demo页面 sc.html:
 <!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"></head><body><p class="hstsDemo"><span id="hstsState"></span><code id="hstsValue"></code></p></body><script type="text/javascript" src="superCookie.js"></script></html>
大家可以将代码拷贝下来运行下。此为原创,如果想转载请注明出处,thanks @author 刘明海
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐