webpack实战:某网站RSA登录加密逆向分析

1. 写在前面

  回过头看,已慢慢将JS爬虫逆向类型的文章从0建设到了1,文章所有案例真实且内容有效,加密类型丰富。收获了很多粉丝的关注与支持,非常感谢大家!

在这里插入图片描述

往后的时间内,将着手准备在空余时间内开始写关于分布式采集平台在开源情报、网络舆情中的建设技术文章,将自己多年的经验与储备分享出来,这也是一直以来想写的文章题材!


分析目标

aHR0cHM6Ly93d3cuZ205OS5jb20v


在这里插入图片描述

2. 抓包分析

  本次目标登录参数加密,老规矩构造用户名密码尝试登录抓包分析一下:

在这里插入图片描述

可以看到提交登陆请求重password是我们需要分析的参数,ckcode是验证码,其他都无关紧要

3. 定位分析

  尝试使用全局搜索看看password可不可追溯一下,发现common.js、home.min.js两个文件可能大概率有加密操作,代码也不多。先翻翻第一个文件,找到了很显眼的函数,如下所示:

在这里插入图片描述

common.js文件中找到关键代码如下所示:

function Rsa(){
    
    
    if(typeof JSEncrypt === 'undefined') return;
    this.jsencrypt = new JSEncrypt();

    // 设置公钥
    this.jsencrypt.setPublicKey("-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDq04c6My441Gj0UFKgrqUhAUg+kQZeUeWSPlAU9fr4HBPDldAeqzx1UR92KJHuQh/zs1HOamE2dgX9z/2oXcJaqoRIA/FXysx+z2YlJkSk8XQLcQ8EBOkp//MZrixam7lCYpNOjadQBb2Ot0U/Ky+jF2p+Ie8gSZ7/u+Wnr5grywIDAQAB-----END PUBLIC KEY-----");
}

/**
 * rsa加密
 * @param  {string} [str] [待加密字符串]
 * @return {string} [经过rsa加密的字符串]
 */
Rsa.prototype.encode = function(str,confuse){
    
    
    var enStr = confuse ? confuse + "|" + str : str;
    return encodeURIComponent(this.jsencrypt.encrypt(enStr)); // rsa+uri编码
}

var rsa = new Rsa();
// 针对login接口的登录函数(部分官网在调用)
function lessLogin( params ){
    
    
    var timestamp = new Date().getTime();
    var uname = params['uname'];
    var password = rsa.encode(params['password'],timestamp);
    var forward = params['forward'];
    var remember = params['remember'];
    $.ajax({
    
    
        url : '//passport.gm99.com/login/login',
        type : 'get',
        data:{
    
     'encrypt':1, 'uname': uname, 'password': password, 'forward': forward, 'remember': remember },
        xhrFields: {
    
    
            withCredentials: true
        },
        jsonp: 'callback',
        async : true,
        dataType : 'jsonp',
        success : function(data){
    
    
            $('head').append(data);
        }
    });
}

可以看到上面的代码是一个封装了RSA加密函数的函数,RSA()其实是对RSA加密函数进行了再次封装,然后网站调用这个函数来发送登录表单进行验证,它并不是真正的加密函数

home.min.js文件中找到了如下一行代码:

o = a.encode(t.password, s)

断点重新提交登录,可以发现t.password就是我提交的明文密码。o则是加密后的密文

在这里插入图片描述

home.min.js文件的代码一打开就能开到,典型的webpack方式加载模块!

划重点: webpack不是加密代码,而是加载加密模块的方法!结构特征()([])、()({})

结构区别:()([])传递的参数是数组,()({})传递的参数是对象

在这里插入图片描述

4. 构建webpack

  先不用去管加密代码啥的,我们先构建webpack的结构。这里可以直接用它自己的自执行函数:

!function(t) {
    
    
	var i = {
    
    };
	function e(s) {
    
    
	    if (i[s])
	        return i[s].exports;
	    var n = i[s] = {
    
    
	        exports: {
    
    },
	        id: s,
	        loaded: !1
	    };
	    return t[s].call(n.exports, n, n.exports, e),
	    n.loaded = !0,
	    n.exports
	}
}({
    
    /*这里是加载模块*/})

上面的代码我们可以在控制台内测试一下,看看如下是否通过:

在这里插入图片描述

接下来要做的就是找到加载模块,回到之前t.password那里。一共就两个JS文件,这个地方更像是加密的位置,所以我们分析断点。鼠标查看发现a.encode,直接点击跳转

在这里插入图片描述

定位到了如下代码块:

在这里插入图片描述

从上述代码分析可以提炼出两个关键点:

加密函数实例化:new r.JSEncrypt
公钥:setPublicKey

至于this.jsencrypt.encrypt(i)不像是实现加密的代码,看起来像是封装加密函数的模块

直接在这一行下断点再次登录,鼠标找到encrypt点击跳转

在这里插入图片描述

跳转到如下代码块:

在这里插入图片描述

上图所示的代码所在位置在4: function这个加载模块内:

在这里插入图片描述

var r = i(4)中的i函数对应加载器函数里面的t[s].call(n.exports, n, n.exports, e)的参数i,即i 等于e,而e就是加载器函数,所以4: function这个加载模块正是加密代码!

最终完整可用的webpack结构加密代码结构如下:

var _Encryp;
var navigator = {
    
    };
var window = this;
!function(t) {
    
    
    var i = {
    
    };
    function e(s) {
    
    
        if (i[s])
            return i[s].exports;
        var n = i[s] = {
    
    
            exports: {
    
    },
            id: s,
            loaded: !1
        };
        return t[s].call(n.exports, n, n.exports, e),
        n.loaded = !0,
        n.exports
    }
    _Encryp = e;
}({
    
    3: function模块, 4: function加密模块})

3: function模块, 4: function加密模块的代码自己扣一下填入上面即可!不会扣的有需要测试学习的也可以私我!

因为代码多达近3000行比较庞大!这里我就不再贴出来了,最终加密需要的参数上面断点信息也可以看到分别是密码、时间戳!如下所示为控制台测试效果:

在这里插入图片描述

  好了,到这里又到了跟大家说再见的时候了。创作不易,帮忙点个赞再走吧。你的支持是我创作的动力,希望能带给大家更多优质的文章

猜你喜欢

转载自blog.csdn.net/qiulin_wu/article/details/132801536
今日推荐