【2020-12-23】JS逆向之某線上監測分析平臺
宣告:本文只作學習研究,禁止用於非法用途,否則後果自負,如有侵權,請告知刪除,謝謝!
前言
目標網站:aHR0cHM6Ly93d3cuYXFpc3R1ZHkuY24v
反爬型別:無限debugger、禁止F12除錯
加密型別:JS混淆、AES、DES、BASE64
一、頁面分析
1.1 解決無限debugger
進入網頁按F12,出現下圖
解決辦法:在行數旁邊點選右鍵,點選紅框內容,輸入false,點選執行即可
1.2 解決禁止除錯
解決無限debugger後,又不給除錯了,如下圖,咋解決呢??
解決辦法:主要是下面兩個函式在搞事情熬,用fiddler中間人改寫,咋改寫自己去搜吧,這裡就不描述了
弄好之後就可以除錯了!!
二、加密解密破解
獲取如下資料
加密引數是請求時傳入的引數
解密引數就是響應的資料
2.1 請求引數數破解
直接下XHR斷點,找到請求引數的加密位置,這個檔案的JS是https://www.aqistudy.cn/js/encrypt_eZMqs7H0RJRS.min.js?t=1603351502
,扣下來放本地可以除錯用
這裡的加密方法是pNg63WJXHfm8r
,可以在扣下的JS程式碼裡看出主要的加密方式MD5和BASE64,這裡就不用原始碼的加密方式了,直接用CryptoJS
加密包
原始碼的加密函式都在這個混淆的JS裡面
改寫好程式碼後就可以破解請求引數的加密方式了,應為裡面的時間戳不一樣,所以有部分差異,用來發請求是完全沒問題的
2.2 返回引數解密
解密的函式位置在這裡,也在之前扣下來的JS函式裡
裡面是這幾個加密方法
自己用加密包改寫一下就可以實現解密了
三、JS原始碼
var CryptoJS = require('crypto-js');
const askCju6cmMLz = "apAteRdhDd5i5n74";
const asieXomd2dAl = "bN8izWwuwRjjA0pH";
const ackWpSYGqWDU = "dOzNkylRKkmvJ8WP";
const aciPXJAqV8bc = "fS6yu6Kz72UWOqLm";
const dskq6mV934LL = "hY8XWvmotJ7yhyBV";
const dsi68kk2Mig9 = "xCYtuanHBbJFWlKg";
const dckmQMBceyd6 = "ougX3aSyswLitv49";
const dciNka5Pmv4x = "pebJx2rKU7WTkBP6";
const aes_local_key = 'emhlbnFpcGFsbWtleQ==';
const aes_local_iv = 'emhlbnFpcGFsbWl2';
var BASE64 = {
encrypt: function (text) {
// var b = new Base64();
// return b.encode(text)
var wordArray = CryptoJS.enc.Utf8.parse(text);
return CryptoJS.enc.Base64.stringify(wordArray)
}, decrypt: function (text) {
// var b = new Base64();
// return b.decode(text)
var parsedWordArray = CryptoJS.enc.Base64.parse(text);
return parsedWordArray.toString(CryptoJS.enc.Utf8)
}
};
var DES = {
encrypt: function (text, key, iv) {
var secretkey = (CryptoJS.MD5(key).toString()).substr(0, 16);
var secretiv = (CryptoJS.MD5(iv).toString()).substr(24, 8);
secretkey = CryptoJS.enc.Utf8.parse(secretkey);
secretiv = CryptoJS.enc.Utf8.parse(secretiv);
var result = CryptoJS.DES.encrypt(text, secretkey, {
iv: secretiv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return result.toString()
}, decrypt: function (text, key, iv) {
var secretkey = (CryptoJS.MD5(key).toString()).substr(0, 16);
var secretiv = (CryptoJS.MD5(iv).toString()).substr(24, 8);
secretkey = CryptoJS.enc.Utf8.parse(secretkey);
secretiv = CryptoJS.enc.Utf8.parse(secretiv);
var result = CryptoJS.DES.decrypt(text, secretkey, {
iv: secretiv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return result.toString(CryptoJS.enc.Utf8)
}
};
var AES = {
encrypt: function (text, key, iv) {
var secretkey = (CryptoJS.MD5(key).toString()).substr(16, 16);
var secretiv = (CryptoJS.MD5(iv).toString()).substr(0, 16);
secretkey = CryptoJS.enc.Utf8.parse(secretkey);
secretiv = CryptoJS.enc.Utf8.parse(secretiv);
var result = CryptoJS.AES.encrypt(text, secretkey, {
iv: secretiv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return result.toString()
}, decrypt: function (text, key, iv) {
var secretkey = (CryptoJS.MD5(key).toString()).substr(16, 16);
var secretiv = (CryptoJS.MD5(iv).toString()).substr(0, 16);
secretkey = CryptoJS.enc.Utf8.parse(secretkey);
secretiv = CryptoJS.enc.Utf8.parse(secretiv);
var result = CryptoJS.AES.decrypt(text, secretkey, {
iv: secretiv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return result.toString(CryptoJS.enc.Utf8)
}
};
var localStorageUtil = {
save: function (name, value) {
var text = JSON.stringify(value);
text = BASE64.encrypt(text);
text = AES.encrypt(text, aes_local_key, aes_local_iv);
try {
localStorage.setItem(name, text)
} catch (oException) {
if (oException.name === 'QuotaExceededError') {
console.log('超出本地儲存限額!');
localStorage.clear();
localStorage.setItem(name, text)
}
}
}, check: function (name) {
return localStorage.getItem(name)
}, getValue: function (name) {
var text = localStorage.getItem(name);
var result = null;
if (text) {
text = AES.decrypt(text, aes_local_key, aes_local_iv);
text = BASE64.decrypt(text);
result = JSON.parse(text)
}
return result
}, remove: function (name) {
localStorage.removeItem(name)
}
};
function getDataFromLocalStorage(key, period) {
if (typeof period === 'undefined') {
period = 0
}
var d = DES.encrypt(key);
d = BASE64.encrypt(key);
var data = localStorageUtil.getValue(key);
if (data) {
const time = data.time;
const current = new Date().getTime();
if (new Date().getHours() >= 0 && new Date().getHours() < 5 && period > 1) {
period = 1
}
if (current - (period * 60 * 60 * 1000) > time) {
data = null
}
if (new Date().getHours() >= 5 && new Date(time).getDate() !== new Date().getDate() && period === 24) {
data = null
}
}
return data
}
function ObjectSort(obj) {
var newObject = {};
Object.keys(obj).sort().map(function (key) {
newObject[key] = obj[key]
});
return newObject
}
function dX506x9jVK3vuMMhoz6ZXx(data) {
data = AES.decrypt(data, askCju6cmMLz, asieXomd2dAl);
data = DES.decrypt(data, dskq6mV934LL, dsi68kk2Mig9);
data = BASE64.decrypt(data);
return data
}
var pNg63WJXHfm8r = (function () {
function ObjectSort(obj) {
var newObject = {};
Object.keys(obj).sort().map(function (key) {
newObject[key] = obj[key]
});
return newObject
}
return function (method, obj) {
var appId = 'baec98a73c1bff796603cb2fa9d6d449';
var clienttype = 'WEB';
var timestamp = new Date().getTime();
var param = {
appId: appId,
method: method,
timestamp: timestamp,
clienttype: clienttype,
object: obj,
// secret: hex_md5(appId + method + timestamp + clienttype + JSON.stringify(ObjectSort(obj)))
secret: CryptoJS.MD5(appId + method + timestamp + clienttype + JSON.stringify(ObjectSort(obj))).toString()
};
param = BASE64.encrypt(JSON.stringify(param));
return param
}
})();
function sJwf3VwkSgqmf0Ddr92K(method, object, callback, period) {
const key = hex_md5(method + JSON.stringify(object));
const data = getDataFromLocalStorage(key, period);
if (!data) {
var param = pNg63WJXHfm8r(method, object);
$.ajax({
url: '../apinew/aqistudyapi.php', data: {h0lgYxgR3: param}, type: "post", success: function (data) {
data = dX506x9jVK3vuMMhoz6ZXx(data);
obj = JSON.parse(data);
if (obj.success) {
if (period > 0) {
obj.result.time = new Date().getTime();
localStorageUtil.save(key, obj.result)
}
callback(obj.result)
} else {
console.log(obj.errcode, obj.errmsg)
}
}
})
} else {
callback(data)
}
}
相關文章
- 【JS 逆向百例】某空氣質量監測平臺無限 debugger 以及資料動態加密JS加密
- js逆向實戰之某資料平臺響應數解密邏輯JS解密
- 高耗能工廠能耗分析系統開發方案,線上監測平臺搭建
- js逆向實戰之某市場監管公告服務平臺返回資料解密JS解密
- 【JS逆向百例】某點資料逆向分析,多方法詳解JS
- 工廠園區能耗監測系統開發方案,線上監測平臺搭建
- python爬蟲之JS逆向某易雲音樂Python爬蟲JS
- 重點高耗能企業能耗監測管理系統開發,線上監測平臺搭建
- Python爬蟲之JS逆向分析技巧Python爬蟲JS
- 能源能源管控系統開發方案,線上監測平臺搭建
- 大型企業能源管理監控系統開發,線上監測平臺搭建方案
- 體育線上平臺 - 體之美
- 【JS逆向百例】東某航空數美指紋 v4 裝置 ID 逆向分析JS
- 智慧工廠能源管理系統開發方案,線上監測平臺搭建
- js逆向實戰之某網遊登入引數password加密JS加密
- js逆向實戰之某樂網登入引數pwd加密JS加密
- 【JS逆向百例】cebupacificair 航空逆向分析JSAI
- 智慧園區工廠能源管控平臺搭建,線上監測系統開發
- 重工業能源管控系統開發解決方案,線上監測平臺搭建
- 智慧工廠能源管控中心繫統開發方案,線上監測平臺搭建
- 工廠園區能源管控系統開發方案,線上監測平臺搭建
- 智慧工廠能耗線上監測平臺建設能源管理系統開發
- js逆向實戰之某證信Accept-Enckey引數加密解析JS加密
- 【JS 逆向百例】如何跟棧除錯?某 e 網通 AES 加密分析JS除錯加密
- 【小程式逆向專欄】某潤選房小程式逆向分析
- 【驗證碼逆向專欄】某多多驗證碼逆向分析
- 1.某道翻譯js逆向sign值JS
- js逆向) 某音cookie中的__ac_signatureJSCookie
- 能耗線上管理平臺搭建能源監控系統開發
- 重點高耗能企業能源管控平臺搭建,線上監測系統開發
- 能耗線上監測系統系統開發方案,工廠能耗管理平臺開發
- 線上監測系統開發,智慧工廠能源管控平臺搭建解決方案
- js逆向爬蟲實戰(2)--快手第三方平臺之加密引數JS爬蟲加密
- 智慧工廠園區能耗綜合管控系統開發,線上監測平臺搭建
- 【JS 逆向百例】Fiddler 外掛 Hook 實戰,某創幫登入逆向JSHook
- DIY一個前端監控平臺(上)前端
- 【JS 逆向百例】網洛者反爬練習平臺第六題:JS 加密,環境模擬檢測JS加密
- python爬蟲之JS逆向Python爬蟲JS