前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js逆向之mytoken热搜榜

js逆向之mytoken热搜榜

作者头像
Python编程与实战
修改2019-12-04 15:50:50
6510
修改2019-12-04 15:50:50
举报

币圈的同学应该都听说过MyToken,其中最有价值的就是他的热搜榜。与其每天盯盘炒币,不如写一个脚本抓取它热搜榜数据。

阅读流程

  • 效果图
  • 项目地址
  • 反爬知识点
  • js重写
  • 思考问题

效果图

效果图

项目地址

MyToken热搜榜 https://github.com/justcodedroid/spider_js/tree/master/my_token

反爬知识点

本次研究的站点地址: https://mytoken.io/

MyToken的反爬比较简单,其对ts进行了一系列操作,然后生成一个code值。请求的时候携带上ts和code即可。

项目代码和js重写的时候都会详细说明。

js重写

通过debug,发现了一系列函数。并把这些函数封装到了一个工具类中。代码如下。

var utils = {
    stringToBytes: function (t) {
        for (var e = [], n = 0; n < t.length; n++)
            e.push(255 & t.charCodeAt(n));
        return e
    },
    bytesToWords: function (t) {
        for (var e = [], n = 0, r = 0; n < t.length; n++,
            r += 8)
            e[r >>> 5] |= t[n] << 24 - r % 32;
        return e
    },
    rotl: function (t, e) {
        return t << e | t >>> 32 - e
    },
    endian: function (t) {
        if (t.constructor == Number)
            return 16711935 & utils.rotl(t, 8) | 4278255360 & utils.rotl(t, 24);
        for (var e = 0; e < t.length; e++)
            t[e] = utils.endian(t[e]);
        return t
    },
    wordsToBytes: function (t) {
        for (var e = [], n = 0; n < 32 * t.length; n += 8)
            e.push(t[n >>> 5] >>> 24 - n % 32 & 255);
        return e
    },
    bytesToHex: function (t) {
        for (var e = [], n = 0; n < t.length; n++)
            e.push((t[n] >>> 4).toString(16)),
                e.push((15 & t[n]).toString(16));
        return e.join("")
    }

}

然后我们重写签名函数

var digest = function (t) {
    t = utils.stringToBytes(t + "9527" + t.substr(0, 6))
    for (var n = utils.bytesToWords(t), c = 8 * t.length, s = 1732584193, f = -271733879, l = -1732584194, p = 271733878, d = 0; d < n.length; d++)
        n[d] = 16711935 & (n[d] << 8 | n[d] >>> 24) | 4278255360 & (n[d] << 24 | n[d] >>> 8);
    n[c >>> 5] |= 128 << c % 32
    n[14 + (c + 64 >>> 9 << 4)] = c
    h = function (t, e, n, r, o, i, a) {
        var u = t + (e & n | ~e & r) + (o >>> 0) + a;
        return (u << i | u >>> 32 - i) + e
    }
    v = function (t, e, n, r, o, i, a) {
        var u = t + (e & r | n & ~r) + (o >>> 0) + a;
        return (u << i | u >>> 32 - i) + e
    }
    y = function (t, e, n, r, o, i, a) {
        var u = t + (e ^ n ^ r) + (o >>> 0) + a;
        return (u << i | u >>> 32 - i) + e
    }
    g = function (t, e, n, r, o, i, a) {
        var u = t + (n ^ (e | ~r)) + (o >>> 0) + a;
        return (u << i | u >>> 32 - i) + e
    }
    for (d = 0; d < n.length; d += 16) {
        var m = s, b = f, _ = l, w = p;
        f = g(f = g(f = g(f = g(f = y(f = y(f = y(f = y(f = v(f = v(f = v(f = v(f = h(f = h(f = h(f = h(f, l = h(l, p = h(p, s = h(s, f, l, p, n[d + 0], 7, -680876936), f, l, n[d + 1], 12, -389564586), s, f, n[d + 2], 17, 606105819), p, s, n[d + 3], 22, -1044525330), l = h(l, p = h(p, s = h(s, f, l, p, n[d + 4], 7, -176418897), f, l, n[d + 5], 12, 1200080426), s, f, n[d + 6], 17, -1473231341), p, s, n[d + 7], 22, -45705983), l = h(l, p = h(p, s = h(s, f, l, p, n[d + 8], 7, 1770035416), f, l, n[d + 9], 12, -1958414417), s, f, n[d + 10], 17, -42063), p, s, n[d + 11], 22, -1990404162), l = h(l, p = h(p, s = h(s, f, l, p, n[d + 12], 7, 1804603682), f, l, n[d + 13], 12, -40341101), s, f, n[d + 14], 17, -1502002290), p, s, n[d + 15], 22, 1236535329), l = v(l, p = v(p, s = v(s, f, l, p, n[d + 1], 5, -165796510), f, l, n[d + 6], 9, -1069501632), s, f, n[d + 11], 14, 643717713), p, s, n[d + 0], 20, -373897302), l = v(l, p = v(p, s = v(s, f, l, p, n[d + 5], 5, -701558691), f, l, n[d + 10], 9, 38016083), s, f, n[d + 15], 14, -660478335), p, s, n[d + 4], 20, -405537848), l = v(l, p = v(p, s = v(s, f, l, p, n[d + 9], 5, 568446438), f, l, n[d + 14], 9, -1019803690), s, f, n[d + 3], 14, -187363961), p, s, n[d + 8], 20, 1163531501), l = v(l, p = v(p, s = v(s, f, l, p, n[d + 13], 5, -1444681467), f, l, n[d + 2], 9, -51403784), s, f, n[d + 7], 14, 1735328473), p, s, n[d + 12], 20, -1926607734), l = y(l, p = y(p, s = y(s, f, l, p, n[d + 5], 4, -378558), f, l, n[d + 8], 11, -2022574463), s, f, n[d + 11], 16, 1839030562), p, s, n[d + 14], 23, -35309556), l = y(l, p = y(p, s = y(s, f, l, p, n[d + 1], 4, -1530992060), f, l, n[d + 4], 11, 1272893353), s, f, n[d + 7], 16, -155497632), p, s, n[d + 10], 23, -1094730640), l = y(l, p = y(p, s = y(s, f, l, p, n[d + 13], 4, 681279174), f, l, n[d + 0], 11, -358537222), s, f, n[d + 3], 16, -722521979), p, s, n[d + 6], 23, 76029189), l = y(l, p = y(p, s = y(s, f, l, p, n[d + 9], 4, -640364487), f, l, n[d + 12], 11, -421815835), s, f, n[d + 15], 16, 530742520), p, s, n[d + 2], 23, -995338651), l = g(l, p = g(p, s = g(s, f, l, p, n[d + 0], 6, -198630844), f, l, n[d + 7], 10, 1126891415), s, f, n[d + 14], 15, -1416354905), p, s, n[d + 5], 21, -57434055), l = g(l, p = g(p, s = g(s, f, l, p, n[d + 12], 6, 1700485571), f, l, n[d + 3], 10, -1894986606), s, f, n[d + 10], 15, -1051523), p, s, n[d + 1], 21, -2054922799), l = g(l, p = g(p, s = g(s, f, l, p, n[d + 8], 6, 1873313359), f, l, n[d + 15], 10, -30611744), s, f, n[d + 6], 15, -1560198380), p, s, n[d + 13], 21, 1309151649), l = g(l, p = g(p, s = g(s, f, l, p, n[d + 4], 6, -145523070), f, l, n[d + 11], 10, -1120210379), s, f, n[d + 2], 15, 718787259), p, s, n[d + 9], 21, -343485551),
            s = s + m >>> 0,
            f = f + b >>> 0,
            l = l + _ >>> 0,
            p = p + w >>> 0
    }
    return utils.bytesToHex(utils.wordsToBytes(utils.endian([s, f, l, p])))
}

到此为止,myToken的反爬已经搞定。剩下的就是用node起一个http服务。

思考问题

一般的站点签名是基于请求参数+ts+公钥的,为什么MyToken的只是基于ts的?这样做对后端开发有什么好处?


作者:阳光下的小树 来源:CSDN

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python编程与实战 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 阅读流程
  • 效果图
  • 项目地址
  • 反爬知识点
  • js重写
  • 思考问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档