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()
运行结果如下图:
希望能给你带来收获和灵感!以后给大家带来更有趣的!如果有不懂的可以在评论区提问,答主会进行回答哦!谢谢大家的观看