网络优化

hook.js通用Javascript函数钩子

2019年09月12日 热度:271 ℃
最近看Dom Xss检测相关的Paper,涉及到Hook Javascript函数,网上翻了一下,貌似没有什么通用的函数钩子脚本,自己用就自己写一个吧。最后有代码地址,前面写下mind storm的过程。
最经典且简单的Javascript函数钩子的写法应该是下面这样了:

var _alert = alert;
window.alert = function(s) {
       console.log("Hooked!");
        _alert(s);
}

不过这种Hook方式跟闹着玩儿似的,用到实际生产上通用性不好,效率也不高。
国内比较早看到的介绍Javascript函数劫持的文章应该是安全焦点上luoluo写的《浅谈javascript函数劫持》,用Javascript函数钩子实现了一个简单的内联代码调试器。后来看到了大风在08年搞了一个anehta的攻击平台,其中有一段能够hook任意Javascript函数的代码,看了下感觉有一些问题。这里贴出部分代码,有兴趣可以到这里看完整版:

 

 hook: function(funcNameHooked, RealFuncAfterHooked, hookFunc){
                try {
                  setTimeout(function(){
                          //alert("hook before: "+window[funcNameHooked]);
                          // 保存原函数
                          window[RealFuncAfterHooked] = window[funcNameHooked];
                          //window[funcNameHooked] = window[hookFunc];
                          // 参数个数可以根据需要进行调整
                          window[funcNameHooked] = function (param1,param2,param3,param4,param5,param6,param7){
                                // 劫持参数
                                var newParam = new Array();
                                  // 先执行注入的函数; 需要返回被劫持后的参数,作为新参数传入原函数
                                  newParam = window[hookFunc](param1,param2, param3, param4, param5, param6, param7)
                                  //alert("newParam= "+newParam);
                                  // 再执行原函数
                                  window[RealFuncAfterHooked](newParam[0], newParam[1], newParam[2], newParam[3],
                                                              newParam[4], newParam[5], newParam[6]);                                                  // 不注入参数,直接执行原函数;
                                  //window[RealFuncAfterHooked](param1,param2,param3,param4,param5,param6,param7);
                                  }
                          //alert("hook after: "+window[funcNameHooked]);
                          },
                      10);
                    return true;
                  } catch (e){
                          return false;
                  }
          },

这段代码固定了被Hook的函数所在对象是window,这样对于自定义对象中的函数及原型对象中的函数(String.prototype)就没办法进行Hook了。而且参数param[1-7]是写死在函数里的,通用性不太好,其实可以用arguments对象来实现变参。
因为要做的是函数钩子,函数又都是Function对象的实例,那么直接给Function.prototype添加hook和unhook函数就可以了。
按照这个思路自己写了一个小脚本,简单封装了一下,能够对普通的全局函数(eg:alert),自定义类中的函数(eg:cat.Eat()),以及原型对象中的函数(eg:String.prototype.slice)进行hook。可以防止函数被二次hook而导致的callback in callback。代码不长这里就贴出来了,也可以到github上去看,有测试样例和参数说明。

 

function Hooks()
{
return {
initEnv:function () {
	Function.prototype.hook = function (realFunc,hookFunc,context,funcName) {
		var _context = null; //函数上下文
		var _funcName = null; //函数名

		_context = context || window;
		_funcName = funcName || getFuncName(this);
		_context[realFunc] = this;

		if(_context[_funcName].prototype && _context[_funcName].prototype.isHooked)
		{
			console.log("Already has been hooked,unhook first");
			return false;
		}
		function getFuncName (fn) {
			// 获取函数名
			var strFunc = fn.toString();
			var _regex = /function\s+(\w+)\s*\(/;
			var patten = strFunc.match(_regex);
			if (patten) {
				return patten[1];
			};
			return '';
		}
		try
		{
			eval('_context[_funcName] = function '+_funcName+'(){\n'+
				'var args = Array.prototype.slice.call(arguments,0);\n'+
				'var obj = this;\n'+
				'hookFunc.Apply(obj,args)\n'+
				'return _context[realFunc].apply(obj,args);\n'+
				'};');
			_context[_funcName].prototype.isHooked = true;
			return true;
		}catch (e)
		{
			console.log("Hook failed,check the params.");
			return false;
		}
	}
	Function.prototype.unhook = function (realFunc,funcName,context) {
		var _context = null;
		var _funcName = null;
		_context = context || window;
		_funcName = funcName;
		if (!_context[_funcName].prototype.isHooked)
		{
			console.log("No function is hooked on");
			return false;
		}
		_context[_funcName] = _context[realFunc];
		delete _context[realFunc];
		return true;
	}
},
cleanEnv:function () {
	if(Function.prototype.hasOwnProperty("hook"))
	{
		delete Function.prototype.hook;
	}
	if(Function.prototype.hasOwnProperty("unhook"))
	{
		delete Function.prototype.unhook;
	}
	return true;
}
};
}



下载hook.js  https://github.com/pnigos/hookjs

分享给朋友:

相关文章

WordPress曝XSS高危漏洞 百万网站受影响!

WordPress曝XSS高危漏洞 百万网站受影响!

WordPress内容管理系统(CMS)刚刚发布了更新——4.2.3版本,修复一个严重的、影响数百万网站的安全漏洞。 WordPress上存在XSS漏洞 WordPress...

MetInfo_v5.1.3 任意文件上传漏洞

MetInfo_v5.1.3 任意文件上传漏洞

MetInfo 23号发布了新版本5.1.5,修补了本文提到的漏洞,当然严格来说应该是任意变量覆盖漏洞.... ps:欢迎各种形式转载,首发t00ls.net 注:请勿利用本文内容从...

当Vcenter遇到域(控制某校园网管电脑之后)

当Vcenter遇到域(控制某校园网管电脑之后)

自从上次改卡被约谈之后学校开始大力整治校园网。今天上学校虚拟机看看结果被提示当前计算机被另一个vcenter管理着,于是来到提示的xxx.252,登陆之结果被告知无权限科普:VMware...

xss渗透试验

xss渗透试验

工具:appscan 站点:www.talk915.com 浏览器:IE8,firefox 方法:插入<imgsrc=”javascript: “&g...

土豆两个分站远程代码执行漏洞

土豆两个分站远程代码执行漏洞

土豆channels.tudou.com“频道”分站远程代码执行漏洞   sleep 5秒测试代码:   POST /director...

跨站请求伪造 CSRF防护方法

跨站请求伪造 CSRF防护方法

CSRF(Cross-site request forgery跨站请求伪造,也被称成为“one click attack”或者session riding,通常缩...

服务器数据安全保护需要找准要害

服务器数据安全保护需要找准要害

  随着企业信息化办公管理体系的普及,服务器在加快整个企业网络运行速度和扩大存储容量的同时,它的安全运行也是最让人头疼的事儿,而那些仅靠服务器本身设置的基础故障处理技术和销售商...

代码审计phpdisk盲注和前台任意用户登录漏洞(exp)

代码审计phpdisk盲注和前台任意用户登录漏洞(exp)

文件 plugins\phpdisk_client\passport.php   $str = $_SERVER['QUERY_STRING'];...

Zend Framework本地文件泄露及解决方案

Zend Framework本地文件泄露及解决方案

标题: Local file disclosure via XXE injection 影响产品: Zend Framework 影响版本: 1.11.11  1.12.0...

淘宝欺骗病毒的鉴定 TaBAccelerate.dll

淘宝欺骗病毒的鉴定 TaBAccelerate.dll

样本名称:TaBAccelerate.dll 样本大小:1135104 字节 样本MD5:7AEF6EEECB37685D17F3D9BD76FA9EA0 样本SHA1: EB1E...

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
请先 登录 再评论,若不是会员请先 注册