网站建设和域名什么关系,牛年起广告公司名字,河北省建设执业资格中心网站,wordpress网页特效一、数据接口分析
主页地址#xff1a;某鸟记录中心
1、抓包
通过抓包可以发现数据接口是front/record/search/page
2、判断是否有加密参数
请求参数是否加密#xff1f; 通过查看“载荷”模块可以发现#xff0c;请求参数是加密的 请求头是否加密#xff1f; 通过查…一、数据接口分析
主页地址某鸟记录中心
1、抓包
通过抓包可以发现数据接口是front/record/search/page
2、判断是否有加密参数
请求参数是否加密 通过查看“载荷”模块可以发现请求参数是加密的 请求头是否加密 通过查看“请求标头”可以发现Requestid和Sign是加密参数并且有一个Timestamp时间戳 响应是否加密 通过查看“响应”模块可以发现响应中的数据是加密数据 cookie是否加密 无
二、加密位置定位
1、加密参数以及请求头加密
1看启动器
查看启动器发现里面有一个pullData的调用堆栈点进去查看 点进去后可以看出此处是发送ajax请求的位置在此处下断点再次翻页获取数据发现可以断住但是此处是明文数据所以加密位置不在这里。
2搜索关键字
因为“载荷”是一整个密文没有关键字所以无法搜索
3hook
因为“载荷”是一整个密文所以网站大概率会使用JSON.stringify将数据转换为json字符串再进行加密所以我们可以hookJSON.stringifyhook代码
var my_stringify JSON.stringify;
JSON.stringify function (params) {debuggerconsole.log(json_stringify params:,params);return my_stringify(params);
};运行hook代码再次获取数据发现可以断住 继续调试执行可以发现网站是使用ajaxSetup设置了ajax请求的全局配置请求头和加密参数都是在此处进行赋值的。
2、响应数据
1hook
因为响应加密数据一般都是json数据加密所以解密后会使用JSON.parse进行解密所以我们可以对JSON.parse进行hook hook代码段
var my_parse JSON.parse;
JSON.parse function (params) {debuggerconsole.log(json_parse params:,params);return my_parse(params);
};运行hook代码再次获取数据发现可以断住明文 接着调试执行就可以找到解密位置
三、扣js代码
1、加密参数及请求头
将定位到的加密位置的代码扣出可以发现网站的数据加密是使用的JSEncrypt模块进行的RAS加密所以我们可以直接使用标准模块进行加密但是网站使用的encrypt.encryptUnicodeLong方法node.js中是没有的所以我们还需要将这个方法扣出来。下方请求头加密使用的md5我们同样可以使用标准模块进行加密。
2、响应数据
将定位到的解密位置的代码扣出进入到网站的解密方法BIRDREPORT_APIJS.decode中可以发现网站是使用的AES解密的所以我们可以使用标准的AES模块进行解密。 JavaScript源码
const JSEncrypt require(jsencrypt);var b64map ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/;
var b64pad ;function hex2b64(h) {var i;var c;var ret ;for (i 0; i 3 h.length; i 3) {c parseInt(h.substring(i, i 3), 16);ret b64map.charAt(c 6) b64map.charAt(c 63);}if (i 1 h.length) {c parseInt(h.substring(i, i 1), 16);ret b64map.charAt(c 2);} else if (i 2 h.length) {c parseInt(h.substring(i, i 2), 16);ret b64map.charAt(c 2) b64map.charAt((c 3) 4);}while ((ret.length 3) 0) {ret b64pad;}return ret;
}JSEncrypt.prototype.encryptUnicodeLong function (string) {var k this.getKey();//根据key所能编码的最大长度来定分段长度。key size - 1111字节随机padding使每次加密结果都不同。var maxLength ((k.n.bitLength() 7) 3) - 11;var subStr , encryptedString ;var subStart 0, subEnd 0;var bitLen 0, tmpPoint 0;for (var i 0, len string.length; i len; i) {//js 是使用 Unicode 编码的每个字符所占用的字节数不同var charCode string.charCodeAt(i);if (charCode 0x007f) {bitLen 1;} else if (charCode 0x07ff) {bitLen 2;} else if (charCode 0xffff) {bitLen 3;} else {bitLen 4;}//字节数到达上限获取子字符串加密并追加到总字符串后。更新下一个字符串起始位置及字节计算。if (bitLen maxLength) {subStr string.substring(subStart, subEnd)encryptedString k.encrypt(subStr);subStart subEnd;bitLen bitLen - tmpPoint;} else {subEnd i;tmpPoint bitLen;}}subStr string.substring(subStart, len)encryptedString k.encrypt(subStr);return hex2b64(encryptedString);
};const CryptoJS require(crypto-js)function getUuid() {var s [];var a 0123456789abcdef;for (var i 0; i 32; i) {s[i] a.substr(Math.floor(Math.random() * 0x10), 1)}s[14] 4;s[19] a.substr((s[19] 0x3) | 0x8, 1);s[8] s[13] s[18] s[23];var b s.join();return b
}function sort_ASCII(a) {var b new Array();var c 0;for (var i in a) {b[c] i;c}var d b.sort();var e {};for (var i in d) {e[d[i]] a[d[i]]}return e
}function url2json(a) {var b /^[^\?]\?([\w\W])$/, reg_para /([^])([\w\W]*?)(|$|#)/g, arr_url b.exec(a), ret {};if (arr_url arr_url[1]) {var c arr_url[1], result;while ((result reg_para.exec(c)) ! null) {ret[result[1]] result[2]}}return ret
}function dataTojson(a) {var b [];var c {};b a.split();for (var i 0; i b.length; i) {if (b[i].indexOf() ! -1) {var d b[i].split();if (d.length 2) {c[d[0]] d[1]} else {c[d[0]] }} else {c[b[i]] }}return c
}const serialize function (a) {var b [];for (var p in a)if (a.hasOwnProperty(p) a[p]) {b.push(encodeURIComponent(p) encodeURIComponent(a[p]))}return b.join()
};
var paramPublicKey MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvxXa98E1uWXnBzXkS2yHUfnBM6n3PCwLdfIox03T91joBvjtoDqiQ5x3tTOfpHs3LtiqMMEafls6b0YWtgB1dse1W5mFpeusVkCOkQxB4SZDH6tuerIknnmB/Hsq5wgEkIvO5Pff9biig6AyoAkdWpSek/1/B7zYIepYY0lxKQIDAQAB;
var encrypt new JSEncrypt();
encrypt.setPublicKey(paramPublicKey);function get_params() {var b_data page1limit20taxonidstartTimeendTimeprovincecitydistrictpointname%E6%B2%B3%E5%8D%97usernameserial_idctimetaxonnamestatemode0outside_type0var c Date.parse(new Date());var d getUuid();var e JSON.stringify(sort_ASCII(dataTojson(b_data || {})));b_data encrypt.encryptUnicodeLong(e);var f CryptoJS.MD5(e d c).toString();return [{timestamp: c.toString(),requestId: d.toString(),sign: f.toString()}, b_data]
}var key 3583ec0257e2f4c8195eec7410ff1619;
var iv d93c0d5ec6352f20
apijs_decode function(a) {var b CryptoJS.enc.Utf8.parse(key);var c CryptoJS.enc.Utf8.parse(iv);var d CryptoJS.AES.decrypt(a, b, {iv: c,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});return d.toString(CryptoJS.enc.Utf8)}function get_data(r_data) {var decode_str apijs_decode(r_data);return JSON.parse(decode_str)
}