js逆向实战之Bitcoin浏览器交易x-apikey参数加密逻辑

sbhglqy 2024-10-01 09:09:01 阅读 57

声明:本篇文章仅用于知识分享

实战网址:https://www.oklink.com/zh-hans/btc/tx-list

分析过程

  1. 访问网址,会触发一条数据包。

    image

    看它的响应内容。

    image

    就是我们想要获取的内容,找到数据了。可以先尝试直接去访问该url,看能否获取数据。

<code>import requests

url = "https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?offset=0&limit=20&t=1726967064457"

headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "

"Chrome/128.0.0.0 Safari/537.36"}

resp = requests.get(url, headers=headers)

print(resp.text)

回显如下。

image

提示我们<code>API_KEY未找到,说明代码中少了这个参数,再回去看数据包是否有API_KEY

image

有,但是是一串加密后的字符串,接下来就去解析加密逻辑。

2. 全局搜索<code>x-apikey。

image

只有一处,双击定位。

image

打断点,刷新页面,发现此处断点没有触发,不知道是什么原因。既然断点触发不了,直接看这行代码,有用的就是<code>getApiKey函数。

3. 全局搜索getApiKey

image

总共有6处,只需关注定义的地方,调用的就不需要看了。

image

把这两处都点进去看一下。

image

image

代码都一样的,随便看一个就可以了。打断点,刷新界面,还是没有触发断点。那就直接看代码吧。

<code>var t = (new Date).getTime(), e = this.encryptApiKey();

return t = this.encryptTime(t),

this.comb(e, t)

这段代码主要涉及4个函数,一个一个看。

(1)getTime()

这个函数看意思就知道获取时间戳的,没什么好讲的。

(2)encryptApiKey()

在当前文件中搜索encryptApiKey,找到定义的地方。

image

涉及三个变量<code>t、er

t = this.API_KEY:当前文件搜索API_KEY,是个定值。

image

<code>e = t.split(""):将t进行分割,如果不知道得到的是什么,可以在控制台输出一下。

image

<code>r = e.splice(0, 8):对e进行切片,获取前8个元素。

image

<code>return t = e.concat(r).join(""):将er进行拼接。

image

这个函数最关键的变量就是<code>t,只要t是个定值,该函数返回的就是一个定值。

(3)encryptTime()

在当前文件中搜索encryptTime,找到定义的地方。

image

涉及四个变量<code>e、rni

e = (1 * t + l).toString().split(""):t是时间戳,只需要知道l的值是什么。在当前函数定义处往上翻几行,就可以看到定义的地方,也是个定值。

image

获取时间戳,看看输出结果,相当于对时间戳做了个运算,将每位数字拆分开来。

image

<code>r = parseInt(10 * h.o.mathRandom(), 10):获取一个随机数,h.o.mathRandom()Math.random()作用一样。

image

所以<code>r、ni三个变量都是随机数。

return e.concat([r, n, i]).join(""):直接输出看结果,将四个变量进行拼接。

image

(4)<code>comb()

在当前文件中搜索comb,找到定义的地方。

image

涉及变量<code>r和函数window.btoa()

r = "".concat(t, "|").concat(e):输出看结果,就是将两个变量用|拼接。

image

<code>return window.btoa(r):输出看结果。

image

可以看到输出结果与我们在流量包中<code>x-apikey的值格式一致。

4. 编写代码进行数据获取。

function getApiKey(t){

var e = encryptApiKey();

return t = encryptTime(t),

comb(e, t)

}

API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"

function encryptApiKey() {

var t = API_KEY

, e = t.split("")

, n = e.splice(0, 8);

return t = e.concat(n).join("")

}

s = 1111111111111;

function encryptTime(t) {

var e = (1 * t + s).toString().split("")

, n = parseInt(10 * Math.random(), 10)

, r = parseInt(10 * Math.random(), 10)

, i = parseInt(10 * Math.random(), 10);

return e.concat([n, r, i]).join("")

}

function comb(t, e) {

var n = "".concat(t, "|").concat(e);

return btoa(n)

}

// console.log(getApiKey());

import requests

import execjs

import time

import json

# 想获取第几页的数据

offset = input("请输入你想获取第几页:")

# 获取时间戳

timestamp = int(time.time()*1000)

url = "https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?offset={}&limit=20&t={}".format(

offset, timestamp)

# 生成x-apikey

file_object = open("encrypt.js", mode="r")code>

exec_code = file_object.read()

exec_js = execjs.compile(exec_code)

x_apikey = exec_js.call("getApiKey", timestamp)

headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "

"Chrome/128.0.0.0 Safari/537.36",

"x-apikey": x_apikey}

resp = requests.get(url, headers=headers)

print(json.loads(resp.text))

运行结果如下。

image

大功告成,结束。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。