目录
一、目标网址:
base64加密:aHR0cHM6Ly9vcGVuLm9wcG9tb2JpbGUuY29tL25ldy9sb2dpbkZvckhleVRhcA==
二、图片还原算法
/*! captcha.js v1.3.41(541) 2022-10-12 09:47:18 b9f46c49ba89f57da6d701302bd8b968a81d6c87 prod */
const canvas = require("canvas");
let _e;
let $tsukuyomi_array_10417 = {}
let $tsukuyomi_var_1989 = 'h';
(function (t) {
var s = {}
, i = {
"index": 0
};
function _(r) {
console.log(r)
if (s[r])
return s[r].exports;
var u = s[r] = {
"i": r,
"l": !1,
"exports": {}
};
return t[r].call(u.exports, u, u.exports, _),
u.l = !0,
u.exports
}
_e = _
})({
"w4qZ": function (i, a, t) {
var r = "canv"
, e = "le"
, n = t("HUnT");
var o = t("tY/s");
function c(i) {
if (!i)
return "";
for (var a = "", t = "V587", r = 17542, e = 0; e < i.length; e++) {
var n = i.charCodeAt(e);
r = (r + 1) % t.length,
n ^= t.charCodeAt(r),
a += String.fromCharCode(n)
}
return a
}
var s = t("SxjO");
function d(i) {
if (!i)
return "";
for (var a = "", t = 36997, r = 0; r < i.length; r++) {
var e = i.charCodeAt(r)
, n = e ^ t;
t = e,
a += String.fromCharCode(n)
}
return a
}
function l(i, a, t, r, o) {
var c = i.getContext("2d");
c.drawImage(a, 0, 0, t, r);
var s = Math.floor(t / o.length);
n(o, function (i, t) {
var n = i * s
, d = s;
o[e + "ngth"],
c[function (i) {
if (!i)
return "";
for (var a = "", t = 83083, r = 0; r < i.length; r++) {
var e = i.charCodeAt(r) ^ t;
t = t * r % 256 + 2333,
a += String.fromCharCode(e)
}
return a
}("\u44ef\u096f\u095b\u09e6\u0999\u0930\u098f\u09d6\u0991")](a, n, 0, d, r, t * s, 0, d, r)
})
return i.toDataURL()
}
i.exports = l
},
"HUnT": function (t, r) {
t.exports = function (t, r) {
for (var u = 0, e = t["lengt" + $tsukuyomi_var_1989], o = []; u < e; u++)
o[u] = r(t[u], u);
return o
}
},
"tY/s": function (t, r) {
t[$tsukuyomi_array_10417[51]] = function (t) {
return new RegExp("\\.(png|jpg|jpeg|webp)$", $tsukuyomi_decryptor_encryptor1("^")).test(t)
}
},
"SxjO": function (t, r, u) {
var e = u("WWgC");
t.exports = function () {
for (var t = arguments.length, r = new Array(t), u = 0; u < t; u++)
r[u] = arguments[u];
console[$tsukuyomi_array_10419[71]](r.join(" ")),
_dx.inSDK && r.length && e(r, function (t) {
window.console && window.console.log(t)
})
}
},
// 还原图片的
"WWgC": function (t, r) {
t.exports = function (t, r) {
for (var u = 0, e = t.length; u < e; u++)
r(t[u])
}
},
// 根据乱码图片url获取相关的加密值
"g0jM": function (i, a, t) {
var r = t("HUnT");
i.exports = function (i) {
var a;
if (!i)
return "";
a = i.split("?")[1].split("&");
var t = [0, 0];
return r(a, function (i) {
var a = i.split("=");
i && a[0] === "c".split("").reverse().join("") && a[1] && "null" !== a[1] ? t = [a[1]] : (a[0] === function (i) {
if (!i)
return "";
for (var a = "", t = 83083, r = 0; r < i.length; r++) {
var e = i.charCodeAt(r) ^ t;
t = t * r % 256 + 2333,
a += String.fromCharCode(e)
}
return a
}("\u44ea\u0974\u095e") && (t[1] = a[1]),
"sid" === a[0] && (t[0] = a[1]))
}),
t.join("")
}
},
// 图片还原所需的o数组
"Grd8": function (i, a) {
function t(i, a) {
if (i.includes)
return i.includes(a);
for (var t = 0, r = i.length; t < r; t++)
if (i[t] === a)
return !0;
return !1
}
function r(i) {
if (!i)
return "";
for (var a = "", t = 17542, r = 0; r < i.length; r++) {
var e = i.charCodeAt(r);
e ^= "V587".charCodeAt(t = (t + 1) % "V587".length),
a += String.fromCharCode(e)
}
return a
}
i.exports = function (i) {
for (var a = [], e = 0; e < i.length; e++) {
var n = i[r('T>TJt9Q]v"')](e);
if (32 === e)
break;
for (; t(a, n % 32);)
n++;
a.push(n % 32)
}
return a
}
},
})
let reductionImg = function (img_path, sign_o) {
let i = canvas.createCanvas(400, 200),
a = new canvas.Image(),
t = 400, //宽
r = 200, //高
o = _e('Grd8')(sign_o)
a.src = img_path
return _e('w4qZ')(i, a, t, r, o).slice(22)
}
console.log(reductionImg('./bg_img.jpg', 'dingxiang85b86927da6c31ecee742bd20ee03743'));
webpack扣取还原算法。
三、获取图片
import base64
import time
import requests
import execjs
def get_img():
"""
图片接口-》获取图片
:return: 还原数组o
"""
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
}
url = "https://captcha-sec.heytapmobi.com/api/a"
params = {
"w": "300",
"h": "144",
"s": "50",
"ak": "b960842d69fec0920579b4ec213809a3",
"c": "661254613F9PL2e2vzSw9c2jGVGAN0hcHDMNi1U1",
"jsv": "v1.3.41(541)",
"aid": f"dx-{int(time.time() * 1000)}-54510378-1",
}
response = requests.get(url, headers=headers, params=params)
print(response.text)
res = response.json()
o = res['o']
bg_img = f'https://captcha-sec.heytapmobi.com{res["p1"]}'
slider_img = f'https://captcha-sec.heytapmobi.com{res["p2"]}'
print(f'获取的背景图片url:{bg_img}')
print(f'获取的滑块图片url:{slider_img}')
print(f'获取的解密数组o:{o}')
res = requests.get(bg_img).content
with open('bg_img.jpg', 'wb') as fp:
fp.write(res)
slider_con = requests.get(slider_img).content
with open('slider_img.jpg', 'wb') as fp:
fp.write(slider_con)
return o
def reduction_img():
"""
调用js还原图片
:return:
"""
o = get_img()
with open(f'./oppo.js', 'r', encoding='utf-8') as f:
js_code = f.read()
my_execjs = execjs.compile(js_code)
res = my_execjs.call('reductionImg', './bg_img.jpg', o)
# base64转图片
data = base64.b64decode(res)
with open('reduction_img.jpg', 'wb') as fp:
fp.write(data)
reduction_img()
个人记录所用~