前言
- 请勿用于商业用途,仅供学习
- 该登录方式为账号-密码登录,只能登录经常登录的账号,登录他人账号,只能进行扫码
- 感谢这个博客的帮助 https://blog.csdn.net/illbehere/article/details/53262033
- qq邮箱登录地址
正文
1 找到js文件,打断点
输入账号和错误的密码,可以看到有两个请求,一个check,一个login。check会根据账号返回一些参数,这些参数会使用在login里。
采用xhr的方式寻找js文件,你会发现然并卵,不会有断点停住的。
正确的寻找js文件,是监听登录按钮的点击事件。
一步一步往下执行的结果
这个i.p就是login登录里面的参数p,也就是加密后的密码,是重点要破解获取的。
2 寻找pt.plogin.salt
分析这个函数的参数
i.p = $.Encryption.getEncryption(n, pt.plogin.salt, i.verifycode, pt.plogin.armSafeEdit.isSafe)
n:是密码明文
pt.plogin.salt:暂时不明是个啥
i.verifycode:是check返回的参数之一
pt.plogin.armSafeEdit.isSafe:无意义,undefined
pt.plogin.salt全局搜索一下,可以看到调用了uin2hex的函数,参数是不带@qq.com的账号。跟进去,可以看到该函数的具体实现。
可以试验一下,这个函数是否正确,使用Snippets,查看控制台输入是否跟断点显示的一样。
3 分析h函数
所需参数分析完了,进入getEncryption函数,可以看到h函数,h函数是加密密码的主函数
主函数里面有各种函数的调用栈,非常复杂繁琐,一层跟进又一层,我原本尝试着一层一层跟进去,取出里面所涉及到的方法,后来分析到rsa_encrypt这个函数,彻底放弃了,方法太多,我取函数名都取得晕晕的,担心函数撞名,毕竟人家混淆后用abcd来命名,我们跟着这么命名会重复的,而且万一哪里出错了,你还得一个一个去核对函数是否正确。最后我发现所有涉及的函数都在c_login_2.js里面,所以我全部复制黏贴了,放到了sublime里面去查看
放到sublime里面一看,有4653行,还好不算很多。里面有很多方式是用不到的,所以接下来我们要取出主要涉及登录的函数部分。
首先 根据 function h(e, i, n, o),判断包含这个函数的函数是需要的,往上翻,可以看到h函数是存在$.Encryption = $pt.Encryption = function() 这里的,然后把这个函数全部复制黏贴下来。
然后看看h函数里面有涉及到哪些函数。仔细分析下h函数,看红色框框,凡是这种t,g,r这样的,都是跟h函数是同一个函数体下面的,刚刚已经复制黏贴了,不用管了。看看蓝色框框,有个TEA,不知道是哪个啥,全局搜索找到TEA的函数体,然后复制黏贴下来。之后同理找到黄色框框RSA涉及到的函数体。
找到之后,复制黏贴发现才1000行,之后我们要保证,这些js代码,能够脱离单独运行。在一个新的窗口打开,新建一个snippet文件。不要在qq邮箱登录地址的窗口打开,因为它的js文件已经加载了,你运行js代码,是不会报任何错的。
接下来就进行js文件修改,让它可以脱离原本的js文件加载运行起来。
4 修改js文件
前面有个uin2hex的函数,这个函数也复制进去,我们要获取salt,然后调用h函数看看,会不会报什么错。
4.1 $pt is not defined
$pt我觉得只是一个指明,代号这样的,完全可以删除,把所有涉及到的 $pt.XX全部删掉,涉及到 $pt的调用,改为 $.xx的调用,比如 var h = $.RSA.rsa_encrypt(g(u + c));改完之后再运行,控制台输入了一串
把这个复制黏贴,跟抓包里面的p比一下长度,发现是一模一样的,而且我们基本没有改动关键代码,我们有理由相信,这个就是我们要的加密后的密码。之后我们放进python中,看能不能直接调用这个js。在js里面写个函数getPassword,写个py文件调用这个函数,看打印效果。
function getPassword() {
var n = "qerewtwret123214"
var salt = getSalt(123456789)
var verticode = "!C90"
var safe = undefined
return $.Encryption.getEncryption(n, salt,verticode , safe)
}