注意!!!!某XX网站逆向实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!!
案例--aHR0cDovLzExMS41Ni4xNDIuMTM6MTgwODgvc3Vic2lkeU9wZW4=
第一步:分析页面和请求方式
通过查看请求参数和响应内容,均为加密数据。最后的加密方式非AES和DES类型。本文主要分享案例中的sm4和sm3 加密
第二步:请求页面并分析请求
请求参数
headers 内容
响应内容
可以看出是均为密文
第三步:打断点逆向解析
在【search】里搜索 sign,通过观察关键信息得到以下即可(至于为啥能找到,自己悟吧,目前我能力有限无法用言语表达,全是命[一脸无奈]),可以看到headers 里加密的三个参数均能看到。sign, timestamp,source
第四步:分析加密方式
通过第三步,可以看到断点后重新请求,能够看出 e 和 t 很像参数,但不是很确定,可以先在控制台打印看一下。可以看出很像,但不确定,可以放置。将sign 生成的方法进行解析。可以看出 使用了s() 方法和 l()方法 ,注意s(t)返回的值要转成大写。
s()方法可以看出使用了sm3的加密方式
l() 方法可以看出使用sm4加密,同时可以看到有个 o 的参数,且参数为常量(别问我为啥,我也说不好,全凭感觉[一脸无奈]),注意注意d() 方法是sm4解密(别问,问就是自己想)
如果把上述代码扣下来会发现r.encrypt() 是个方法,且m() 也是个方法。把我所说的都扣下来基本就妥了。加密的过程就是这样。基本headers内加密参数就解决了
参数加密解析。sign 的断点页面,如下操作,堆栈那块选择上一步。就可以看到请求参数了。可以看到是 h()方法 ,正是一开始解析sign时 部分了。因此e的原本内容是 那一大串dict序列化的 内容(这部分请有缘人自己解析吧,基本复述上述步骤)
第五步:上代码
# -*- coding:utf-8 -*-
# @Time : 2024/3/16 17:39
# @Author: 水兵没月
# @File : XXX解析.py
# @Software: PyCharm
import execjs
from gmssl import sm4, sm3
# 读取JS文件
with open('./XX-解密.js', 'r', encoding='utf-8')as f:
files = f.readlines()
f.close()
files = ''.join(files)
ctx = execjs.compile(files)
# 国密 SM3加密
def sm3_hash(message: str):
"""
国密sm3加密
:param message: 消息值,bytes类型
:return: 哈希值
"""
msg_list = [i for i in bytes(message.encode('UTF-8'))]
hash_hex = sm3.sm3_hash(msg_list).upper()
return hash_hex
def sm4_jiami(t):
result = ctx.call('jiami', t)
return result
def sm4_jiemi(t):
result = ctx.call('jiemi', t)
return result
/* =====================
#@Time : 2024/3/16 17:44
#@Author: 水兵没月
#@File : XX-解密.py
#@Software: PyCharm
=======================*/
// &key=HD7232D2AAAKA@978D8723H211?IER&6
const e = 0
, r = 32
, i = 16
, o = [214, 144, 233, 254, 204, 225, 61, 183, 22, 182, 20, 194, 40, 251, 44, 5, 43, 103, 154, 118, 42, 190, 4, 195, 170, 68, 19, 38, 73, 134, 6, 153, 156, 66, 80, 244, 145, 239, 152, 122, 51, 84, 11, 67, 237, 207, 172, 98, 228, 179, 28, 169, 201, 8, 232, 149, 128, 223, 148, 250, 117, 143, 63, 166, 71, 7, 167, 252, 243, 115, 23, 186, 131, 89, 60, 25, 230, 133, 79, 168, 104, 107, 129, 178, 113, 100, 218, 139, 248, 235, 15, 75, 112, 86, 157, 53, 30, 36, 14, 94, 99, 88, 209, 162, 37, 34, 124, 59, 1, 33, 120, 135, 212, 0, 70, 87, 159, 211, 39, 82, 76, 54, 2, 231, 160, 196, 200, 158, 234, 191, 138, 210, 64, 199, 56, 181, 163, 247, 242, 206, 249, 97, 21, 161, 224, 174, 93, 164, 155, 52, 26, 85, 173, 147, 50, 48, 245, 140, 177, 227, 29, 246, 226, 46, 130, 102, 202, 96, 192, 41, 35, 171, 13, 83, 78, 111, 213, 219, 55, 69, 222, 253, 142, 47, 3, 255, 106, 114, 109, 108, 91, 81, 141, 27, 175, 146, 187, 221, 188, 127, 17, 217, 92, 65, 31, 16, 90, 216, 10, 193, 49, 136, 165, 205, 123, 189, 45, 116, 208, 18, 184, 229, 180, 176, 137, 105, 151, 74, 12, 150, 119, 126, 101, 185, 241, 9, 197, 110, 198, 132, 24, 240, 125, 236, 58, 220, 77, 32, 121, 238, 95, 62, 215, 203, 57, 72]
, a = [462357, 472066609, 943670861, 1415275113, 1886879365, 2358483617, 2830087869, 3301692121, 3773296373, 4228057617, 404694573, 876298825, 1347903077, 1819507329, 2291111581, 2762715833, 3234320085, 3705924337, 4177462797, 337322537, 808926789, 1280531041, 1752135293, 2223739545, 2695343797, 3166948049, 3638552301, 4110090761, 269950501, 741554753, 1213159005, 1684763257];
function s(t) {
const n = [];
for (let e = 0, r = t.length; e < r; e += 2)
n.push(parseInt(t.substr(e, 2), 16));
return n
}
function c(t) {
return t.map(t=>(t = t.toString(16),
1 === t.length ? "0" + t : t)).join("")
}
function u(t) {
const n = [];
for (let e = 0, r = t.length; e < r; e++) {
const r = t.codePointAt(e);
if (r <= 127)
n.push(r);
else if (r <= 2047)
n.push(192 | r >>> 6),
n.push(128 | 63 & r);
else if (r <= 55295 || r >= 57344 && r <= 65535)
n.push(224 | r >>> 12),
n.push(128 | r >>> 6 & 63),
n.push(128 | 63 & r);
else {
if (!(r >= 65536 && r <= 1114111))
throw n.push(r),
new Error("input is not supported");
e++,
n.push(240 | r >>> 18 & 28),
n.push(128 | r >>> 12 & 63),
n.push(128 | r >>> 6 & 63),
n.push(128 | 63 & r)
}
}
return n
}
function g(t, n, r) {
const i = new Array(4)
, o = new Array(4);
for (let e = 0; e < 4; e++)
o[0] = 255 & t[0 + 4 * e],
o[1] = 255 & t[1 + 4 * e],
o[2] = 255 & t[2 + 4 * e],
o[3] = 255 & t[3 + 4 * e],
i[e] = o[0] << 24 | o[1] << 16 | o[2] << 8 | o[3];
i[0] ^= 2746333894,
i[1] ^= 1453994832,
i[2] ^= 1736282519,
i[3] ^= 2993693404;
for (let e, s = 0; s < 32; s += 4)
e = i[1] ^ i[2] ^ i[3] ^ a[s + 0],
n[s + 0] = i[0] ^= d(h(e)),
e = i[2] ^ i[3] ^ i[0] ^ a[s + 1],
n[s + 1] = i[1] ^= d(h(e)),
e = i[3] ^ i[0] ^ i[1] ^ a[s + 2],
n[s + 2] = i[2] ^= d(h(e)),
e = i[0] ^ i[1] ^ i[2] ^ a[s + 3],
n[s + 3] = i[3] ^= d(h(e));
if (r === e)
for (let e, a = 0; a < 16; a++)
e = n[a],
n[a] = n[31 - a],
n[31 - a] = e
}
function v(t, n, e) {
const r = new Array(4)
, i = new Array(4);
for (let o = 0; o < 4; o++)
i[0] = 255 & t[4 * o],
i[1] = 255 & t[4 * o + 1],
i[2] = 255 & t[4 * o + 2],
i[3] = 255 & t[4 * o + 3],
r[o] = i[0] << 24 | i[1] << 16 | i[2] << 8 | i[3];
for (let o, a = 0; a < 32; a += 4)
o = r[1] ^ r[2] ^ r[3] ^ e[a + 0],
r[0] ^= p(h(o)),
o = r[2] ^ r[3] ^ r[0] ^ e[a + 1],
r[1] ^= p(h(o)),
o = r[3] ^ r[0] ^ r[1] ^ e[a + 2],
r[2] ^= p(h(o)),
o = r[0] ^ r[1] ^ r[2] ^ e[a + 3],
r[3] ^= p(h(o));
for (let o = 0; o < 16; o += 4)
n[o] = r[3 - o / 4] >>> 24 & 255,
n[o + 1] = r[3 - o / 4] >>> 16 & 255,
n[o + 2] = r[3 - o / 4] >>> 8 & 255,
n[o + 3] = 255 & r[3 - o / 4]
}
function d(t) {
return t ^ l(t, 13) ^ l(t, 23)
}
function p(t) {
return t ^ l(t, 2) ^ l(t, 10) ^ l(t, 18) ^ l(t, 24)
}
function h(t) {
return (255 & o[t >>> 24 & 255]) << 24 | (255 & o[t >>> 16 & 255]) << 16 | (255 & o[t >>> 8 & 255]) << 8 | 255 & o[255 & t]
}
function l(t, n) {
const e = 31 & n;
return t << e | t >>> 32 - e
}
function f(t) {
const n = [];
for (let e = 0, r = t.length; e < r; e++)
t[e] >= 240 && t[e] <= 247 ? (n.push(String.fromCodePoint(((7 & t[e]) << 18) + ((63 & t[e + 1]) << 12) + ((63 & t[e + 2]) << 6) + (63 & t[e + 3]))),
e += 3) : t[e] >= 224 && t[e] <= 239 ? (n.push(String.fromCodePoint(((15 & t[e]) << 12) + ((63 & t[e + 1]) << 6) + (63 & t[e + 2]))),
e += 2) : t[e] >= 192 && t[e] <= 223 ? (n.push(String.fromCodePoint(((31 & t[e]) << 6) + (63 & t[e + 1]))),
e++) : n.push(String.fromCodePoint(t[e]));
return n.join("")
}
function m(t, n, o, {padding: a="pkcs#7", mode: l, iv: h=[], output: p="string"}={}) {
if ("cbc" === l && ("string" === typeof h && (h = s(h)),
16 !== h.length))
throw new Error("iv is invalid");
if ("string" === typeof n && (n = s(n)),
16 !== n.length)
throw new Error("key is invalid");
if (t = "string" === typeof t ? o !== e ? u(t) : s(t) : [...t],
("pkcs#5" === a || "pkcs#7" === a) && o !== e) {
const n = i - t.length % i;
for (let e = 0; e < n; e++)
t.push(n)
}
const d = new Array(r);
g(n, d, o);
const m = [];
let b = h
, y = t.length
, _ = 0;
while (y >= i) {
const n = t.slice(_, _ + 16)
, r = new Array(16);
if ("cbc" === l)
for (let t = 0; t < i; t++)
o !== e && (n[t] ^= b[t]);
v(n, r, d);
for (let t = 0; t < i; t++)
"cbc" === l && o === e && (r[t] ^= b[t]),
m[_ + t] = r[t];
"cbc" === l && (b = o !== e ? r : n),
y -= i,
_ += i
}
if (("pkcs#5" === a || "pkcs#7" === a) && o === e) {
const t = m.length
, n = m[t - 1];
for (let e = 1; e <= n; e++)
if (m[t - e] !== n)
throw new Error("padding is invalid");
m.splice(t - n, n)
}
return "array" !== p ? o !== e ? c(m) : f(m) : m
}
function jiami(t){
var n = '30062AFC48C0E7B5B0918851C0445A37'
var e1 = 0
data = m(t, n, 1, e1)
return data
}
function jiemi(t){
var n = '30062AFC48C0E7B5B0918851C0445A37'
var e1 = undefined
data = m(t, n, 0, e1)
return data
}
仅作为笔记记录,如有问题请各位大佬来指导