浅谈javascript函数劫持[转自xfocus]第2/3页
更新时间:2008年02月18日 22:03:26 作者:
javascript函数劫持,也就是老外提到的javascript hijacking技术。最早还是和剑心同学讨论问题时偶然看到的一段代码
三、反劫持
谈到劫持也就必然要谈谈反劫持的话题,假设你要写一个健壮的xss playload,就需要考虑反劫持,有两个问题要解决:
如何判断是否被劫持了?
如果发现被劫持了,如何反劫持?
1. 判断某个函数是否被劫持,这个好办,写个小程序对比一下一个函数被hook前后,有什么差别:
复制代码 代码如下:
<textarea id="tb1" cols="80" rows="8"></textarea>
<script type="text/javascript">
<!--
document.getElementById("tb1").value = eval + "\n";
var _eval = eval;
eval = function(s) {
alert(s);
_eval(s);
}
document.getElementById("tb1").value += eval;
//-->
</script>
结果:
function eval() {
[native code]
}
function(s) {
alert(s);
_eval(s);
}
我们发现那些内置函数是[native code],而自定义的则是具体的函数定义,用这个特征就可以简单的检测函数是否被劫持:
function checkHook(proc) {
if (proc.toString().indexOf("[native code]") > 0) {
return false;
} else {
return true;
}
}
2. 如何反劫持,第一个想法就是恢复被劫持的函数,如果劫持的人把原函数保存在某个变量里那还好办,直接调用原函数就可以了,但是劫持者自己也没保存副本怎么办,只能自己创建个新的环境,然后用新环境里的干净的函数来恢复我们这里被hook了的,怎么创建新环境?整个新的iframe好了,里面就是个全新的环境。ok,动手吧:
复制代码 代码如下:
function unHook(proc) {
var f = document.createElement("iframe");
f.style.border = "0";
f.style.width = "0";
f.style.height = "0";
document.body.appendChild(f);
var d = f.contentWindow.document;
d.write("<script type=\"text/javascript\">window.parent.escape = escape;<\/script>");
d.close();
}
综合1、2节,整个测试代码如下:
<!--antihook.htm-->
复制代码 代码如下:
<script type="text/javascript">
<!--
escape = function(s) {
return s;
}
//-->
</script>
<html>
<body>
<input type="button" onclick="javascript: test();" value="test" />
<script type="text/javascript">
<!--
function test() {
alert(escape("s y"));
if (checkHook(escape)) {
unHook(escape);
}
alert(escape("s y"));
}
function checkHook(proc) {
if (proc.toString().indexOf("[native code]") > 0) {
return false;
} else {
return true;
}
}
function unHook(proc) {
var f = document.createElement("iframe");
f.style.border = "0";
f.style.width = "0";
f.style.height = "0";
document.body.appendChild(f);
var d = f.contentWindow.document;
d.write("<script type=\"text/javascript\">window.parent.escape = escape;<\/script>");
d.close();
}
//-->
</script>
</body>
</html>
3. 不是上面两个问题都解决了么,为什么要有第3节?因为那不是个最好的解决办法,既然我们可以创建全新的iframe,何不把代码直接放到全新iframe里执行呢,这样做的话绿色环保,既不用考虑当前context里的hook问题,也不用改动当前context,不会影响本身的程序执行。给出两个比较通用点的函数:
复制代码 代码如下:
function createIframe(w) {
var d = w.document;
var newIframe = d.createElement("iframe");
newIframe.style.width = 0;
newIframe.style.height = 0;
d.body.appendChild(newIframe);
newIframe.contentWindow.document.write("<html><body></body></html>");
return newIframe;
}
function injectScriptIntoIframe(f, proc) {
var d = f.contentWindow.document;
var s = "<script>\n(" + proc.toString() + ")();\n</script>";
d.write(s);
}
把你的payload封装进一个函数,然后调用这两个方法来在iframe里执行:
function payload() {
// your code goes here
}
var f = createIframe(top);
injectScriptIntoIframe(f, payload);
四、最后
由于国内很少有见文章提及这个东西,所以才草成这篇,希望能够抛砖引玉。由于本人水平有限,难免有错误或者疏漏之处请谅解,没有说清楚的地方,欢迎和我交流。
还有就是一些不得不感谢的人,感谢剑心一直以来毫无保留的交流,感谢黑锅多次鼓励我把自己的心得体会写成文字,感谢幻影所有的朋友们、B.C.T的朋友们以及群里那帮经常一起扯淡的朋友们。
广告一下,没法幻影blog的朋友,可以添加hosts来突破:
72.14.219.190 pstgroup.blogspot.com
相关文章
JavaScript判断textarea值是否为空并给出相应提示
假如用户没有输入数据则给出相应提示,那么该如何来判断呢?下面以判断textarea值是否为空为例2014-09-09
如何让一个层关闭之后,就算刷新页面了也不显示。除非关闭页面再次打开
这个功能,一般可用于广告的显示,当关闭后,就不显示,除非重新关闭打开,增加用户体验2008-09-09
webpack使用 babel-loader 转换 ES6代码示例
本篇文章主要介绍了webpack使用 babel-loader 转换 ES6代码 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。2017-08-08


最新评论