Python 爬蟲進階必備 | 某小眾商城 h5 商品列表頁加密參數(shù)邏輯分析
第一時間關(guān)注Python技術(shù)干貨!
圖源:極簡壁紙
今日網(wǎng)站
aHR0cHM6Ly9oNS53YW53dWRlemhpLmNvbS9tYWxsLXdlYi9jYXRlZ29yeS9jbGFzc2lmeS8xNjE5MTYxNDM3NDMxP3RleHQ9JUU2JTg5JThCJUU0JUI4JUIyJmNpZD0xMCZmYWNhZGVDYXRlZ29yeUlkPTEwJmlzU2hvd0F1Y3Rpb25GaXJzdD0xJl9fSGdXdHdZVT0xNjE5MTYxNDM3NDMxJnJ0cFJlZmVyPWJ3MC53MC4wLjAuMTYxOTE2MTQzNTQ4MiUyNEc3SiZzaGFyZVVzZXJJZD0xODc1OTU4OCZzaGFyZVRpbWU9MTU5MTY5MDY5OSZydHBBcHBsaWNhdGlvbj1INS5VWEdCdVR4ZloxNjMzMDg4OTQzMDcw
這個網(wǎng)站需要分析的參數(shù)較多,一個個來
抓包分析與加密定位
像這種下拉刷新的看抓包直接切換到xhr里就可以看到了

可以看到上述圖片的請求頭的位置都是需要分析的值
分析下以下幾個參數(shù),分別是kl_sign、kl_device_id、kl_trace_id
接下來一個個分析他們的加密邏輯
加密定位與分析
kl_device_id
直接檢索只有一項,并且在結(jié)果項中再檢索也只有一個匹配項


function?he(t)?{
????if?(!t)
????????return?s[64];
????for?(var?e?=?"",?r?=?92132,?n?=?s[65];?n?????????var?i?=?t.charCodeAt(n)?^?r;
????????r?=?r?*?n?%?256?+?a[4],
????????????e?+=?String.fromCharCode(i)
????}
????return?e
}
這里傳入的參數(shù)是兩個特殊的編碼


“特殊編碼在編輯器里經(jīng)常會因為我們在運行代碼的時候的編碼轉(zhuǎn)換出現(xiàn)問題,所以可以在傳參的時候先 base64 編碼一下,然后在接收的時候解碼避免因為編碼不同導(dǎo)致的各種問題
kl_trace_id
這里的 trace_id 就在device_id的下邊

然后這里的調(diào)用了Qr[a[194]]的邏輯,在控制臺輸出一下,點擊回顯跳轉(zhuǎn)過去


m?=?function()?{
????var?t?=?(new?Date).getTime();
????return?"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,?(function(e)?{
????????var?r?=?(t?+?16?*?Math.random())?%?16?|?0;
????????return?t?=?Math.floor(t?/?16),
????????????("x"?===?e???r?:?3?&?r?|?8).toString(16)
????}))
}
就是根據(jù)時間戳隨機生成的uuid
kl_sign
這個參數(shù)沒有上面的參數(shù)放在一塊所以單獨找找看看
直接檢索是沒有結(jié)果的,但是肯定是和上面幾個參數(shù)一塊提交的
所以我們繼續(xù)下一步分析看看


所以需要分析的參數(shù)kl_sign就是R
這里的R
R?=?Yr.a[de("%\\_Y")](d,?j,?C)
所以對以上的參數(shù)一個個分析

這里的C是一個Map對象,里面有kl_path、kl_trace_id、kl_device_id
除了kl_path之外其他兩個都已經(jīng)找到生成的邏輯了
kl_path是一個固定值沒有太多分析的必要
d是時間戳/1000,現(xiàn)在還剩一個j,這里的j是提交的參數(shù)
所以現(xiàn)在需要分析的回到上面又變成了Yr.a[de("%\\_Y")]這個加密方法是什么?
所以重新斷點進去看看加密

這里返回的是oe
接下來繼續(xù)一步步跟

單步到oe里看到這里就是直接返回了一個方法,可以看到好大一串
所以繼續(xù)找這個返回的方法的返回值
ee[Jt(s[57])][$t(bt?+?r?+?"REDAE"?+?n?+?i?+?o)]?+?"="?+?ee[te("d?RVg7GYZ[MZ%")].ALGORITHM?+?u[58]?+?ee[Jt("涐淹淶淰潿淁涳淒涿淺涔淡涌淿")][wt?+?"ER_SIGNEDHEADERS"]?+?"="?+?m[Jt("涷淘涋淿涍淤涊"?+?p)]()?+?te("")?+?ee[$t(d?+?"raPngiS")][St?+?"IONHEADER_"?+?b]?+?$t(u[59])?+?O?+?$t("/")?+?ee[h[67]]["AUTHORIZATION"?+?g?+?xt]?+?a[63]?+?A
就是上面一串
這一串有很多的未知參數(shù),所以先剔除一些固定值,并且把里面混淆的亂碼啥的去掉

可以看到通過一個個分析有很多的固定參數(shù),所以我們不用分析
主要分析的變成了最后最后的A
前面的O是時間戳+_wwdz_request的字符串
O?=?t[te('C?X]D"TUG')]?+?"_"?+?ee[y?+?"Enums"][a[62]];

這里的A在上面的方法返回

混淆還原之后是下面這樣的代碼
var?A?=?function(t,?e)?{
????var?r,?n?=?"od",?i?=?"s",?o?=?"s",?p?=?"SIGNEDPARAM_T",?d?=?'ums',?g?=?h[80],?v?=?"SIGNEDPARAM_S",?m?=?new?Map,?y?=?at['MD5'](ee.SignParamEnums.SIGNSECRETKEY?+?ee.SignParamEnums.SIGNSALT?+?t.signVersion)["toString"](),?b?=?it(e);
????try?{
????????for?(b.s();?!(r?=?b['n']())['done'];?)?{
????????????var?E?=?r["value"];
????????????m.set(E[0],?E[1])
????????}
????}?catch?(t)?{
????????b.e(t)
????}?finally?{
????????b['f']()
????}
????return?m['set'](ee['SignParamEnums']['SIGNEDPARAM_SID'],?t['sId']),
????????m['set'](ee['SignParamEnums']['SIGNEDPARAM_TIMESTAMP'],?t['timestamp']),
????????m['set'](ee['SignParamEnums']['SIGNEDPARAM_APPVERSION'],?t['appVersion']),
????????m['set'](ee['SignParamEnums']['SIGNEDPARAM_SIGNVERSION'],?t['signVersion']),
????????m['set'](ee.SignParamEnums['SIGNEDPARAM_PAYLOAD'],?function(t,?e)?{
????????return?at['HmacSHA256'](t,?e)['toString']()
????}(t['payload'],?y)),
????????function(t,?e)?{
????????var?r?=?st.getParamStr(t);
????????return?r?=?r.toUpperCase(),
????????????at.HmacSHA256(r,?e).toString()
????}(m,?y)
}(t,?e)
可以看到大致就是對時間戳和上面分析到的幾個參數(shù)進行hash,并且在最后還用了sha256對提交參數(shù)進行取值,完成最后的加密
而具體流程是這樣的
在開始的定義參數(shù)的位置先對下面的幾個參數(shù)進行 hash
Md5 的參數(shù)是取得下面的幾個參數(shù)拼接的結(jié)果

ee.SignParamEnums.SIGNSECRETKEY?+?ee.SignParamEnums.SIGNSALT?+?t.signVersion
#?'bbcc71f7b26a82ea97196366558a8ef0e680d60e7e6bd5931cb46d30c91d6d0d1.0.0'
然后下面有一個 Map
其中在 Map 的 PAYLOAD 傳入下面代碼計算出來的值
function(t,?e)?{
????return?at["sha256"](t,?e)["toString"]()
}(t["payloa"?+?v],?y))
這里的y是上面hash的結(jié)果,另一個參數(shù)是請求提交的參數(shù)

'{"orderType":4,"facadeCategoryId":88,"type":0,"pageIndex":6,"pageSize":20,"facadeStr":"{\"facadeCategoryId\":88,\"icon\":\"https://cdn.wanwudezhi.com/seller-admin/image/MTYyODI1NzIwODI2Mg==608_408x408.png\",\"name\":\"全部\"}"}'
這兩個參數(shù)傳入進去之后,經(jīng)過了sha256的處理

最后 Map 和上面的 y也就是上面 md5 的結(jié)果再進行一次sha256就是最后需要的參數(shù)A了
這個時候Map需要先經(jīng)過一個方法getParamStr
這個getParamStr是將這個 Map 的鍵值用=拼接起來并大寫

結(jié)果是這樣的

'APPVERSION=4.2.2&KL_DEVICE_ID=929297D0-22AD-11EC-8138-2F372015C114&KL_PATH=/ACTIVITYSEARCH/CATEGORY/ITEM&KL_TRACE_ID=398B3426-DA81-4C7B-8814-262E71E16D0C&PAYLOAD=6E38BB8B8405042A505B761B1BF2BF0BBD8BBB968A24FB6F0FF3DF4A89D6427A&SID=300100&SIGNVERSION=1.0.0&TIMESTAMP=1633100416'
然后將這個值和y?sha256 得到最后的結(jié)果

這個站的加密不難就是惡心,很多邏輯都混淆過,就是讓你看起來麻煩
好了,以上就是今天的全部內(nèi)容了。
我是沒有更新就在摸魚的咸魚
收到請回復(fù)~
我們下次再見。
對了,看完記得一鍵四連,這個對我真的很重要。
