想到一个猥琐的方法,对付简单的运营商广告脚本,让它插入到错误的地方~
<!doctype html>
<!--
<html>
<head></head>
<body></body>
</html>
-->
<html>
<head></head>
<body>
Hello World
</body>
</html>
当然,这种方案只适用于插一次的情况,例如 nginx 设置了
sub_filter_once on
。如果给所有的<head>
都插入那就没办法了。
看之前的 PPT 时翻到一个有趣的 Demo
https://www.etherdream.com/webdraw/demo/bin/
刚研究 HaXe 时突发奇想,用一种语言,同时生成 HTML5 和 Flash 两个版本。这样就不用考虑低版本浏览器的兼容性问题了。
关于使用 haXe 做小游戏的优势,在这个 PPT中有讲解。
Cloud9 试用版都那么强大!
有趣的 emoji 效果:
var i = 0
var arr = ['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘']
setInterval(function() {
location.hash = arr[i++ % arr.length]
}, 50);
如果地址栏里不想有 #
,可换成:
setInterval(function() {
history.replaceState('', '', '/' + arr[i++ % arr.length])
}, 50);
无意中发现 nginx 有个 gunzip
的指令,终于解决了无法在 gzip 网页中使用 sub_filter
的问题。
之前研究中间人攻击时,为了能在 HTML 中插入脚本,代理过程中还得让把请求头 Accept-Encoding
去掉,让服务器不返回压缩格式,才能顺利执行 sub_filter
。但这样又会浪费网络流量,很是纠结。
现在有了 gunzip
,只需在 nginx 内部再套一次代理,即可注入 JS 到压缩后的页面里了~
# nginx.conf
events {
worker_connections 1024;
}
http {
resolver 8.8.8.8;
server {
listen 8080;
gzip on;
location / {
proxy_set_header host $http_host;
proxy_pass http://unix:/tmp/mitm.sock;
sub_filter <head '<script>console.warn("inject!!!")</script><head';
sub_filter_once on;
}
}
server {
listen unix:/tmp/mitm.sock;
gunzip on;
location / {
proxy_set_header Accept-Encoding gzip;
proxy_pass http://$http_host;
}
}
}
之前有人为了隐蔽执行加密后的 JS,尝试用 (function(){}).constructor
取代 Function
,例如:
(function(){}).constructor('alert(1)')()
当时以为这种方案没法监控。不过后来想到了破解方案,只需先执行:
Function.prototype.__defineGetter__('constructor', function() {
return function() {
console.log(arguments)
return Function.apply(this, arguments)
}
})
这样就可以 hook 读取任何函数的 constructor
属性,然后返回一个包装过的 Function
函数,用于跟踪之后执行时传入的参数~
思考题:获取闭包内的变量。
// 目标:获取闭包内容的 token 变量,提交给 check 校验
// 备注:
// 执行环境需联网,总用时不超过 10s
// 兼容现代浏览器即可,自己弹 alert('win') 不算~
(function() {
var token = '$' + Math.random()
new Image().src = 'https://www.baidu.com/s?wd=' + token
window.check = function(v) {
if (v === token) {
alert('win') // 通过
}
}
})()
// 你的代码写在此处...
点击查看答案
// 目标:获取闭包内容的 token 变量,提交给 check 校验
// 备注:
// 执行环境需联网,总用时不超过 10s
// 兼容现代浏览器即可,自己弹 alert('win') 不算~
(function() {
var token = '$' + Math.random()
new Image().src = 'https://www.baidu.com/s?wd=' + token
window.check = function(v) {
if (v === token) {
alert('win') // 通过
}
}
})()
// 你的代码写在此处...
setTimeout(function() {
performance.getEntries().forEach(function(item) {
var r = item.name.split('$0.')
if (r.length > 1) {
var key = '$0.' + r[1]
check(key)
}
})
}, 3000)
Chrome 终于支持 DOM 原型上的 getter / setter。过去写的《前端防火墙 -- 可疑模块拦截》 可以大幅精简了。
之前写《XSS 前端防火墙 —— 内联事件拦截》时,漏一个原理图,现补上:
HTML5 Service Workers 可以接管浏览器网络请求,本以为 MITM 攻击又有新玩法了,结果这货只能在 HTTPS 下开启。。。
查了下原来人家早就考虑到了~
FireFox 居然会检测「扩展名」和「MIME」是否匹配,就这点比其他浏览器有进步~
而 Chrome 仍然可以玩扩展名的小把戏,例如扩展名是 GIF 的 URL 也可以运行 JS:
https://www.etherdream.com/upload/20150603.gif
设置了 X-Frame-Options
的页面怎么玩反射型 XSS?
如果当前存在来源页的话,跳转 opener.location
就可以(并且这个属性无视同源策略~)
TypeScript 编译器居然是用 TypeScript 实现的,最终编译成 JS 跑在 NodeJS 里。。。
虽说语言自举一直都是惯例,但毕竟 JS 效率很低,导致 TS 编译很慢,半天电脑就滚烫了~
恶作剧 XSS:
for (i = 0; i < 4; i++) {
document.cookie = i + '=' + 'X'.repeat(3000)
}
想到一个测试用户是否上过某网站的方法:加载该网站 logo,瞬间完成说明有缓存,之前访问过;反之亦然~
不禁用第三方 cookie 实在太危险了~ 一大波应用被坑死
非 80 端口的 IP 也能河蟹。。。
未来 webapp 头部会不会加上这句~~
<!--[if IE]>
This program cannot be run in IE Mode.
<![endif]-->
静态资源存 localStorage 就是水坑漏洞的前兆,风险远远大于优化。
可以用 CSP 监控 HTTPS 中的 HTTP 资源,只允许 https://*
即可找出全站 HTTPS 升级中的遗漏点~
或者用之前提到的 onload/onerror 监控资源加载:
https://www.cnblogs.com/index-html/p/use-onload-event-trace-http-hijack.html
相比 CSP,这种方案上报的信息更详细,方便排查。
bj.cn
居然和 com.cn
一样,都是顶级域名~
查了下 TLD 的官方列表:https://publicsuffix.org/list/effective_tld_names.dat
居然有这么多,而且还有这么长的顶级域名:higashimatsuyama.saitama.jp
JS 页面截屏的效果~
原理很简单,JS 采集整个 DOM 树,以及鼠标位置、滚动条坐标等等,编码压缩后发给后端。
后端根据这些信息,在相同的浏览器内核中渲染出用户当前看到的网页模样。
同时,根据 User-Agent 大致模仿浏览器的外观~
不过目前只能静态截图,之后再改进成动态录屏的效果~ 虽然连续不断的截图也可以当做动画,但效率太低。目前在考虑使用一些 diff 算法,只需很小的开销就可以实现高 fps 录屏。
十年前的手绘黑魔法。。。如果还能找到,之后继续分享~