• 看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块


    @

    ⛳️ 看漫画漫画柜 mhgui 实战分析

    本次爬虫采集的案例是漫画柜,该站点貌似本身就游走在法律的边缘。
    看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块
    站点地址直接检索即可进入,在该目标站点,橡皮擦发现了 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:时间戳。

    通过开发者工具的 DOM 事件绑定器,找到下一页按钮点击事件,然后在下述位置添加断点。
    看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块
    通过该断点调试,发现参数在页面加载时已经生成,继续寻找的意义不大,接下来要更换思路。

    全局检索关键字 m=,查看所有搜索结果之后,最终定位到 config.js 文件,即下图代码高亮位置。
    看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块
    截取相应的代码文件,如下所示,这代码一眼看上去就能猜测是 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)}
    

    但是这里并没有前文的关键字参数 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 函数解析上述代码,发现出现如下错误。
    看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块
    但是 \x65\x76\x61\x6c 可以解码为 eval

    console.log('\x65\x76\x61\x6c')
    16:42:45.372 VM251:1 eval
    

    但是下述这段代码出现了问题。
    看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块
    在结合刚才我们得到的一个莫名的加密函数。

    function(f){return LZString.decompressFromBase64(this).split(f)}
    

    可以试着用 Python 解密一下上述代码段,而且 Python 中恰好有同名第三方模块。

    pip install lzstring
    

    直接解密加密字符串即可。

    import lzstring
    
    x = 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。
    看漫画漫画柜mhgui,Python爬虫之神奇的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 编码就变的索然无味 了,大家加油~


    你正在阅读 【梦想橡皮擦】 的博客
    阅读完毕,可以点点小手赞一下
    发现错误,直接评论区中指正吧
    橡皮擦的第 687 篇原创博客

    从订购之日起,案例 5 年内保证更新

  • 相关阅读:
    读取 classes下的配置文件
    java中Class.getResource用法(用于配置文件的读取)
    windows 中 到底是用的哪个java.exe??? 删除了PATH变量的Java设置还是可以运行java.exe windows/system32
    mysql中null与“空值”的坑
    innodb架构理解
    mysql5.7性能提升一百倍调优宝典
    servlet 3.0笔记之servlet的动态注册
    前端性能优化建议
    了解CSRF攻击原理和预防
    vue的热更新配置
  • 原文地址:https://www.cnblogs.com/happymeng/p/16441870.html
Copyright © 2020-2023  润新知