Python網(wǎng)絡(luò)爬蟲逆向之frida rpc轉(zhuǎn)發(fā)案例(x物)
回復(fù)“書籍”即可獲贈(zèng)Python從入門到進(jìn)階共10本電子書
本教程只用于學(xué)習(xí)探討,不允許任何人使用技術(shù)進(jìn)行違法操作,閱讀教程即表示同意!
前言
Hello,大家好,我是碼農(nóng)星期八,本次帶來的是如何通過frida rpc算法轉(zhuǎn)發(fā)來完成x物搜索商品接口的加密!
用到的app
x物4.74.5版本
鏈接:https://pan.baidu.com/s/1el0a48vsIl7XI-cDr7iynA
提取碼:tlvb
--來自百度網(wǎng)盤超級會員V1的分享
環(huán)境
pixel2 v10(已root)
Magisk v23.0
Charles v4.6.2
Drony v1.3.154
Python v3.8.6
frida v14.2.18
x物抓包
首先進(jìn)行搜索,根據(jù)抓到的包逐條篩選,可以發(fā)現(xiàn)這條url數(shù)據(jù)是吻合的!

經(jīng)過不斷測試,發(fā)現(xiàn)newSign這個(gè)值是不斷變化的。
通過構(gòu)造請求,這個(gè)值不對確實(shí)是無法請求的?。祷匾粋€(gè)簽名校驗(yàn)失?。?/p>
那,如何搞定這個(gè)newSign呢?
簡單分析
將app拖入jadx中,搜索newSign

發(fā)現(xiàn)有很多newSign,是哪個(gè)呢?那就只能猜了,我們先hook第一個(gè),看是不是走的這個(gè)!
點(diǎn)進(jìn)入,看看是哪個(gè)類,hook的是RequestUtils.c這個(gè)方法!

hook代碼
Java.perform(function () {
function printMap2(map) {
return Java.cast(map, Java.use("java.util.HashMap"));
}
Java.use("com.shizhuang.duapp.common.utils.RequestUtils").c.implementation = function (map, j2) {
console.log("RequestUtils c is call")
console.log("map:", map)
console.log("map:", printMap2(map))
console.log("j2:", j2)
let result = this.c(map, j2)
console.log("RequestUtils c result:", result)
return result
}
})
驗(yàn)證
可以發(fā)現(xiàn)走的確實(shí)是第一個(gè),并且newSign也能對上!

rpc轉(zhuǎn)發(fā)
那就好辦了,既然已經(jīng)知道了他調(diào)用的是哪個(gè)方法,但是也不想使勁扣代碼,直接上rpc吧!
com.shizhuang.duapp.common.utils.RequestUtils.c這個(gè)函數(shù)接受的是兩個(gè)參數(shù)。
一個(gè)是一個(gè)map,一個(gè)是時(shí)間戳。
map里面包括了分頁,要搜索的內(nèi)容什么的。

rpc轉(zhuǎn)發(fā)代碼
from fastapi import FastAPI
import uvicorn
import frida
jsCode = """
function newsign(arg_f,j2) {
let result = "";
Java.perform(function () {
let map = Java.use("java.util.HashMap").$new();
for (let key in arg_f) {
map.put(key + "", arg_f[key] + "")
}
result = Java.use("com.shizhuang.duapp.common.utils.RequestUtils").c(map, j2)
})
return result;
}
rpc.exports = {
newsign:newsign
};
"""
# 準(zhǔn)備工作
# process = frida.get_device_manager().add_remote_device('192.168.3.68:27042').attach("com.dodonew.online")
process = frida.get_usb_device().attach('com.shizhuang.duapp')
script = process.create_script(jsCode)
print('[*] Running ')
script.load()
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
m: dict
j2: int
@app.post("/getnewsign")
async def getencrypt(item: Item):
result = script.exports.newsign(item.m, item.j2)
return {"data": result}
if __name__ == '__main__':
uvicorn.run(app, port=8080)
請求接口代碼
代碼
import requests
import time
import json
timestamp = int(time.time() * 1000)
url = "https://app.dewu.com/api/v1/app/search/ice/search/list"
params = {
"originSearch": "false", "catId": 0, "abTest": '[{"name":"search_equlheight_spu_strategy","value":"0"}]',
"hideAddProduct": 0, "sortType": 0, "showHot": 1, "limit": 20, "productDetailVersionFlag": 1, "typeId": 0,
"sortMode": 0, "page": 0, "title": "13蘋果"
}
# ########### 加密newsign begin
data = {
"m": params,
"j2": timestamp,
}
r = requests.post("http://127.0.0.1:8080/getnewsign", data=json.dumps(data))
sign = r.json().get("data")
# ########### 加密newsign end
params["newSign"] = sign
print(params)
headers = {
"duuuid": "38a763c08fd35e88",
"duimei": "",
"duplatform": "android",
"appId": "duapp",
"duchannel": "pp",
"humeChannel": "",
"duv": "4.74.5",
"duloginToken": "",
"dudeviceTrait": "Pixel+2",
"dudeviceBrand": "google",
"timestamp": f"{timestamp}",
"shumeiid": "20220315115339c2791752e1a1601028f3d267a317791d01458b2315a9eba3",
"oaid": "",
"User-Agent": "duapp/4.74.5(android;10)",
"X-Auth-Token": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1dWlkIjoiMzhhNzYzYzA4ZmQzNWU4OCIsInVzZXJJZCI6MTg1NDk2MzI5NCwiaXNHdWVzdCI6dHJ1ZSwiZXhwIjoxNjc4ODUyNDE4LCJpYXQiOjE2NDczMTY0MTgsImlzcyI6IjM4YTc2M2MwOGZkMzVlODgiLCJzdWIiOiIzOGE3NjNjMDhmZDM1ZTg4In0.AM9apvMO1rj73LmLF3gHLS0IR5kWICzJIxsjXwMaC3NtlF2VdvH2PEAMDLi-gCb6sceplIC8gJlivVp0WxPOYnA5JOmcaGaA32ihjNCNJdsST2vt-I0vyhi4XVcRvK6-H_H8X-miCXnVkUnq0xs0sz4L9A8QSKJAb9y4xTLPKvw_ncwglg7chNDsBM2AfItPRpqjT-rHrW4tEix9EXCIQsAcRSgqodHOq1TPviNm0j8TaX4DMnTQTN4IktwWqiRXUfDtSraQAFeS_1z4lANCWNshRwNNUxlOHmE8kvN91dr9aZ1PvRF8yoBZg9kWvwOSuxYA7W9VPHx6TsOp2xGFhQ",
"isRoot": "0",
"emu": "0",
"isProxy": "0",
"Host": "app.dewu.com",
"Accept-Encoding": "gzip",
"Connection": "keep-alive"
}
r1 = requests.get(url=url, headers=headers, params=params)
print(r1.url)
print(r1.text)
得到的結(jié)果

總結(jié)
小試牛刀一下,果然,rpc萬能,除了有點(diǎn)廢環(huán)境。
人生沒有白走的路,加油!
如果在操作過程中有任何問題,記得下面留言,我們看到會第一時(shí)間解決問題。
越努力,越幸運(yùn)。
我是碼農(nóng)星期八,如果覺得還不錯(cuò),記得動(dòng)手點(diǎn)贊一下哈。
感謝你的觀看。
小伙伴們,快快用實(shí)踐一下吧!如果在學(xué)習(xí)過程中,有遇到任何Python問題,歡迎加我好友,我拉你進(jìn)Python學(xué)習(xí)交流群共同探討學(xué)習(xí)。
------------------- End -------------------
往期精彩文章推薦:

歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持
想加入Python學(xué)習(xí)群請?jiān)诤笈_回復(fù)【入群】
萬水千山總是情,點(diǎn)個(gè)【在看】行不行
