七麦analysis参数加密分析

1. 接口分析

目标站点

aHR0cHM6Ly93d3cucWltYWkuY24vcmFuay9tYXJrZXRSYW5r

先刷新网页,请求接口中的analysis参数本次分析的目标

在这里插入图片描述

2. 断点调式

打上XHR断点,刷新页面之后断点会断在接口处,接下来单步调式分析找到加密位置
在这里插入图片描述
这里我们可以看到e就是加密后生成的analysis值。不过这上图加密区域的代码逻辑还是有些复杂的,不能直接扣下来用

得分析每一个函数,还有其中有一些固定的值(这个值是会经常变动的),接下来我们开始补环境然后还原最终的JS加密代码

3. 补环境重写加密

function v(t) {
    
    
    t = encodeURIComponent(t).replace(/%([0-9A-F]{2})/g, function (n, t) {
    
    
        return o("0x" + t)
    });
    try {
    
    
        return btoa(t)
    } catch (n) {
    
    
        return Buffer.from(t).toString("base64")
    }
}

function o(n) {
    
    
    let f2 = '66';
    let s2 = '72';
    let d2 = '6f';
    let m2 = '6d';
    let l2 = '43';
    let v2 = '68';
    let p2 = '61';
    let h2 = '64';
    let y2 = '65';
    t = "",

        [f2, s2, d2, m2, l2, v2, p2, s2, l2, d2, h2, y2].forEach(function (n) {
    
    
            t += unescape("%u00" + n)
        });
    var t, e = t;
    return String.fromCharCode(n)
}

function h(n, t) {
    
    
    t = t || u();
    for (var e = (n = n.split("")).length, r = t.length, a = "charCodeAt", i = 0; i < e; i++)
        n[i] = o(n[i][a](0) ^ t[(i + 10) % r][a](0));
    return n.join("")
}

function encrypted(key) {
    
    
    var s = 1359
    var H = 0
    var e, r = +new Date() - (s || H) - 1661224081041, a = [];
    var v1 = "@#"
    // 固定值
    var d = "xyz517cda96abcd"

    // a = a[Ot]()[I1](_),
    a = a.sort().join("")
    a = (a += v1 + key) + (v1 + r) + (v1 + 3)
    e = (0,
        v)((0,
        h)(a, d))
    return e
}

现在我们来说一说上面重写的JS代码流程,首先看这一行代码var e, r = +new z[W] - (s || H) - 1661224081041, a = [];

z[W]我们鼠标放置可以看到它是一个Data(),然后我们需要做的就是把s、H两个变量的值拿到,这两个值写死就可以
在这里插入图片描述

通过上述方法,将d、v两个参数的值找到填好即可。这里需要注意的是d的值是在后续可能随时会变化的,相当于一个令牌

接下来我们需要找到代码中的i[jt]、i[qt]两个函数方法

i[jt]方法断点如下:
在这里插入图片描述

i[qt]方法断点如下:

在这里插入图片描述

其中h方法,我们也需要补一下值,直接替换一下方法跟值:

原始代码:for (var e = (n = n$1)[R], r = t[R], a = q1, i = H; i < e; i++)

替换:for (var e = (n = n.split(“”)).length, r = t.length, a = “charCodeAt”, i = 0; i < e; i++)

接下来处理一下v方法中的这行代码,也是需要重写还原的:

原始代码:t = zV1[T](/%([0-9A-F]{2})/g, function(n, t)

替换:t = encodeURIComponent(t).replace(/%([0-9A-F]{2})/g, function (n, t)

至于怎么补怎么还原可以根据断点,分析每一个参数、变量来补就可以,比如上面的z[V1]它就是一个encodeURIComponent方法,T是一个replace方法,数据内容不变

接下来,继续接着往下走,可以看到在v方法内调用了一个o,我们需要将这个o的方法也扣出来

断点调式找到o方法后,可以发现这个方法内有f2、s2、d2…多个参数值,因为外部没有在调用的时候传参,直接补上显示的值:
在这里插入图片描述

let f2 = '66';
let s2 = '72';
let d2 = '6f';
let m2 = '6d';
let l2 = '43';
let v2 = '68';
let p2 = '61';
let h2 = '64';
let y2 = '65';

v方法内还有一个z方法使用同样的方式重写:

原始代码:return z[W1]K1U1

替换:return Buffer.from(t).toString(“base64”)

4. 验证结果

接下来我们简单的写一个python请求调用代码,测试一下效果:

import time
import execjs
import requests

headers = {
    
     
    'authority': 'api.qimai.cn',
    'sec-ch-ua': '"Google Chrome";v="87", " Not;A Brand";v="99", "Chromium";v="87"',
    'accept': 'application/json, text/plain, */*',
    'sec-ch-ua-mobile': '?0',
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
    'sec-fetch-site': 'same-site',
    'sec-fetch-mode': 'cors',
    'sec-fetch-dest': 'empty',
    'accept-language': 'zh-CN,zh;q=0.9',
}

url = "https://api.qimai.cn"
url_args = "/rank/marketRank"

with open("./qimai.js") as f:
    js_code = f.read()

analysis = execjs.compile(js_code).call("encrypted", url_args)
res = requests.get(f"{
      
      url}{
      
      url_args}?analysis={
      
      analysis}", headers=headers).json()
print(res)

验证如下:

在这里插入图片描述
  好了,到这里又到了跟大家说再见的时候了。创作不易,帮忙点个赞再走吧。你的支持是我创作的动力,希望能带给大家更多优质的文章

猜你喜欢

转载自blog.csdn.net/qiulin_wu/article/details/132343879