Javascript 逆向找到 genToken() 源码

2 minute read

最近开始了我的实习之旅,爬虫相关的, 然后就遇到某个网站在获取部分 URL 的时候,header 里会带有一个 token,根据内容能发现是 HMAC 加密的

没有 token 的时候一律会返回错误, 于是研究了下 JS 的逆行,找到了生成 token 的 function

理念就是打断点,先是针对于 url 的断点,找到是在哪个 js 文件中发生了 http 请求

然后顺着 call stack 一层一层往上找,看在哪里生成的 header

然后在 getAuthToken() 这里打点,能在环境变量里看到用于加密使用的 key

然后顺着找到 getAuthToken() 的源码,

1
2
3
4
5
6
7
8
9
function (t){
    var e=s.initConfig.getConfig("env"),
        n=this.authKeys[e],
        r=s.initConfig.getTimeOffset(),
        i=(new Date).getTime()+r,
        a=(t&&t.authAcl||"")+"/*",
        u=(0,o.default)({},this.akamaiAuthconfig,{key:n,time:i,acl:a});
    return new c.default(u).generateToken()
}

以及c.default(u).generateToken()的源码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    var t = this.getIpField() + this.getStartTimeField() + this.getExprField() + 
            this.getAclField() + this.getSessionIdField() + this.getDataField(),
    e = t + "" + this.getUrlField() + this.getSaltField(),
    n = RegExp(this.delimiter + "$");
    return t + "hmac=" + u.default.HmacSHA256(e.replace(n, ""), function(t) {
        var e = "",
        n = 0;
        do {
            var r = t[n] + t[n + 1],
            o = parseInt((r + "").replace(/[^a-f0-9]/gi, ""), 16);
            e += String.fromCharCode(o), n += 2
        } while (t.length > n);
            return e
        }(this.key))

再根据实际需要进行简化,并进行比对,确认这个 function 正确运行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    def gen_token(self):
        def f(t):
            e, n = "", 0
            while(len(t) > n):
                r = t[n] + t[n+1]
                e += chr(int(re.sub(r"[^a-f0-9]", "", r+"") or "0", 16))
                n += 2
            return e
        key = ""
        t = int(time.time())
        i = 6000
        e = f"st={t}~exp={t+i}~acl=/*"
        _hash = hmac.new(f(key).encode('latin-1'),
                         msg=e.encode('latin-1'), digestmod=sha256).hexdigest()
        return f"{e}~hmac={_hash}"