前端JS加密那些事

前端JS加密那些事

0x01前端基本编码/加密方式

前端信息枚举时,当通过Burp抓包发现参数经过类似Base64、MD5等方式处理过的,可以直接通过Burp->Intruder->Payloads->PayloadProcessing的设置来进行枚举。这里还有一些其他的功能可以自行拓展(如:增加payload前缀)

0x02自定义加密

如果遇到自定义加密的情况,就需要通过阅读js文件,找到加密函数。根据加密函数对参数值进行运算后再提交数据包。

寻找Encrypt()

寻找加密函数的方法有很多种,接下来我通过实例来讲讲我的方法,希望有人能看明白吧。
就在刚刚遇到的一个登录页面,登录的数据包是这样的(如下图)。password参数是经过处理后的数据,咋一看通过URL解码后拿去按base64解是乱码,这时就需要看js做了什么操作了。

我们F12打开开发者工具,通过开发者工具左上角的元素选择工具,定位到登录按钮元素。然后在右侧的选项卡中选择EventListeners,查看绑定了登录按钮Click(点击)事件的js。

一眼应该很明显能看到最后一个customerLogin.js,我们要的东西应该在这里面,点击它跟进进去。
跟进后我们简单阅读js,大概就了解了Burp抓的那一串数据是怎么来的了。通过UED.aes.getKey(16)获得Key后,使用UED.aes.encrypt(key,password)加密。我们可以继续跟进,搜索一下UED是个什么东西以及UED.aes.getKey()和UED.aes.encrypt()的定义。

这里我们通过search in all files来找UED的定义。

跟进这个文件,我们就可以清晰的看到加解密的过程和getKey的作用了~

var UED = window.UED || {};
(function ($, window) {

	
	var App = {
		init: function() {
			this.cacheElements();
			this.bindEvents();
		},
		cacheElements: function() {

		},
		bindEvents: function() {

		},

		/**
		* aes加密
		* @param theKey 密钥
		* @param pass 密码(原文)
		*/
		encrypt: function(theKey,pass){
			 var key = CryptoJS.enc.Utf8.parse(theKey);	

			 var srcs = CryptoJS.enc.Utf8.parse(pass);
			 var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
			 return encrypted.toString();
		},

		/**
		* aes解密
		* @param theKey 密钥
		* @param pass 密码(密文)
		*/
		decrypt: function(theKey,pass){
			 var key = CryptoJS.enc.Utf8.parse(theKey);	

			 var decrypt = CryptoJS.AES.decrypt(pass, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
			 return CryptoJS.enc.Utf8.stringify(decrypt).toString();
		},
		/**
		* 生成密钥
		* @param n 生成多少位的密钥(默认8位)
		*/
		getKey: function(n) {
			var chars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
		
			 if(n==null){
				n = 8;
			 }
			 var res = "";
			 for(var i = 0; i < n ; i ++) {
				 var id = Math.ceil(Math.random()*35);
				 res += chars[id];
			 }
			 return res;
		}
	}
	App.init();
	UED.aes = App;
  
})(jQuery,window);

这样下来我们就了解了整个过程:

  1. getKey(16) //获取随机16位key
  2. encrypt(key, password) //加密password
  3. 将key和password都发送给服务端

0x03 绕过前端加密

这里总结了几种绕过的方式:

  1. 如果加密算法比较简单的话,可以通过编程语言重写一下加密,再构造发送数据包。这样的弊端是,当加密算法较复杂,或时间较紧急时无法快速完成测试。

  2. 第二种与1有些类似,通过Python的PyExecJs模块加载JS加密函数。通过调用此函数获得加密后数据,再构造发送数据包。下图是针对上面讲的案例写的脚本。

  3. 第三种方法相对于前面的更加简单粗暴而且快捷。通过使用c0ny1师傅写的Burp插件jsEncrypter来完成此需求。
    项目链接:jsEncrypter,使用的方法作者已经写的很清楚了,网上也有很多文章,这里就不赘述了。我们直接来看下效果吧~下图是针对上面讲的案例做的操作,可以看到生成的密文服务器端成功解析了。

可以看到使用正确的密码进行登录,已经成功登录

0x04 结尾

渗透测试中,有时枚举可能带你进入新世界,让你寻找到木桶上的最短板。本文主要讲一下遇到前端js加密,需要枚举的情况下的一些解决方法。肯定会有更好的办法,也希望各位师傅能分享分享~
文章可能有写的不太清晰或不正确的地方,希望各位师傅斧正。

posted @ 2020-01-21 18:37  Gcker  阅读(2180)  评论(0编辑  收藏