==请帮忙点点赞,点个关注,谢谢!!==
官网地址:私募数据中心
本文发布的技术与代码仅供技术交流和学习使用,严禁用于数据采集等任何违法活动。请确保合法使用,并独立承担不当使用带来的法律责任。
一、逆向教程
1.我们先来看看返回的数据
点下一页,有个请求返回了数据,data应该是我们想要的数据是密文,其他的暂不知道有啥用就先不管了。那先开始找解密函数。
2.解密函数的定位
hook一段神秘代码。(有没有很熟悉,没错就是上期的那个神秘代码)
(function() {
var parse_ = JSON.parse;
JSON.parse = function(arg) {
console.log("断点----->", arg);
debugger;
return parse_(arg);
}})();
注入完,再点一下翻页。
有了,这hook到的是response返回的内容,没关系继续往下走等看到明文再说。
一不小心跟到明文了,没关系往回跟栈
ok了,传入明文,输出的密文。首尾打上断点,刷新网页(把hook刷没)
3.深入分析
这是个混淆过了的js代码,所以可读性很差,但是没关系,不影响分析。
3.1 参数key分析
发现之前打的首尾断点内的函数调用了key,所以补了一个key的断点,先来分析分析key
这个data[__Ox11208b[15]]值是不是很熟悉,响应中['data']['id']的值。
那么混淆前的代码应该是 "key = eval('window.' + data[id])"
3.1.1 eval()方法分析
再看看eval,找了半天没看到,再仔细回想一下响应里面有个参数是js代码
把他格式化出来看看,长下面这个样子。
var _0xc11e = ["", "split", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/", "slice", "indexOf", "", "", ".", "pow", "reduce", "reverse", "0"];
function _0xe85c(d, e, f) {
var g = _0xc11e[2][_0xc11e[1]](_0xc11e[0]);
var h = g[_0xc11e[3]](0, e);
var i = g[_0xc11e[3]](0, f);
var j = d[_0xc11e[1]](_0xc11e[0])[_0xc11e[10]]()[_0xc11e[9]](function(a, b, c) {
if (h[_0xc11e[4]](b) !== -1) return a += h[_0xc11e[4]](b) * (Math[_0xc11e[8]](e, c))
}, 0);
var k = _0xc11e[0];
while (j > 0) {
k = i[j % f] + k;
j = (j - (j % f)) / f
}
return k || _0xc11e[11]
}
eval(function(h, u, n, t, e, r) {
r = "";
for (var i = 0, len = h.length; i < len; i++) {
var s = "";
while (h[i] !== n[e]) {
s += h[i];
i++
}
for (var j = 0; j < n.length; j++) s = s.replace(new RegExp(n[j], "g"), j);
r += String.fromCharCode(_0xe85c(s, e, 10) - t)
}
return decodeURIComponent(escape(r))
}("jllDwgCgwgDgwgjgwgglwjllDwCjlwggjwCjDwCCgwCClwCCCwCjgwCjCwCDjwCCDwCDlwCDlwCjDwCCCwCCjwCClwCjgwCCDwCDlwCCjwCjDwCDjwCCjwCglwjDDwCCgwCCCwgCjwgClwgCjwjDDw",31,"ljCDgwzrY",9,5,24))
嗯....,eval()藏这里面了。那不管了先把代码拿下来运行一下看看。(报错:ReferenceError: window is not defined, 补一个window上去:global.window = global)
ok,对上了。
3.1.2 key的再赋值
那再往下走。有一个code判断和key的再赋值,太长了,不管了,直接给他拿下来。
code值是响应数据的endode值。弄完混淆前长这样。
key = code === 3 ? key['split']('')['reverse']()['join']('') : code === 4 ? key = key['slice'](2) : code === 5 ? key = key['slice'](0, key['length'] - 2) : code === 6 ? key = key['slice'](1, key['length'] - 1) : code === 7 ? key = key['slice'](2, key['length'] - 1) : code === 8 ? key = key['slice'](1, key['length'] - 2) : code === 9 ? key = key[0] + key['slice'](2, key['length']) : code === 10 && (key = key['slice'](0, key['length'] - 2) + key[key['length'] - 1])
ok,又对上了。那key值的还原就结束了。
3.2 data的解密
这标标准准的AES解密,就不用多说了吧,用CryptoJS库把混淆一个一个还原就行。
还原后长下面这样:
const CryptoJS = require("crypto-js")
e = CryptoJS.MD5(key).toString()
t = CryptoJS.enc.Utf8.parse(e)
r = CryptoJS.enc.Utf8.parse(e.slice(16,32))
s = window.atob(datas)
o = (CryptoJS.AES.decrypt(s, t, {
iv: r,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8))
运行一下出值了。
二、完整JS解密代码和python调用代码
1. 完整JS解密代码如下
global.window = global
const CryptoJS = require("crypto-js")
function main(h, u, n, t, e, r, code, id,data){
var _0xc6e = ["", "split", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/", "slice", "indexOf", "", "", ".", "pow", "reduce", "reverse", "0"];
function _0xe85c(d, e, f) {
var g = _0xc6e[2][_0xc6e[1]](_0xc6e[0]);
var h = g[_0xc6e[3]](0, e);
var i = g[_0xc6e[3]](0, f);
var j = d[_0xc6e[1]](_0xc6e[0])[_0xc6e[10]]()[_0xc6e[9]](function(a, b, c) {
if (h[_0xc6e[4]](b) !== -1) return a += h[_0xc6e[4]](b) * (Math[_0xc6e[8]](e, c))
}, 0);
var k = _0xc6e[0];
while (j > 0) {
k = i[j % f] + k;
j = (j - (j % f)) / f
}
return k || _0xc6e[11]
}
eval(function(h, u, n, t, e, r) {
r = "";
for (var i = 0, len = h.length; i < len; i++) {
var s = "";
while (h[i] !== n[e]) {
s += h[i];
i++
}
for (var j = 0; j < n.length; j++) s = s.replace(new RegExp(n[j], "g"), j);
r += String.fromCharCode(_0xe85c(s, e, 10) - t)
}
return decodeURIComponent(escape(r))
}(h, u, n, t, e, r))
key = eval("window." + id)
key = code === 3 ? key['split']('')['reverse']()['join']('') : code === 4 ? key = key['slice'](2) : code === 5 ? key = key['slice'](0, key['length'] - 2) : code === 6 ? key = key['slice'](1, key['length'] - 1) : code === 7 ? key = key['slice'](2, key['length'] - 1) : code === 8 ? key = key['slice'](1, key['length'] - 2) : code === 9 ? key = key[0] + key['slice'](2, key['length']) : code === 10 && (key = key['slice'](0, key['length'] - 2) + key[key['length'] - 1])
s = window.atob(data)
e = CryptoJS.MD5(key).toString()
t = CryptoJS.enc.Utf8.parse(e)
r = CryptoJS.enc.Utf8.parse(e.slice(16,32))
o = (CryptoJS.AES.decrypt(s, t, {
iv: r,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8))
return o
}
2. python调用代码如下
import json
import re
import execjs
import requests
def decodeData(h, u, n, t, e, r, code, id, data):
file = open('decode_data.js', mode='r', encoding='utf-8')
js = file.read()
file.close()
decData = execjs.compile(js)
dataJson = decUrlJs.call('main', h, u, n, t, e, r, code, id, data)
return json.loads(dataJson)
response = requests.get('请求自己写吧')
dataJson = response.json()
params_str = re.search(r'}\((.*?)\)\)', dataJson["data"]["key"], re.S).group(1)
h, u, n, t, e, r = params_str.replace("\"", '').split(",")
code = dataJson["data"]["encode"]
id = dataJson["data"]["id"]
encData = dataJson["data"]["data"]
print(decodeData(h, u, n, t, e, r, code, id, encData))
python运行结果如下:
三、声明
本文发布的技术与代码仅供技术交流和学习使用,严禁用于数据采集等任何违法活动。请确保合法使用,并独立承担不当使用带来的法律责任。
未经允许禁止转载
标签:教程,code,数据中心,解密,0xc11e,length,slice,key,var From: https://blog.csdn.net/m0_60082046/article/details/144750297