前端JS加密那些事

前端JS加密那些事

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

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

0x02自定义加密

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

寻找Encrypt()

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

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

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

这里我们通过search in all files来找UED的定义。
前端JS加密那些事
前端JS加密那些事

跟进这个文件,我们就可以清晰的看到加解密的过程和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加密函数。通过调用此函数获得加密后数据,再构造发送数据包。下图是针对上面讲的案例写的脚本。
    前端JS加密那些事

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

可以看到使用正确的密码进行登录,已经成功登录
前端JS加密那些事

0x04 结尾

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

上一篇:【2020-12-23】JS逆向之某在线监测分析平台


下一篇:java – 在AES解密时,给定Final Block未正确填充