写过后,发现挺简单的,虽然看起来做了混淆,但其实和没做没啥区别。另外,通过搜索就可以发现签名函数的位置。
这里使用node js的方式来解决md5和encrypt的引入问题,尽管使用python可以手写出签名,但是比较麻烦,而通过pyexecjs更麻烦。
先说说,该网站反爬策略,登录+sign反爬,page和时间戳生成sign,因此你的sign必须每次更换。
1.开篇找到sign加密的位置
点击jquery处,发现api请求的函数。得到下列函数
function ajax_load_posts(data) {
const _a = 'emSinoyApT_xsuPlcda-vbk.OtCrhjwg';
const _b = 'eius.g-OnlSkmbxtcdPAy_CwraovThpj';
const _c = 'njxt-APirwOvckgah_o.CdsuyTSblemp';
$(_b[4] + _c[15] + _a[29] + _c[15] + _c[2] + _a[19] + _a[15] + _c[18] + _b[25] + _c[21] + _b[1] + _c[0] + _a[31])[_a[12] + _a[28] + _a[5] + _a[30]]();
data[_c[3] + _b[3]] = get_time();
delete data[_a[12] + _c[7] + _a[31] + _b[8]];
data[_c[22] + _a[3] + _a[31] + _b[8]] = makeSign(data);
var loadButton = $(_b[4] + _c[21] + _c[31] + _b[26] + _c[22] + _c[3] + _b[3] + _c[4] + _b[25] + _c[1] + _c[15] + _a[11] + _c[4] + _b[9] + _c[18] + _a[18] + _c[21]);
loadButton[_b[29] + _c[7] + _c[21] + _a[0]]();
var times = globals[_a[8] + _b[26] + _a[12] + _a[25] + _a[12] + _b[21] + _c[31] + _a[0] + _c[8] + _a[10] + _a[8] + _c[15] + _a[31] + _c[29]];
while (times--)
$(_b[4] + data[_b[25] + _c[31] + _b[30] + _c[29] + _a[4] + _a[17]])[_b[25] + _c[31] + _b[30] + _a[0] + _c[0] + _b[17]]($(_b[15] + _b[0] + _c[30] + _c[31] + _c[28] + _b[25] + _c[3] + _a[0] + _c[19] + _b[16] + _a[18] + _c[8] + _b[17] + _a[19] + _c[22] + _a[22] + _a[0] + _a[15] + _c[29] + _b[15] + _a[5] + _c[0])[_a[28] + _b[15] + _c[30] + _a[15]]());
$[_b[25] + _b[31] + _a[18] + _c[2]]({
[_b[2] + _c[8] + _a[15]]: globals[_c[15] + _a[29] + _a[18] + _a[11] + _a[10] + _a[13] + _a[27] + _a[15]],
[_a[25] + _a[6] + _b[30] + _b[0]]: _b[18] + _b[7] + _c[26] + _c[25],
[_b[17] + _a[18] + _a[25] + _b[25] + _c[25] + _b[20] + _b[30] + _b[0]]: _a[29] + _b[3] + _a[5] + _b[8],
[_c[21] + _b[25] + _b[15] + _b[25]]: data
})[_b[17] + _b[26] + _b[8] + _a[0]](function(response) {
const _a2 = _b;
const _b2 = _a;
const _c2 = _c;
loadButton[_c[8] + _c[29] + _c[30] + _c[18] + _a[20] + _c[29] + _a[7] + _c[3] + _a[25] + _c[8]](_a[17] + _c[7] + _a[12] + _a[18] + _b[13] + _a[15] + _c[29] + _b[17]);
if (response[_a[12] + _b[15] + _b[25] + _c[3] + _c[23] + _c[22]] == 200) {
var html = eval(response[_a[17] + _c[15] + _c[3] + _a[18]]);
loadButton[_c[21] + _a[18] + _c[3] + _c[15]](_b[30] + _c[15] + _b[5] + _a[0] + _a[17], data[_a[8] + _a[18] + _b[5] + _a[0] + _b[17]] * 1 + 1);
$(_c[19] + data[_c[15] + _a[8] + _b[30] + _b[0] + _c[0] + _b[17]])[_a[18] + _c[31] + _c[31] + _a[0] + _c[0] + _c[21]](html);
loadButton[_c[8] + _b[0] + _b[12] + _b[26] + _c[11] + _a[0] + _b[22] + _a[15] + _c[15] + _c[22] + _c[22]](_a[15] + _b[26] + _a[18] + _c[21] + _a[3] + _b[8] + _c[14])[_b[3] + _a[28] + _a[5] + _a[30]]();
} else if (response[_b[3] + _b[15] + _c[15] + _c[3] + _a[13] + _b[3]] == 201) {
ncPopupTips(0, response[_c[30] + _c[22] + _b[5]]);
loadButton[_c[3] + _c[29] + _c[2] + _c[3]](response[_b[12] + _b[3] + _c[14]])[_a[12] + _b[29] + _b[26] + _b[23]]();
} else {
ncPopupTips(0, response[_c[30] + _a[12] + _c[14]]);
loadButton[_b[25] + _b[15] + _b[15] + _a[27]](_b[17] + _b[1] + _b[3] + _b[25] + _a[21] + _b[9] + _a[0] + _b[17], _c[21] + _b[1] + _c[22] + _b[25] + _b[13] + _c[28] + _c[29] + _c[21]);
loadButton[_b[25] + _a[17] + _a[17] + _b[22] + _c[28] + _b[25] + _c[22] + _b[3]](_c[21] + _b[1] + _a[12] + _b[25] + _b[13] + _c[28] + _c[29] + _b[17])[_c[22] + _b[29] + _b[26] + _c[9]]();
loadButton[_c[3] + _a[0] + _a[11] + _a[25]](__cosy__[_c[8] + _a[0] + _c[15] + _b[16] + _a[28] + _b[0] + _a[17] + _b[21] + _c[3] + _b[29] + _a[0] + _c[17] + _c[29] + _a[4] + _a[17]])[_a[12] + _b[29] + _a[5] + _b[23]]();
}
})[_c[15] + _c[28] + _a[30] + _c[15] + _c[24] + _a[12]](function() {
const _a3 = _c;
const _b3 = _b;
const _c3 = _a;
$(_a[17] + _b[1] + _b[27] + _c[19] + _b[16] + _b[25] + _b[24] + _a[17] + _c[4] + _a[12] + _b[11] + _b[0] + _b[9] + _c[29] + _b[15] + _a[5] + _a[4])[_c[21] + _c[29] + _c[3] + _a[18] + _c[12] + _c[16]]();
$(_b[4] + _b[25] + _c[1] + _c[15] + _b[14] + _a[19] + _c[28] + _b[26] + _b[25] + _a[17] + _a[3] + _b[8] + _a[31])[_c[16] + _b[1] + _c[21] + _c[29]]();
});
}
可能有人看到这,就直接放弃了,别急,这只是使用了字符串的切片而已,你可以手动将函数复原,获取使用程序。其实,没必要,每次发送请求时,只是修改sign,你可以找到makeSign,打断点,获取data参数,data参数如下:
{
"action": "ajax_load_posts",
"append": "list_home",
"paged": 1,
}
完整的data参数,还需要t(时间戳)和sign
2.开始破解
找到makeSign函数
function makeSign(params) {
const _a = 'w&4915i708etp.rul6Um/afo2dyC=h:skng3bc';
const _b = 'wg0=&5C7U6rof:32e1asy48dkmbn/pcu.9lhit';
const _c = '&ced2hlmk8U3frstbiw5ay14/g07=C.un:p6o9';
var h = window[_a[16] + _b[11] + _c[1] + _c[20] + _a[11] + _b[36] + _b[11] + _b[27]][_b[35] + _c[36] + _b[19] + _b[37]];
var dm = _c[18] + _b[0] + _b[0] + _b[32] + _a[11] + _c[36] + _b[23] + _a[21] + _b[20] + _c[16] + _c[17] + _b[27] + _c[25] + _b[32] + _b[30] + _a[23] + _c[7];
var ksort = Object[_a[32] + _b[16] + _b[20] + _b[19]](params)[_a[31] + _a[23] + _b[10] + _c[15]]();
if (h != dm) {
window[_b[34] + _c[36] + _a[37] + _a[21] + _b[37] + _b[36] + _a[23] + _b[27]][_c[5] + _a[14] + _c[2] + _c[12]] = _a[29] + _a[11] + _b[37] + _b[29] + _a[31] + _b[13] + _b[28] + _c[24] + _c[18] + _a[0] + _b[0] + _c[30] + _c[15] + _c[36] + _b[23] + _c[20] + _c[21] + _b[26] + _b[36] + _b[27] + _a[34] + _b[32] + _c[1] + _c[36] + _b[25];
}
var secret = hex_md5(_c[2] + _c[22] + _c[26] + _b[18] + _c[3] + _a[37] + _b[14] + _c[37] + _b[21] + _a[3] + _b[26] + _a[21] + _b[5] + _c[37] + _c[26] + _a[35] + _a[34] + _b[12] + _b[31] + _a[0] + _b[27] + _a[2] + _c[11] + _c[37] + _a[5] + _c[35] + _a[10] + _a[8] + _a[5] + _c[27] + _c[12] + _b[15] + _c[26] + _c[12] + _b[22] + _a[9] + _c[11] + _a[10] + h);
var str = '';
for (var ki in ksort) {
str += ksort[ki] + _a[28] + params[ksort[ki]] + _c[0];
}
str += _c[14] + _b[16] + _c[1] + _a[14] + _c[2] + _a[11] + _a[28] + secret;
var token = hex_md5(str)[_c[15] + _b[11] + _a[18] + _a[12] + _b[29] + _c[2] + _b[10] + _b[6] + _c[20] + _b[19] + _b[16]]();
return rsa_sign(token);
}
function rsa_sign(token) {
const _a = 'Z4DaR8QOKrsFYcdEjxTtSezVnM7Bb /P3Wv9wiXq-uLApGyJlIU+15Nm2HCh6f0g';
const _b = '6IZ09rhm 3YudOcNeUvBH8LPEp27GaM-Tg/flwtjyV+xKFXzACsnJD1RWiS4Q5bq';
const _c = 'Bi0jHG7sY rIa9QXh8KMPNz/64ec2ywFgbfxld3-+mVqpOJvU5TZ1CLtDEAWuSRn';
var pubkey = _a[40] + _b[31] + _b[31] + _b[31] + _c[39] + _b[19] + _b[24] + _a[45] + _c[11] + _c[21] + _a[29] + _a[31] + _c[48] + _b[19] + _b[22] + _b[1] + _b[49] + _a[29] + _b[44] + _a[15] + _b[10] + _c[39] + _a[40] + _a[40] + _c[39] + _c[39];
pubkey += _a[25] + _a[49] + _a[45] + _c[34] + _b[30] + _a[43] + _b[3] + _b[28] + _c[53] + _c[61] + _a[39] + _b[28] + _c[61] + _a[49] + _b[62] + _b[9] + _c[56] + _b[60] + _a[15] + _c[0] + _b[48] + _c[14] + _a[50] + _b[48] + _b[48] + _b[59] + _c[5] + _b[15] + _b[48] + _c[56] + _c[53] + _b[19] + _c[1] + _a[6] + _b[44] + _c[0] + _b[33] + _c[14] + _c[56] + _b[48] + _a[28] + _b[35] + _b[43] + _a[1] + _a[23] + _b[33] + _b[33] + _a[23] + _c[42] + _c[44] + _a[13] + _b[35] + _c[53] + _a[16] + _b[47] + _b[60] + _a[51] + _a[24] + _b[24] + _c[1] + _a[47] + _a[56] + _b[53] + _c[54];
pubkey += _b[51] + _a[4] + _b[33] + _a[32] + _c[26] + _b[26] + _b[60] + _a[14] + _b[53] + _b[35] + _c[23] + _a[55] + _b[34] + _b[63] + _b[30] + _a[34] + _b[38] + _c[43] + _a[38] + _b[57] + _c[25] + _a[17] + _c[16] + _a[36] + _c[47] + _c[33] + _c[44] + _c[4] + _a[61] + _b[29] + _c[15] + _b[59] + _c[24] + _c[53] + _c[22] + _c[14] + _b[47] + _a[24] + _b[17] + _c[17] + _a[48] + _a[35] + _c[21] + _b[52] + _a[19] + _b[45] + _b[26] + _c[17] + _b[25] + _a[18] + _c[61] + _a[0] + _a[20] + _b[44] + _c[63] + _c[57] + _b[34] + _c[6] + _b[4] + _b[54] + _a[25] + _a[47] + _b[35] + _b[41];
pubkey += _a[24] + _c[60] + _b[14] + _c[42] + _b[14] + _b[52] + _a[13] + _c[35] + _c[62] + _c[58] + _c[57] + _c[27] + _c[44] + _b[23] + _b[25] + _c[10] + _a[28] + _b[21] + _a[38] + _a[32] + _c[16] + _b[35] + _b[12] + _c[35] + _c[18] + _b[24] + _c[57] + _a[12] + _b[39] + _a[7] + _b[23] + _a[43] + _a[41] + _c[42] + _c[7] + _b[16] + _c[26] + _b[37] + _c[41] + _a[7] + _a[53] + _c[27] + _b[30] + _b[42] + _a[17] + _c[6] + _b[47] + _b[57] + _c[13] + _b[45] + _a[33] + _b[62] + _a[0] + _b[21] + _b[4] + _b[11] + _a[7] + _a[44] + _b[61] + _c[7] + _c[35] + _c[3] + _a[25] + _c[63];
pubkey += _a[48] + _b[41] + _a[16] + _a[2] + _b[29] + _c[11] + _c[27] + _c[22] + _b[44] + _a[18] + _a[4] + _a[17] + _b[42] + _c[6] + _b[18] + _a[24] + _b[26] + _a[36] + _c[11] + _c[56] + _c[58] + _b[60] + _c[58] + _c[0];
pubkey += _b[31] + _a[40] + _a[40] + _c[39] + _b[31] + _b[24] + _b[15] + _c[56] + _a[29] + _c[20] + _b[17] + _b[19] + _b[22] + _c[11] + _b[49] + _a[29] + _a[8] + _a[15] + _a[12] + _c[39] + _c[39] + _a[40] + _b[31] + _a[40];
var encrypt = new JSEncrypt();
encrypt[_a[10] + _b[16] + _a[19] + _b[23] + _a[41] + _a[28] + _c[36] + _b[57] + _a[13] + _c[18] + _a[21] + _c[29]](pubkey);
return encrypt.encrypt(token);
}
/*
* 获取时间戳
*/
function get_time() {
var d = new Date();
var time = d.getTime() / 1000;
return parseInt(time);
}
找到了生成sign的函数,就好办了。
找到函数的依赖,需要md5和encrypt
3.安装环境,生成sign
cnpm install express // 提供接口
cnpm install md5 // md5
cnpm install node-jsencrypt // jsencrypt,普通版本的jsencrypt无法使用
启动express服务器
const express = require('express');
const getSign = require('./get_sign.js'); // 生成sign的函数
const app = express();
app.get('/get_sign', function (req, res) {
const s = new getSign();
const {page} = req.query;//获取page
let params = {
action: "ajax_load_posts",
append: "list_home",
paged: page * 1,
ts: s.get_time()
};
res.send({
data: s.get_sign(params)// 生成sign
})
});
app.listen(3000, () => {
console.log('server listen to 3000 port');
});
get_sign.js
const md5 = require('md5');
const JSEncrypt = require('node-jsencrypt');
const jsEncrypt = new JSEncrypt();
var window = {};
class GetSign {
makeSign(params) {
const _a = 'w&4915i708etp.rul6Um/afo2dyC=h:skng3bc';
const _b = 'wg0=&5C7U6rof:32e1asy48dkmbn/pcu.9lhit';
const _c = '&ced2hlmk8U3frstbiw5ay14/g07=C.un:p6o9';
var h = "www.todaybing.com";
var dm = "www.todaybing.com";
var ksort = Object.keys(params).sort();
if (h != dm) { // 不影响生成 sign
window.location.href = "https://www.todaybing.com";
}
var secret = md5("e10adc3949ba5903gfuwn43956e057f20f883e" + h);
var str = '';
for (var ki in ksort) {
str += ksort[ki] + "=" + params[ksort[ki]] + "&";
}
str += _c[14] + _b[16] + _c[1] + _a[14] + _c[2] + _a[11] + _a[28] + secret;
var token = md5(str).toUpperCase();
return this.rsa_sign(token);
}
get_time() { // 获取时间戳
var d = new Date();
var time = d.getTime() / 1000;
return parseInt(time);
}
rsa_sign(token) {
const _a = 'Z4DaR8QOKrsFYcdEjxTtSezVnM7Bb /P3Wv9wiXq-uLApGyJlIU+15Nm2HCh6f0g';
const _b = '6IZ09rhm 3YudOcNeUvBH8LPEp27GaM-Tg/flwtjyV+xKFXzACsnJD1RWiS4Q5bq';
const _c = 'Bi0jHG7sY rIa9QXh8KMPNz/64ec2ywFgbfxld3-+mVqpOJvU5TZ1CLtDEAWuSRn';
var pubkey = _a[40] + _b[31] + _b[31] + _b[31] + _c[39] + _b[19] + _b[24] + _a[45] + _c[11] + _c[21] + _a[29] + _a[31] + _c[48] + _b[19] + _b[22] + _b[1] + _b[49] + _a[29] + _b[44] + _a[15] + _b[10] + _c[39] + _a[40] + _a[40] + _c[39] + _c[39];
pubkey += _a[25] + _a[49] + _a[45] + _c[34] + _b[30] + _a[43] + _b[3] + _b[28] + _c[53] + _c[61] + _a[39] + _b[28] + _c[61] + _a[49] + _b[62] + _b[9] + _c[56] + _b[60] + _a[15] + _c[0] + _b[48] + _c[14] + _a[50] + _b[48] + _b[48] + _b[59] + _c[5] + _b[15] + _b[48] + _c[56] + _c[53] + _b[19] + _c[1] + _a[6] + _b[44] + _c[0] + _b[33] + _c[14] + _c[56] + _b[48] + _a[28] + _b[35] + _b[43] + _a[1] + _a[23] + _b[33] + _b[33] + _a[23] + _c[42] + _c[44] + _a[13] + _b[35] + _c[53] + _a[16] + _b[47] + _b[60] + _a[51] + _a[24] + _b[24] + _c[1] + _a[47] + _a[56] + _b[53] + _c[54];
pubkey += _b[51] + _a[4] + _b[33] + _a[32] + _c[26] + _b[26] + _b[60] + _a[14] + _b[53] + _b[35] + _c[23] + _a[55] + _b[34] + _b[63] + _b[30] + _a[34] + _b[38] + _c[43] + _a[38] + _b[57] + _c[25] + _a[17] + _c[16] + _a[36] + _c[47] + _c[33] + _c[44] + _c[4] + _a[61] + _b[29] + _c[15] + _b[59] + _c[24] + _c[53] + _c[22] + _c[14] + _b[47] + _a[24] + _b[17] + _c[17] + _a[48] + _a[35] + _c[21] + _b[52] + _a[19] + _b[45] + _b[26] + _c[17] + _b[25] + _a[18] + _c[61] + _a[0] + _a[20] + _b[44] + _c[63] + _c[57] + _b[34] + _c[6] + _b[4] + _b[54] + _a[25] + _a[47] + _b[35] + _b[41];
pubkey += _a[24] + _c[60] + _b[14] + _c[42] + _b[14] + _b[52] + _a[13] + _c[35] + _c[62] + _c[58] + _c[57] + _c[27] + _c[44] + _b[23] + _b[25] + _c[10] + _a[28] + _b[21] + _a[38] + _a[32] + _c[16] + _b[35] + _b[12] + _c[35] + _c[18] + _b[24] + _c[57] + _a[12] + _b[39] + _a[7] + _b[23] + _a[43] + _a[41] + _c[42] + _c[7] + _b[16] + _c[26] + _b[37] + _c[41] + _a[7] + _a[53] + _c[27] + _b[30] + _b[42] + _a[17] + _c[6] + _b[47] + _b[57] + _c[13] + _b[45] + _a[33] + _b[62] + _a[0] + _b[21] + _b[4] + _b[11] + _a[7] + _a[44] + _b[61] + _c[7] + _c[35] + _c[3] + _a[25] + _c[63];
pubkey += _a[48] + _b[41] + _a[16] + _a[2] + _b[29] + _c[11] + _c[27] + _c[22] + _b[44] + _a[18] + _a[4] + _a[17] + _b[42] + _c[6] + _b[18] + _a[24] + _b[26] + _a[36] + _c[11] + _c[56] + _c[58] + _b[60] + _c[58] + _c[0];
pubkey += _b[31] + _a[40] + _a[40] + _c[39] + _b[31] + _b[24] + _b[15] + _c[56] + _a[29] + _c[20] + _b[17] + _b[19] + _b[22] + _c[11] + _b[49] + _a[29] + _a[8] + _a[15] + _a[12] + _c[39] + _c[39] + _a[40] + _b[31] + _a[40];
jsEncrypt[_a[10] + _b[16] + _a[19] + _b[23] + _a[41] + _a[28] + _c[36] + _b[57] + _a[13] + _c[18] + _a[21] + _c[29]](pubkey);
return jsEncrypt.encrypt(token);
}
get_sign (data) {
data.ts = this.get_time();
data.sign = this.makeSign(data);
return data;
}
}
module.exports = GetSign;
评论列表
已有0条评论