网易游戏登录密码加密破解小试

最近实在太忙,更新速度也慢了,今天得空网上冲浪一会,心血来潮打开了童年游戏大话西游官网,本想看看有什么变化,发个帖抱怨一下为啥还不开怀旧服,就在登录之际又忍不住按下了F12,跟我想的一样,的确是把密码加密了,那好吧,等我把JS代码扣完再去发帖吧,觉得有帮助关注一下知识图谱与大数据公众号吧,当然不关注也无所谓。

前言

依然有完整JS代码,原文链接,点击文末阅读更多即可,还是熟悉的rsa加密,有兴趣的可以跟着东扣扣西扣扣,锻炼一下,整个过程不难。登录地址请跳到运行章节,在python代码里有。。

直入正题

打开登录界面,输入错误的账号密码(图中的账号均为虚构)。
在这里插入图片描述
目的当然是查看提交的数据里有没有加密的,找到其提交url,如下所示:
在这里插入图片描述
右侧往下拉一点即可看到提交的参数,这次有点不一样,提交的参数并不是FormData形式,不过也不影响,如下:
在这里插入图片描述
仔细看一下,大概可以知道pw是密码加密结果,un是账号,其它几个参数暂时可以看成是固定的(一样也可以通过调试得到),今天主要是pw即密码解密,接下来可以通过调用栈进去,调用栈进去也可以稍微利用一点技巧,比如可以查看方法名,我们现在是在解密登录,那我们就可以通过方法名里有类似login的进去。如下图所示:
在这里插入图片描述
进去以后你可能会迫不及待的像往常一样查找pw关键字,其实通过关键字也能猜到这样查找是能找到,当时要耗费不少精力,毕竟pw只有两个字母太容易与其它单词匹配了:
在这里插入图片描述
是不是,一下子匹配了113个地方,你当然可以一下一下点了,这样细心点也能找到,只不过费点时间而已,还有一个方法,现在我们已经知道密码是被加密了,那我们就搜索关于加密的单词,类似encrypt,这是一个经验,大家可以掌握,试着搜一下encrypt
在这里插入图片描述
一共搜到16处,这可比113少多了吧,手再也不酸了,,因为以后还会遇到很多参数名只有一个字母或者两个的情况,这算是一个比较有意思的方法吧。接下来我们在几个比较怀疑的encrypt打上断点,一共有三处,为什么这么说,看下面代码,是不是都很像要找的(截图麻烦,我直接把代码放下面了):

n.pw = MP.encrypt2(this.__password);//第一处
t.pw = MP.encrypt2(this.$refs.mpinput._$getValue() || "0");//第二处
 t.pw = MP.encrypt2(n);//第三处

进入调试

在前面我们已经在几个可以点打上了断点,接下来就可以调试了,激活断点(即输入账号密码,点击登录),果不其然,跳到了其中一个断点:
在这里插入图片描述
那就是这里喽,单步运行下去,进入加密函数encrypt2
在这里插入图片描述
其中encrypt2的参数e为你输入的密码,调试了几次发现这里getPublicKey参数p其实也是个固定值,一共需要抠的主函数也就两个,一个encryptgetPublicKeyp值请看下图:
在这里插入图片描述
继续运行,进入设置getPublicKey函数:

  getPublicKey: function(e) {
        if (e.length < 50)
            return !1;
        if ("-----BEGIN PUBLIC KEY-----" != e.substr(0, 26))
            return !1;
        e = e.substr(26);
        if ("-----END PUBLIC KEY-----" != e.substr(e.length - 24))
            return !1;
        e = e.substr(0, e.length - 24);
        e = new ASN1Data(Base64.decode(e));
        if (e.error)
            return !1;
        e = e.data;
        if ("1.2.840.113549.1.1.1" == e[0][0][0])
            return new RSAPublicKey(e[0][1][0][0],e[0][1][0][1]);
        else
            return !1
    }

encrypt函数:

   encrypt: function(e, t) {
        if (!t)
            return !1;
        var i = t.modulus.bitLength() + 7 >> 3;
        e = this.pkcs1pad2(e, i);
        if (!e)
            return !1;
        e = e.modPowInt(t.encryptionExponent, t.modulus);
        if (!e)
            return !1;
        e = e.toString(16);
        for (; e.length < 2 * i; )
            e = "0" + e;
        return Base64.encode(Hex.decode(e))
    }

到这里大家应该都知道要扣哪些了吧,对,就是getPublicKeyencrypt里面使用到的一些小函数,比如Base64.decode(e)Hex.decode(e)等等这些,难点是这些方法里面还嵌套了其它方法,容易的地方是这些方法基本都在一起,再提一个抠代码的小技巧,抠的时候可以找到你想要的函数,点一下函数的大括号,括号下面会有横线,这时候你就可以确定抠到哪里了,因为结尾的大括号下面也会有横线,听不明白没关系,看一下下图就理解了:
在这里插入图片描述

我这里就不列出所有代码了,大家有兴趣的可以关注知识图谱与大数据公众号,找到这篇文章,点击文末的阅读原文即可看到完整JS代码。

运行

相信大家都能抠出来,抠完就可以通过python运行,上盘古时期代码:

import execjs
#url = //xy2.netease.com/member.php?mod=logging&action=login
with open('..//js//dahuaxiyou.js', encoding='utf-8') as f:
    dahuaxiyou = f.read()
js = execjs.compile(dahuaxiyou)
logid = js.call('get_pwd', "qwerqwrqrq")
print(logid)

运行结果如下:
在这里插入图片描述

结束

rsa的代码的确要比md5要费点时间,不过只要细心都能抠出来,抠不出来的点即文末阅读原文即可。觉得有帮助关注一下知识图谱与大数据公众号吧,有大量抠JS代码的文章,当然不关注也无所谓。
在这里插入图片描述