开始先登录正常输入
抓到这中文直译为’验证’的包,查看其formdata
formdata没有提交的验证码字段,不断更换验证码也没有新包出现,说明这个验证码是本地js生成的无关紧要
uName为明文的‘’登录手机号‘’,israndomPwd直译来猜测是随机密码,uPwd猜测为密码,那就先破解密码,全局搜索upwd,其中upwd:pwd,所以我们猜pwd是已经加密好的断点调试一下
function ValidatePwd(UType, Account, Pwd, RandomFlag) {
var isRandomPwd = RandomFlag == "1" ? true : false;
$.postJSON(webAppPath + "/pwd/validate", {
"uName": Account,
"uType": UType,
"uPwd": Pwd,
"isRandomPwd":isRandomPwd
}, function (data) {
if(data == null){
showErrMsg('系统繁忙');
return;
}
// rspCode=0000,表示密码符合规范
if(data.rspCode == '0000'){
hideErrMsg();
return;
}
// rspCode=9114,表示密码为弱密码
if(data.rspCode == '9114'){
showErrMsg('密码过于简单,请通过“<a style="color: #ff8200" onclick="wjmmShow();">忘记密码</a>”进行重置。');
return;
}
showErrMsg(data.desc);
}, false);
};
知识点1 调用栈
我们看见此时pwd已经变成了3k开头的加密串,说明已经完成加密,那我们想看这上一步是如何生成的,就利用到了调用栈call stack,程序的执行顺序在栈是从下到上,那我们看最近的anonyous,点击即可
在这里我们看见密码明文了,下一个栈就是密文,说明就在其中,我们看到aesEncrypt就知道这是标准的加密库(速记:看到加密就cry了),那我们就单独在这里打断点,取消其他的断点(避免干扰)
程序停在这里了,我们进入
最上面就是我们要的函数,我们看下需要剥离多少,首先返回的是d,d是由e:密码明文生成的,c是由a生成的,a是由默认字符串生成的,那我们只需要先抠出这一个如下
# 抠出的代码
$.fn.aesEncrypt = function(e) {
var a = CryptoJS.MD5("login.189.cn");
var c = CryptoJS.enc.Utf8.parse(a);
var b = CryptoJS.enc.Utf8.parse("1234567812345678");
var d = CryptoJS.AES.encrypt(e, c, {
iv: b
});
return d + ""
}
;
# 剥离函数名(仅修改第一行)
function aesEncrypt(e) {
var a = CryptoJS.MD5("login.189.cn");
var c = CryptoJS.enc.Utf8.parse(a);
var b = CryptoJS.enc.Utf8.parse("1234567812345678");
var d = CryptoJS.AES.encrypt(e, c, {
iv: b
});
return d + ""
}
;
上函数又调用了CryptoJS库的.MD5等,那我们还需要这个库,可以直接python包自己生成,也可以剥离代码,此处我们剥离,点击调试进入函数(就是之前的下箭头)
调用部分:
此文件的开头部分:
那妥了呀整个文件,都是这个库,直接全部复制粘贴就好了,此处不贴源码了
一共复制这个aes.min.js:formatted整个文件+上面剥离的文件,加下面这一行验证代码
console.log(aesEncrypt('lsxy13145678'))
查看结果,二者一致
知识点总结
栈 :call stack
下箭头:进入函数
剥离代码
aes加密
加密库名称CryptoJS (遇到加密就cry了)
min:代表压缩