微信小程序代運(yùn)營(yíng)長(zhǎng)沙排名優(yōu)化公司
一、數(shù)據(jù)接口分析
主頁(yè)地址:某礦
1、抓包
通過(guò)抓包可以發(fā)現(xiàn)數(shù)據(jù)接口是cgxj/by-lx-page
2、判斷是否有加密參數(shù)
- 請(qǐng)求參數(shù)是否加密?
通過(guò)查看“載荷”模塊可以發(fā)現(xiàn)有一個(gè)param
的加密參數(shù)
- 請(qǐng)求頭是否加密?
無(wú) - 響應(yīng)是否加密?
無(wú) - cookie是否加密?
無(wú)
二、加密位置定位
1、看啟動(dòng)器
查看啟動(dòng)器發(fā)現(xiàn)里面有一個(gè)index.js中的匿名調(diào)用堆棧,點(diǎn)進(jìn)去查看
點(diǎn)進(jìn)去后發(fā)現(xiàn),網(wǎng)站確實(shí)是在此處發(fā)送的請(qǐng)求,而且參數(shù)param
也是在此處賦值。但是param
的值來(lái)自于A.sent
,此處找不到A.sent
賦值的位置,所以此處只是發(fā)包位置,并不是加密位置。
2、搜索關(guān)鍵字
通過(guò)搜索sent
相關(guān)的關(guān)鍵字,不能有效的定位到加密位置
3、hook
因?yàn)檎?qǐng)求參數(shù)中只有一個(gè)param
密文參數(shù),所以網(wǎng)站大概率會(huì)使用JSON.stringify
將數(shù)據(jù)轉(zhuǎn)換為json字符串再進(jìn)行加密,所以我們可以hookJSON.stringify
,hook代碼:
var my_stringify = JSON.stringify;
JSON.stringify = function (params) {debuggerconsole.log("json_stringify params:",params);return my_stringify(params);
};
運(yùn)行hook代碼,再次獲取數(shù)據(jù),發(fā)現(xiàn)可以斷住
接著調(diào)試執(zhí)行,就可以發(fā)現(xiàn)加密位置
但是,此時(shí)我們并不能確定此處的加密結(jié)果是否就是發(fā)包時(shí)使用的A.sent
,所以我們可以在發(fā)包位置再打上斷點(diǎn),并將此處斷點(diǎn)放開(kāi),通過(guò)對(duì)比,我們可以發(fā)現(xiàn),此處的加密結(jié)果就是發(fā)包時(shí)使用的。
三、扣js代碼
將加密位置的代碼扣出,缺啥補(bǔ)啥即可。
注意,加密時(shí)使用的RSA加密以及md5加密,均可使用標(biāo)準(zhǔn)模塊,但是RSA加密時(shí),要補(bǔ)一下網(wǎng)站的encryptLong
方法,同時(shí)RSA加密所使用的公鑰,通過(guò)觀察發(fā)包可以看出,網(wǎng)站每次獲取數(shù)據(jù)前,都會(huì)先發(fā)一個(gè)包獲取公鑰。
所以先請(qǐng)求public接口獲取到公鑰,再進(jìn)行加密即可。
JavaScript源碼:
const JSEncrypt = require('jsencrypt');
const CryptoJS = require("crypto-js");function w(A) {var e, t, n = "", r = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", a = "=";for (e = 0; e + 3 <= A.length; e += 3)t = parseInt(A.substring(e, e + 3), 16),n += r.charAt(t >> 6) + r.charAt(63 & t);e + 1 == A.length ? (t = parseInt(A.substring(e, e + 1), 16),n += r.charAt(t << 2)) : e + 2 == A.length && (t = parseInt(A.substring(e, e + 2), 16),n += r.charAt(t >> 2) + r.charAt((3 & t) << 4));while ((3 & n.length) > 0)n += a;return n
}JSEncrypt.prototype.encryptLong = function (A) {var e = this.getKey(), t = (e.n.bitLength() + 7 >> 3) - 11;var n = "", r = "";if (A.length > t)return n = A.match(/.{1,50}/g),n.forEach((function (A) {var t = e.encrypt(A);r += t})),w(r);var a = e.encrypt(A), s = w(a);return s
}function b(A, e, t) {return e in A ? Object.defineProperty(A, e, {value: t,enumerable: !0,configurable: !0,writable: !0}) : A[e] = t,A
}function d(A, e) {var t = Object.keys(A);if (Object.getOwnPropertySymbols) {var n = Object.getOwnPropertySymbols(A);e && (n = n.filter((function (e) {return Object.getOwnPropertyDescriptor(A, e).enumerable}))),t.push.apply(t, n)}return t
}function m(A) {for (var e = 1; e < arguments.length; e++) {var t = null != arguments[e] ? arguments[e] : {};e % 2 ? d(Object(t), !0).forEach((function (e) {b(A, e, t[e])})) : Object.getOwnPropertyDescriptors ? Object.defineProperties(A, Object.getOwnPropertyDescriptors(t)) : d(Object(t)).forEach((function (e) {Object.defineProperty(A, e, Object.getOwnPropertyDescriptor(t, e))}))}return A
}function get_param(pub_key) {var e = {"inviteMethod": "","businessClassfication": "","mc": "","lx": "CGGG","dwmc": "","pageIndex": 1}var t = new JSEncrypt();t.setPublicKey(pub_key)a = m(m({}, e), {}, {sign: CryptoJS.MD5(JSON.stringify(e)).toString(),timeStamp: +new Date})return t.encryptLong(JSON.stringify(a))
}