zoukankan      html  css  js  c++  java
  • 前端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加密,需要枚举的情况下的一些解决方法。肯定会有更好的办法,也希望各位师傅能分享分享~
    文章可能有写的不太清晰或不正确的地方,希望各位师傅斧正。

    CTF相关
  • 相关阅读:
    浅谈SQLite——查询处理及优化
    .NET 并行(多核)编程系列之七 共享数据问题和解决概述
    sql 存储过程学习一
    SQL中获得EXEC后面的sql语句或者存储过程的返回值的方法 【收藏】
    script刷新页面,刷新代码
    C#编程中关于数据缓存的经验总结
    SQL存储过程的概念,优点及语法
    SQLite数据库安装、试用及编程测试手记
    c# sqlite 数据库加密
    进销存管理系统的设计与实现
  • 原文地址:https://www.cnblogs.com/Gcker/p/12222761.html
Copyright © 2011-2022 走看看