志不强者智不达,言不信者行不果。这篇文章主要讲述看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块相关的知识,希望能为你提供帮助。
@[toc]
?? 看漫画漫画柜 mhgui 实战分析本次爬虫采集的案例是漫画柜,该站点貌似本身就游走在法律的边缘。
文章图片
站点地址直接检索即可进入,在该目标站点,橡皮擦发现了 eval 加密的双重用法。
页面所有点位都无太大难点,而且漫画超多,但是当点击详情页的时候,发现加密点位了。
https://i.hamreus.com/ps1/u/17287/cmdty/%E7%AC%AC01%E8%AF%9D/3.jpg.webp?e=1654230046&
m=T-uqjbcgI-eyVGgsIsnjLw
其中比较关键的就是参数
m
,其余参数都比较容易猜到其含义。%E7%AC%AC01%E8%AF%9D
:第一话;e
:时间戳。
文章图片
通过该断点调试,发现参数在页面加载时已经生成,继续寻找的意义不大,接下来要更换思路。
全局检索关键字
m=
,查看所有搜索结果之后,最终定位到 config.js
文件,即下图代码高亮位置。文章图片
截取相应的代码文件,如下所示,这代码一眼看上去就能猜测是
eval
加密,但是其关键信息,例如 window["\\x65\\x76\\x61\\x6c"]
还是存在加密,下面我们优先解决该值。window["\\x65\\x76\\x61\\x6c"](function(i, k, a, n, m, an)
m = function(a)
return (a <
k ? "" : m(window["\\x70\\x61\\x72\\x73\\x65\\x49\\x6e\\x74"](a / k))) + ((a = a % k) >
35 ? window["\\x53\\x74\\x72\\x69\\x6e\\x67"]["\\x66\\x72\\x6f\\x6d\\x43\\x68\\x61\\x72\\x43\\x6f\\x64\\x65"](a + 29) : a["\\x74\\x6f\\x53\\x74\\x72\\x69\\x6e\\x67"](36));
if (!["\\x72\\x65\\x70\\x6c\\x61\\x63\\x65"](/^/, window["\\x53\\x74\\x72\\x69\\x6e\\x67"]))
while (a--)
an[m(a)] = n[a] || m(a);
n = [function(m)
return an[m]];
m = function()
return \\\\\\x77\\x2b;
a = 1;
while (a--)
if (n[a])
i = i["\\x72\\x65\\x70\\x6c\\x61\\x63\\x65"](new window["\\x52\\x65\\x67\\x45\\x78\\x70"](\\\\\\x62 + m(a) + \\\\\\x62,\\x67), n[a]);
return i
(\\x72 \\x41\\x3d\\x28\\x78\\x28\\x29\\x7b\\x72 \\x6c\\x69\\x74"](\\x7c), 0, ));
别看上述代码长,但是当我使用在线工具解密之后,得到了下面一段代码。
function(f)return LZString.decompressFromBase64(this).split(f)
【看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块】但是这里并没有前文的关键字参数
m=T-uqjbcgI-eyVGgsIsnjLw
,接下来我们在源码中查看一下,看是否存在关键性信息。得到的代码段如下所示
window["\\x65\\x76\\x61\\x6c"](
(function (p, a, c, k, e, d)
e = function (c)
return (
(c <
a ? "" : e(parseInt(c / a))) +
((c = c % a) >
35 ? String.fromCharCode(c + 29) : c.toString(36))
);
;
if (!"".replace(/^/, String))
while (c--) d[e(c)] = k[c] || e(c);
k = [
function (e)
return d[e];
,
];
e = function ()
return "\\\\w+";
;
c = 1;
while (c--)
if (k[c]) p = p.replace(new RegExp("\\\\b" + e(c) + "\\\\b", "g"), k[c]);
return p;
)(
U.k("F":i,"E":"D","C":"i.a","B":A,"z":"f","y":["1.a.b","2.a.b","3.a.b","4.a.b","5.a.b","6.a.b","7.a.b","8.a.b","9.a.b","%x%w%v%c%t%G%d%g%h%r.4.1%q.a.b","%p%j%o%c%j%n%c%l%I%d%H%P%d%g%h.a.b"],"J":W,"Y":11,"Z":"/12/u/X/V/f/","10":1,"S":"","R":Q,"O":0,"N":"e":M,"m":"T-L-K").s();
,
62,
65,
"D41hWAODmwO4FMBGlgFECs6CcJA03gAwCMgu9HACCRwAQlgMzbYBMVAHNcAJYC20AIgEMALgOCtWIbADFg2DmgBswJriasWwSACcEASQB2nIbLqSAwjT7oALMABmnADYIAzsADG+gdwTAMGVgB2YI9OABNgFE53YEBIm0ANvMAQt0BavUBbtUivH0jwsTYsViUHQxcACwQIhABPADUAcWgXXRd9cAAZOGAAVwBHcCR3aF1gIgUMayY6AgJrJRdHTR0AN10I1it/IMCJfQQADyEVyMcAe3cAawB9dxjgAGUAWQAJD24woUr7AUcXXyJAtUCwGc+k0whKwBcIiEnTcmhcRCAA="[
"\\x73\\x70\\x6c\\x69\\x63"
]("\\x7c"),
0,)
);
此时关键信息逐渐出现,我们重点解密该代码段即可。
直接使用 eval 函数解析上述代码,发现出现如下错误。
文章图片
但是
\\x65\\x76\\x61\\x6c
可以解码为 eval
。console.log(\\x65\\x76\\x61\\x6c)
16:42:45.372 VM251:1 eval
但是下述这段代码出现了问题。
文章图片
在结合刚才我们得到的一个莫名的加密函数。
function(f)return LZString.decompressFromBase64(this).split(f)
可以试着用 python 解密一下上述代码段,而且 Python 中恰好有同名第三方模块。
pip install lzstring
直接解密加密字符串即可。
import lzstringx = lzstring.LZString()decompressed = x.decompressFromBase64(
D41hWAODmwO4FMBGlgF加密字符串AA=)
print(decompressed)
得到的信息如下所示,变得越来越清楚了。
||||||||||jpg|webp|E5|E9||第01话|A1|B5|39921|8B|imgData|88||9F|9B|E6|29|2821|preInit|93||9C|BD|E4|files|cname|558777|cid|bpic|沉默的庭园|bname|bid|81|85|86|finished|eyVGgsIsnjLw|uqjbcgI|1654230046|sl|prevId|8D|558778|nextId|block_cc||S
MH|cmdty|false|17287|len|path|status||ps1
此时还是无法得到最终的答案,然后可以看到代码结构发现下述规律,即代码出现了相似的部分,并且都是 eval。
文章图片
细心环节,将代码一点点翻译成可逆向的
将
lzstring
解密字符串,然后手动使用 split
函数进行分隔,因为上述代码 \\x73\\x70\\x6c\\x69\\x63
解析出来竟然是 splic
函数。谷歌开发者工具的控制台中运行下述代码即可。
"||||||||||jpg|webp|E5|E9||第01话|A1|B5|39921|8B|imgData|88||9F|9B|E6|29|2821|preInit|93||9C|BD|E4|files|cname|558777|cid|bpic|沉默的庭园|bname|bid|81|85|86|finished|eyVGgsIsnjLw|uqjbcgI|1654230046|sl|prevId|8D|558778|nextId|block_cc||SMH|cmdty|false|17287|len|path|status||ps1".split(
"|"
);
得到的信息如下所示。
[
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"jpg",
"webp",
"E5",
"E9",
"",
"第01话",
"A1",
"B5",
"39921",
"8B",
"imgData",
"88",
"",
"9F",
"9B",
"E6",
"29",
"2821",
"preInit",
"93",
"",
"9C",
"BD",
"E4",
"files",
"cname",
"558777",
"cid",
"bpic",
"沉默的庭园",
"bname",
"bid",
"81",
"85",
"86",
"finished",
"eyVGgsIsnjLw",
"uqjbcgI",
"1654230046",
"sl",
"prevId",
"8D",
"558778",
"nextId",
"block_cc",
"",
"SMH",
"cmdty",
"false",
"17287",
"len",
"path",
"status",
"",
"ps1",
];
然后将其替换到上述 JS 中,使用解密工具直接在线解析。
SMH.imgData(
bid: 39921,
bname: "沉默的庭园",
bpic: "39921.jpg",
cid: 558777,
cname: "第01话",
files: [
"1.jpg.webp",
"2.jpg.webp",
"3.jpg.webp",
"4.jpg.webp",
"5.jpg.webp",
"6.jpg.webp",
"7.jpg.webp",
"8.jpg.webp",
"9.jpg.webp",
"%E4%BD%9C%E5%93%81%E9%A1%B5%2821.4.1%29.jpg.webp",
"%E6%8B%9B%E5%8B%9F%E5%88%86%E9%85%8D%E9%A1%B5.jpg.webp",
],
finished: false,
len: 11,
path: "/ps1/u/17287/cmdty/第01话/",
status: 1,
block_cc: "",
nextId: 558778,
prevId: 0,
sl:e: 1654230046, m: "T-uqjbcgI-eyVGgsIsnjLw" ,
).preInit();
此时,一些关键参数都已经得到了,例如
e
的值,m
的值。接下来的 Python 编码就变的索然无味 了,大家加油~
推荐阅读
- HarmonyOS - 实现多设备协同
- AI+科学计算-昇思MindSpore都给我们带来哪些惊喜()
- 数据仓库进阶 - 01 《阿里大数据之路》第二篇 数据模型篇
- Java 集合系列07--- HashMap详细介绍(源码解析)----新
- #导入Word文档图片# Linux下IO多路复用: Selectpollepoll
- 流水线中如何获取代码库分支信息
- vivo大规模 Kubernetes 集群自动化运维实践
- H3CERG2系列路由器端口映射(虚拟服务器)
- kubernetes下的Nginx加Tomcat三部曲之二(细说开发)