这里以崔大爬虫练习站 app 的第 5 题作为逆向题目
aHR0cHM6Ly9zY3JhcGUuY2VudGVyLw==
先下载 app ,然后简单抓个包看看
可以看到请求中带有一个加密的参数token
返回的是一个json
字符串
下拉刷新可以看到token
是不断变化的,现在用jadx
反编译看看,找找token
的逻辑
通过检索"token"
在结果处查找用例
可以找到下面的代码处
然后这里的Encrypt
可以看到使用了shaEncrypt
这个方法
通过shaEncrypt
的逻辑可以知道这里进行了一次sha1
加密
未知的就是传入的str
的值,这一步可以通过frida hook
得到结果
简单写一个frida
脚本,打印一下shaEncrypt
的入参和返回值
console.log("脚本加载成功");
function main(){
Java.perform(function(){
var Encrypt = Java.use("com.goldze.mvvmhabit.utils.Encrypt");
Encrypt.shaEncrypt.implementation = function (arg1){
console.log("\Encrypt.shaEncrypt\n");
console.log("Input str=" + arg1 + "\n");
var shaEncrypt_result = this.shaEncrypt(arg1);
console.log("\nOut Rc=" + shaEncrypt_result);
return shaEncrypt_result;
}
})
}
setImmediate(main)
可以看到入参的参数的就是url + , + 时间戳
算法是sha1
,这一点可以通过加密站来验证
接下来将结果和时间戳经过了一次base64
,得到最终的结果
我们来测试一下看看是不是一样的
console.log("脚本加载成功");
function main(){
Java.perform(function(){
var Encrypt = Java.use("com.goldze.mvvmhabit.utils.Encrypt");
Encrypt.shaEncrypt.implementation = function (arg1){
console.log("\Encrypt.shaEncrypt\n");
console.log("Input str=" + arg1 + "\n");
var shaEncrypt_result = this.shaEncrypt(arg1);
console.log("\nOut Rc=" + shaEncrypt_result);
return shaEncrypt_result;
}
var Base64 = Java.use("android.util.Base64");
Base64.encodeToString.overload('[B', 'int').implementation = function (arg1,arg2){
var encodeToString_result = this.encodeToString(arg1,arg2);
console.log("\nOut Rc=" + encodeToString_result);
return encodeToString_result;
}
})
}
setImmediate(main)
可以看到这里打印的结果验证了我们的猜想。
所以token
的生成算法就是base64(sha1(path,时间戳),时间戳)
写一段代码测试一下
import requests
import hashlib
import base64
import time
def encode_sha1(data, encode_method="utf-8"):
"""
sha1加密
:param data: 待加密字符串
:param encode_method: 编码方法,默认utf-8
:return: 40长度字符串
"""
bytes_data = data.encode(encode_method)
m = hashlib.sha1()
m.update(bytes_data)
return m.hexdigest()
def encode_base64(data, encode_method="utf-8"):
"""
base64加密
:param data: 待加密字符串
:param encode_method: 编码方法,默认utf-8
:return:
"""
bytes_data = data.encode(encode_method)
result = base64.b64encode(bytes_data).decode()
return result
def get_params():
# base64(sha1(path,时间戳),时间戳)
path = "/api/movie,"
time_str = str(int(time.time()))
sha1_result = encode_sha1( path + time_str)
base64_params = sha1_result + ',' + time_str
base64_result = encode_base64(base64_params)
# print(base64_result)
return base64_result
def main():
headers = {
'log-header': 'I am the log request header.',
'Host': 'app5.scrape.center',
'Connection': 'Keep-Alive',
'Accept-Encoding': 'gzip',
'User-Agent': 'okhttp/3.10.0',
}
params = (
('offset', '20'),
('limit', '10'),
('token', get_params()),
)
response = requests.get('https://app5.scrape.center/api/movie/', headers=headers, params=params)
print(response.text)
if __name__ == '__main__':
main()
结果如下
好了,以上就是今天的全部内容了。
我是没有更新就在摸鱼的咸鱼
收到请回复~
我们下次再见。