js逆向七麦网站

前言

大数据时代的到来,人们对于数据的需求越来越大,但对于数据的获取不再像以前那么简单。

各大网站都对数据进行了加密处理来保护数据的安全。但是上有政策,下有对策。

今天带来逆向的第一个案例。

Let's Go!

目标网址:七麦数据 -专业移动产品商业分析平台-关键词优化-ASA优化-七麦科技

按F12进行常规抓包,发现这是一个url参数加密,analysis=eDUjFCk/Nw9UaXUMBlMMWgIlJRQiOEcIcRRMFgBXXU4LDQAdAToWAAJaVlUAB1ZbV1A4Wkk=

只要我们破解了该参数,就可以正常获取数据啦!

一般查找加密位置有三种基本方法:

  • 关键字搜索

  • Hook方法

  • XHR断点

当前前提是网站走的XHR(XMLHttpRequest)请求,今天我们采取XHR断点方式来找加密位置。

先点击源代码(source),右侧有个XHR断点点击+号,把analysis添加到方框中去。

而后刷新网页,看如下图,这样就被断住啦。然后我们一定要取消XHR断点,在进行调试,否则后面调试会遇到各种问题。

后面就是常规的调试,发现如下图.then回调方法(后台服务器返回数据给浏览器)

我们点击这个向下的箭头进行下一步。发现我们要的数据就在后台返回的t中。

后面我们再点击向上的箭头出栈。走到如下位置。发现Kt是个interceptors拦截器,Xt是response响应,因此我们可以断定拦截器请求(request)一定在这上面。

再次按向上的箭头,来到如下图位置。然后我们进行打断点,看原始数据的请求是怎么进行加密的,然后找到加密的位置,并把对应代码拿下来,我们就能自己进行模拟加密了。

如下图我们发现:

e = (0,i[jt])((0,i[qt])(a, d)) 经过分析e通过函数加密形成analysis加密参数

(0, i[jt])这种形式,我们可以把看它C语言中的逗号操作符,以最后的那位数的结果作为结果,因此我们改写成:args =i[qt](a, d),analysis=i[jt](args)

a='MTEyMDIzLTAxLTE3MzZjbmZyZWVpcGFk@#/rank/indexSnapshot@#12700680949@#3' 第一次

a='MTEyMDIzLTAxLTE3MzZjbmZyZWVpcGFk@#/rank/indexSnapshot@#12701166844@#3' 第二次

d='xyz517cda96abcd'第一次

d='xyz517cda96abcd'第二次

通过多次分析,d参数是写死的,而a是动态的参数

而a的生成就是如下三个代码生成的:


 a = a[Ot]()[I1](_),
 a = (0,i[jt])(a),
 a = (a += v + t[Jt][T](t[Mt], _)) + (v + r) + (v + 3)

现在开始我们就是扣代码啦。


var obj = {}
obj.xx = v

function o(n) { //o是我们h中要o具体函数的实现
    t = '',
        ['66', '72', '6f', '6d', '43', '68', '61', '72', '43', '6f', '64', '65']['forEach'](function (n) {
            t += unescape('%u00' + n)
        });
    var t, e = t;
    return String[e](n)
}

function h(n, t) {   // h就是i[qt],n就是a加密的数据,t就是要传入的d
    t = t || 'a12c0fa6ab9119bc90e4ac7700796a53';
    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 v(t) { // v 就是我们的i[jt]
    t = encodeURIComponent(t)['replace'](/%([0-9A-F]{2})/g, function (n, t) {
        return o('0x' + t)
    });
    try {
        return btoa(t)
    } catch (n) {
        return z[W1][K1](t)[U1](Z1)
    }
}


function xixi(page) {
    var v = '@#'
    var url = '/rank/index'
    // var url ='/rank/indexSnapshot' //这个是错误的,怪不得一直不对,初始调试要注意
    var baseURL = 'https://api.qimai.cn'
    var s = 15206
    var r = +new Date - (s || H) - 1661224081041 // s这个值也是动态的 但是直接写死也可以拿到数据,无需去还原

    // a=['paid','iphone','cn','5000',]// a这个参数要注意 ,这个是首页的参数,a这个参数可以改,只要把不同接口的参数进行替换,就能拿到别的接口数据了
    a = [1, '15:02:04', page, '2023-02-23', 'paid', 'iphone', 'cn', '5000']//这个可以获取所有页的参数
    a = a['sort']()['join']('')
    a = obj.xx(a) // a = i[jt](a)   i[jt]=v
    a = (a += v + url['replace'](baseURL, '')) + (v + r) + (v + 3)
    d = 'xyz517cda96abcd'
    console.log(a)
    // console.log(obj.xx(h(a, d))); //破解analysis的函数
    return obj.xx(h(a, d))
}

console.log(xixi());

在pycharm里运行,发现实现了我们要的加密效果。😆

那么我们如何用python拿到数据呢?


"""
@IDE     :PyCharm 
@Author  :落花
@Date    :2023/2/23
"""
import datetime
import requests
import execjs


def get_data():
    url = 'https://api.qimai.cn/rank/index?'
    # 头部
    headers = {
        "origin": "https://www.qimai.cn",
        "referer": "https://www.qimai.cn/",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
    }
    current_date = datetime.datetime.now().strftime('%Y-%m-%d')  # 获取当前年月日
    for i in range(1, 3):
        params = {
            "brand": "paid",
            "device": "iphone",
            "country": "cn",
            "genre": "5000",
            "date": str(current_date),
            "page": str(i),
            "is_rank_index": "1",
            "snapshot": "15:02:04"
        }
        # 执行js文件,获取analysis
        with open('xx.js', 'r', encoding='utf-8') as f:
            js_code = f.read()
        context = execjs.compile(js_code)
        analysis = context.call('xixi', i)
        params['analysis'] = analysis

        res = requests.get(url=url, params=params, headers=headers)
        print(res.json())


if __name__ == '__main__':
    get_data()

运行结果如下图:

希望能给你带来收获和灵感!以后给大家带来更有趣的!如果有不懂的可以在评论区提问,答主会进行回答哦!谢谢大家的观看