某外卖平台x-for-with加密逻辑

网站链接

aHR0cHM6Ly9oNS53YWltYWkubWVpdHVhbi5jb20vd2FpbWFpL21pbmRleC9ob21l

网站分析

紧跟上一篇文章,这次是x-for-with的参数加密逻辑,比起上一篇的token,难度要大一些。

首先搜索是搜索不出来这个x-for-with的,但因为是ajax加载的,所以我们可以在xhr里找逻辑,然后去下断点,发现是eval出来的js

经过分析最终定位到x-for-with加密的入口函数是这里

而参数e就是经过这两个函数处理后的值

因为是eval出来的js,而且e参数的值是变化的,那我们就需要找这个js是怎么eval出来的。

ps:其实这里还有个_()函数,控制台打印下就是字符串x-for-with,这就是为什么搜不到这个关键词的原因,因为他混淆了(不过不重要,这里知不知道都无所谓)

这里节省时间,就不踩着坑去走了,直接说最终的eval逻辑。

首先是源码中的一大串看不懂的东西,这个其实就是x-for-with参数加密的js源码加密后的密文(这句话是有点绕哈,说白了就是把js源码给加密了)

对应的解密函数也在源码中,紧跟着这个mieta标签的后面的script标签就是,太长了,截不全,凑合看看知道在那就行了

多刷新几遍会发现,这串js只有最后的这里的三个参数在变化

ps:这三个参数分别为上面mieta标签里的id,aes加密的key和iv,这个我们后面再说

把这个script标签下的所有内容都复制下来,格式化后放在本地,开始js代码的分析

js代码分析

补上window环境后,代码就可以运行了

把格式化后的代码拉到最下面,这里就是入口函数,参数分别有三个,mieta标签里的id,aes加密的key和iv(也就是上面说的那三个)

这里要注意下releasex这个方法前面要加window。还有,红框里的这一行,去获取了mieta标签里的content值,所以我们要先获取到这个值,然后再传进来,不能使用代码原有的写法。

修改后的代码如下:

window.meituan = function _r(metaId, key, iv, content) {
        var keyb = window.releasex.util.convertStringToBytes(key);
        var ivb = window.releasex.util.convertStringToBytes(iv);
        var encryptedHex = content;
        window.metaIdx = getKeys(encryptedHex);
        encryptedHex = getRealSource(encryptedHex);
        var encryptedBytes = window.releasex.util.convertStringToBytes(encryptedHex, "hex");
        var aesCbc = new window.releasex.ModeOfOperation.cbc(keyb, ivb);
        var decryptedBytes = aesCbc.decrypt(encryptedBytes);
        var decryptedText = window.releasex.util.convertBytesToString(decryptedBytes);
        var i;
        for (i = decryptedText.length - 1; i > 0; i--) {
            if (decryptedText.charCodeAt(i) > 31) {
                break
            }
        }
        return decryptedText.slice(0, i + 1)
    }

直接调用window.meituan传入源码中获取到的metaId, key, iv, content,就能成功解密出我们想要的js源码

接着我们复制这段打印出来的js,格式化后发现就是上面eval出来的js

ps:这段js需要补上window,document,XMLHttpRequest,navigator环境,才能在本地运行

因为只有v函数里面的值是变化的,而且这几个if的结果都是true。

所以我们就需要按原逻辑去取出里面的值,拼接好这个code

最后修改后的加密入口函数如下

var p = window.XX = function(e, code) {
    e.code = code;
    e.cts = (new Date).getTime();
    var r = JSON.stringify(e);
    var t = 'jvzempodf8f9anyt';
    var n = window.releasex.util.convertStringToBytes(t);
    var i = window.releasex.util.convertStringToBytes(t);
    var o = window.releasex.util.convertStringToBytes(r);
    var a = window.releasex.padding.pkcs7.pad(o);
    var u = new window.releasex.ModeOfOperation.cbc(n,i);
    var c = u.encrypt(a);
    var f = s(c);
    return f
};
var w = window.EE = function (){return {
    ts: (new Date).getTime(),
    cts: (new Date).getTime(),
    brVD: d(),
    brR: l(),
    aM: h(),
    code: ""}
};

这里要注意的是releasex这个方法前面要加window,变量t是固定值

最后这样调用就能得到x-for-with的值了

console.log(window.XX(e=window.EE, code='刚才自己拼接的code'))

小结

这篇文章的难点在于js是eval出来的,而且eval出来的js里的某个方法里面的值还是动态的

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AJackpot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值