一、逆向目标

image.png

二、逆向参数

1. 密码字段pw

(1)定位密码字段

查看network字段,发现有3个可能涉及的请求接口:”gt”、”l”、”powGetp”

里面请求体都为 encParams加密字段,所以判断不出哪个接口是真正的password加密

image.png

所以,这块需要将这三个接口都打XHR断点。每个接口都进行跟栈。

直接无脑xhr断点,一步步向上跟栈就完事了。。。

image.png

(2)第一个接口:”gt”

image.png

向前跟栈,看能不能定位到和password相关的内容:这块具体过程就省略了……

image.png

继续向前一步跟栈,发现输入的用户名成功显示了,但没有任何密码相关的字段

image.png

向前继续跟一下栈,确实没有发现任何密码字段相关内容。猜测该接口 “gt” 不是密码加密接口

(3)第二个接口:”l”

image.png

向前跟栈……

找到了这样一个栈中提到了”un”和”pw”字段,不出意外,对应下来,应该是用户名和加密后的密码

image.png

再向前跟栈,最终定位pw字段最后一次出现的位置:

image.png

再往前跟栈,发现找不到pw字段了。所以,这块在当前JS中搜索关键字 “pw”

找到多处,仔细观察发现涉及到pw的代码都有出现函数MP.encrypt2

e.pw = MP.encrypt2(this.__password);
t.pw = MP.encrypt2(this.$refs.mpinput._$getValue() || "0");
t.pw = MP.encrypt2(i);
e.pw = MP.encrypt2(this.__password);

下断点,最终在 “t.pw = MP.encrypt2(i);” 位置断下:

image.png

也就说明 MP.encrypt2 是真正的加密函数。

(4)第三个接口”powGetp”

这个就不说了,和上面分析思路类似。看了下跟密码字段也没啥关系

(5)MP.encrypt2加密函数分析

确认为RSA加密。

image.png

硬扣代码:搞定!

……
//前面代码省略,就直接将这个JS拿下来就行
……
function encrypt2(e) {
var h = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5gsH+AA4XWONB5TDcUd+xCz7ejOFHZKlcZDx+pF1i7Gsvi1vjyJoQhRtRSn950x498VUkx7rUxg1/ScBVfrRxQOZ8xFBye3pjAzfb22+RCuYApSVpJ3OO3KsEuKExftz9oFBv3ejxPlYc5yq7YiBO8XlTnQN0Sa4R4qhPO3I2MQIDAQAB-----END PUBLIC KEY-----'
var t = RSA.getPublicKey(h);
return RSA.encrypt(e, t)
}

image.png

2. encParams加密参数

全局搜索,定位到参数位置:确认SM4加密

image.png

(1)跟进加密函数r._$sm4Encrypt

_p._$sm4Encrypt = function(e) {
return window.URSSM4.encrypt(JSON.stringify(e), _sm4pubkey)
}

image.png

这块的 _sm4pubkey 是固定值为:

_sm4pubkey = 'BC60B8B9E4FFEFFA219E5AD77F11F9E2'

image.png

定位 “window.URSSM4.encrypt” 函数位置,发现是webpack的形式

image.png

(2)webpack代码分析

①代码先复制进notepad++中

image.png

②找到分发器的位置

发现这块有调用的过程,且调用函数为n,所以猜测函数n所在位置可能为分发器

image.png

下断点,重新刷新一下页面(因为webpack是在页面最初就加载进来的,所以需要刷新页面)

image.png

成功断下,定位到n的位置:

image.png

image.png

分发器代码简单改写下:

var _e

!function(){
function e(i) {
var r = n[i];
if (void 0 !== r)
return r.exports;
console.log('-->',i)
r = n[i] = {
exports: {}
};
return t[i](r, r.exports, e),
r.exports
}
_e = e
}({

//加载webpack模块
})

③扣取加密模块代码

太多了,省略……

④编写加密函数

var pwd = '{"un":"admin123@163.com","pw":"ffhnKr8vA0EIEEclcRR6Ik8sDkEkjcvalofxRMQcS+ADdxyWoPpZFE6pehucjf/+0F5MliRjC51VMPUkGK/ceLj5fTlhNj34pHSfnU7zMd35XwSaPax/ucpNWpStm4tb0gyl+rb0ulEzQn7Tk4FR1hCUcE5kyAjo52567M+Eb8Q=","pd":"mail163","l":0,"d":30,"t":1695908789441,"pkid":"CvViHzl","domains":"163.com","tk":"8753c188d3bbad4996c4cf699e3beef5","pwdKeyUp":1,"channel":0,"topURL":"https://smart.mail.163.com/login.htm","rtid":"RXuDHOFWWNPiiotxQy3UqrnZvRh7yrSM"}'

var _sm4pubkey = 'BC60B8B9E4FFEFFA219E5AD77F11F9E2'

var p = _e('9579'); //定义导出函数,将加密模块导出为全局变量p


function enc(pwd) {
return p.encrypt(pwd, _sm4pubkey)
}

(3)完整代码测试

略略略……

image.png

image.png