【??作者主頁】:吳秋霖
【??作者介紹】:擅長爬蟲與JS加密逆向分析!Python領(lǐng)域優(yōu)質(zhì)創(chuàng)作者、CSDN博客專家、阿里云博客專家、華為云享專家。一路走來長期堅(jiān)守并致力于Python與爬蟲領(lǐng)域研究與開發(fā)工作!
【??作者推薦】:對(duì)爬蟲領(lǐng)域以及JS逆向分析感興趣的朋友可以關(guān)注《爬蟲JS逆向?qū)崙?zhàn)》《深耕爬蟲領(lǐng)域》
未來作者會(huì)持續(xù)更新所用到、學(xué)到、看到的技術(shù)知識(shí)!包括但不限于:各類驗(yàn)證碼突防、爬蟲APP與JS逆向分析、RPA自動(dòng)化、分布式爬蟲、Python領(lǐng)域等相關(guān)文章
作者聲明:文章僅供學(xué)習(xí)交流與參考!嚴(yán)禁用于任何商業(yè)與非法用途!否則由此產(chǎn)生的一切后果均與作者無關(guān)!如有侵權(quán),請(qǐng)聯(lián)系作者本人進(jìn)行刪除!
1. 寫在前面
??上次周六的時(shí)候熬夜分析還原了一下商家后臺(tái)的Anti-Content,那個(gè)參數(shù)是0aq開頭的,本次的話應(yīng)粉絲要求對(duì)批發(fā)網(wǎng)站進(jìn)行了同樣的參數(shù)分析,與其不同的是參數(shù)開頭為0ar
分析目標(biāo):
aHR0cHM6Ly9waWZhLnBpbmR1b2R1by5jb20v
老規(guī)矩,開局先放一張結(jié)果圖,后續(xù)內(nèi)容全靠編?。?!
另外,對(duì)之前商家端Anti-Content參數(shù)分析感謝的,請(qǐng)看這篇文章:最新商家后臺(tái)Anti-Content參數(shù)逆向分析與純算法還原
2. 接口分析
主要通過商品搜索入口展開分析,然后到商品詳情。首先,還是老規(guī)矩打開網(wǎng)站隨便找個(gè)商品搜索一下,不出意料開局也是給了我一張圖,據(jù)說多多的批發(fā)目前的風(fēng)控是極其強(qiáng)的,我就分析測試了一下,黑了我一個(gè)號(hào)?。?!
如果你看到你的頁面一直是提示操作太過頻繁,請(qǐng)稍后再試!之后頁面就試一片空白,所有的功能都用不了
這個(gè)滑塊的話,問題不大。有實(shí)力的話可以分析研究一下。我的話,沒有實(shí)力,直接頁面手動(dòng)拖動(dòng)一下,不然接口后續(xù)請(qǐng)求基本如下:
{result":{“verifyAuthToken”:“309dYy7ZgpWuk00cOyrgcQ3bed9a9ba4fdagfc7”},“error code”:54001, “error msa”:“”}
在此過程中我發(fā)現(xiàn)了一個(gè)特別迷惑的行為,就是出現(xiàn)滑塊之后,網(wǎng)站頁面,并沒有彈出滑塊的圖,但是重新執(zhí)行程序,接口不出滑塊,正??梢哉?qǐng)求到數(shù)據(jù)
我不知道是不是session的問題,但是就算重新執(zhí)行程序,過程中比如在搜索提交一定次數(shù)后,同樣會(huì)再次出現(xiàn)滑塊反饋
直到最后,你的網(wǎng)頁它也給你彈出了滑塊,這個(gè)時(shí)候,更夢(mèng)幻的就來了,你會(huì)發(fā)現(xiàn)瀏覽器觸發(fā)一次滑塊后,直接手過一下,拿參數(shù)下來用后續(xù)不會(huì)再出滑塊
為了驗(yàn)證這個(gè)問題,我掛了程序一段時(shí)間,訪問正常、搜索正常、詳情頁商品數(shù)據(jù)獲取正常
說了這么多題外話,只是為了給大家一點(diǎn)踩過的坑。下面我們還是回到正題,如下所示:
參數(shù)沒有啥加密的,主要的還是頭部這個(gè)Anti-Content的參數(shù)加密,解決了它就邁過了第一重大山
再看一下響應(yīng)數(shù)據(jù),圖中標(biāo)注的字段在詳情頁接口請(qǐng)求中會(huì)用到
3. 分析與扣代碼
跟商家端一樣,我們搜索參數(shù),然后斷點(diǎn)開始調(diào)試分析。這里還是Webpack,所以我們找到入口,把自執(zhí)行函數(shù)扣下來,Webpack最基本的組成就是自執(zhí)行函數(shù)跟模塊加載器!
之后把函數(shù)的實(shí)參,全部導(dǎo)出來放到自執(zhí)行調(diào)用函數(shù)下,因?yàn)楸旧碚{(diào)用執(zhí)行的就是一堆函數(shù),只不過都是索引的方式
分析調(diào)試找到自執(zhí)行函數(shù),把代碼扣出來,如下所示:
!function(e) {
function t(t) {
for (var n, o, d = t[0], f = t[1], i = t[2], u = 0, s = []; u < d.length; u++)
o = d[u],
Object.prototype.hasOwnProperty.call(c, o) && c[o] && s.push(c[o][0]),
c[o] = 0;
for (n in f)
Object.prototype.hasOwnProperty.call(f, n) && (e[n] = f[n]);
for (l && l(t); s.length; )
s.shift()();
return a.push.apply(a, i || []),
r()
}
function r() {
for (var e, t = 0; t < a.length; t++) {
for (var r = a[t], n = !0, o = 1; o < r.length; o++) {
var f = r[o];
0 !== c[f] && (n = !1)
}
n && (a.splice(t--, 1),
e = d(d.s = r[0]))
}
return e
}
var n = {}
, o = {
21: 0
}
, c = {
21: 0
}
, a = [];
function d(t) {
if (n[t])
return n[t].exports;
var r = n[t] = {
i: t,
l: !1,
exports: {}
};
return e[t].call(r.exports, r, r.exports, d),
r.l = !0,
r.exports
}
d.e = function(e) {
var t = [];
o[e] ? t.push(o[e]) : 0 !== o[e] && {
1: 1,
10: 1,
11: 1,
12: 1,
14: 1,
15: 1,
17: 1
}[e] && t.push(o[e] = new Promise((function(t, r) {
for (var n = "static/css/" + ({
7: "AccountCenter",
8: "Activity",
9: "BestGoods",
10: "Cart",
11: "GoodsDetail",
12: "GoodsDropShipping",
13: "Home",
14: "Mall",
15: "MallSearch",
16: "NotFound",
17: "Order",
18: "Payment",
19: "Search"
}[e] || e) + "." + {
0: "31d6cfe0d",
1: "1bb732cb7",
2: "31d6cfe0d",
3: "31d6cfe0d",
4: "31d6cfe0d",
5: "31d6cfe0d",
6: "31d6cfe0d",
7: "31d6cfe0d",
8: "31d6cfe0d",
9: "31d6cfe0d",
10: "86909bf59",
11: "1405928aa",
12: "9eff41d5d",
13: "31d6cfe0d",
14: "941e90c52",
15: "86909bf59",
16: "31d6cfe0d",
17: "07dca30ce",
18: "31d6cfe0d",
19: "31d6cfe0d",
23: "31d6cfe0d",
24: "31d6cfe0d",
25: "31d6cfe0d",
26: "31d6cfe0d",
27: "31d6cfe0d",
28: "31d6cfe0d",
29: "31d6cfe0d",
30: "31d6cfe0d"
}[e] + ".chunk.css", o = d.p + n, c = document.getElementsByTagName("link"), a = 0; a < c.length; a++) {
var f = (u = c[a]).getAttribute("data-href") || u.getAttribute("href");
if ("stylesheet" === u.rel && (f === n || f === o))
return t()
}
var i = document.getElementsByTagName("style");
for (a = 0; a < i.length; a++) {
var u;
if ((f = (u = i[a]).getAttribute("data-href")) === n || f === o)
return t()
}
var l = document.createElement("link");
l.rel = "stylesheet",
l.type = "text/css",
l.onload = t,
l.onerror = function(t) {
var n = t && t.target && t.target.src || o
, c = new Error("Loading CSS chunk " + e + " failed.\n(" + n + ")");
c.request = n,
r(c)
}
,
l.href = o,
document.getElementsByTagName("head")[0].appendChild(l)
}
)).then((function() {
o[e] = 0
}
)));
var r = c[e];
if (0 !== r)
if (r)
t.push(r[2]);
else {
var n = new Promise((function(t, n) {
r = c[e] = [t, n]
}
));
t.push(r[2] = n);
var a, f = document.createElement("script");
f.charset = "utf-8",
f.timeout = 120,
d.nc && f.setAttribute("nonce", d.nc),
f.src = function(e) {
return d.p + "static/js/" + ({
7: "AccountCenter",
8: "Activity",
9: "BestGoods",
10: "Cart",
11: "GoodsDetail",
12: "GoodsDropShipping",
13: "Home",
14: "Mall",
15: "MallSearch",
16: "NotFound",
17: "Order",
18: "Payment",
19: "Search"
}[e] || e) + "." + {
0: "f10cbb13",
1: "1f11793f",
2: "377e6d6e",
3: "35ce66b2",
4: "067dc63d",
5: "faf75b50",
6: "c87ff2b9",
7: "5a36fa8d",
8: "3e335bc4",
9: "419b7116",
10: "3088d3ab",
11: "39a585d4",
12: "d07a6c4a",
13: "20c6d848",
14: "30a72180",
15: "53f0e801",
16: "bd04a08e",
17: "319b16be",
18: "135c3c2b",
19: "66b54e82",
23: "c46b72b3",
24: "bcfa92ac",
25: "dbb47e8b",
26: "8b9ca1c3",
27: "1e9746e3",
28: "73b775ab",
29: "c13c09f3",
30: "ca572efb"
}[e] + ".chunk.js"
}(e);
var i = new Error;
a = function(t) {
f.onerror = f.onload = null,
clearTimeout(u);
var r = c[e];
if (0 !== r) {
if (r) {
var n = t && ("load" === t.type ? "missing" : t.type)
, o = t && t.target && t.target.src;
i.message = "Loading chunk " + e + " failed.\n(" + n + ": " + o + ")",
i.name = "ChunkLoadError",
i.type = n,
i.request = o,
r[1](i)
}
c[e] = void 0
}
}
;
var u = setTimeout((function() {
a({
type: "timeout",
target: f
})
}
), 12e4);
f.onerror = f.onload = a,
document.head.appendChild(f)
}
return Promise.all(t)
}
,
d.m = e,
d.c = n,
d.d = function(e, t, r) {
d.o(e, t) || Object.defineProperty(e, t, {
enumerable: !0,
get: r
})
}
,
d.r = function(e) {
"undefined" !== typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
value: "Module"
}),
Object.defineProperty(e, "__esModule", {
value: !0
})
}
,
d.t = function(e, t) {
if (1 & t && (e = d(e)),
8 & t)
return e;
if (4 & t && "object" === typeof e && e && e.__esModule)
return e;
var r = Object.create(null);
if (d.r(r),
Object.defineProperty(r, "default", {
enumerable: !0,
value: e
}),
2 & t && "string" != typeof e)
for (var n in e)
d.d(r, n, function(t) {
return e[t]
}
.bind(null, n));
return r
}
,
d.n = function(e) {
var t = e && e.__esModule ? function() {
return e.default
}
: function() {
return e
}
;
return d.d(t, "a", t),
t
}
,
d.o = function(e, t) {
return Object.prototype.hasOwnProperty.call(e, t)
}
,
d.p = "https://mms-static.pddpic.com/wholesale/",
d.oe = function(e) {
throw console.error(e),
e
}
;
var f = window.webpackJsonp = window.webpackJsonp || []
, i = f.push.bind(f);
f.push = t,
f = f.slice();
for (var u = 0; u < f.length; u++)
t(f[u]);
var l = i;
r()
}([]);
如果加載器函數(shù)與執(zhí)行對(duì)象在一個(gè)文件中的Webpack就會(huì)比較好扣,首先,在函數(shù)內(nèi)找到模塊加載器的特征位置,代碼如下所示:
function d(t) {
if (n[t])
return n[t].exports;
var r = n[t] = {
i: t,
l: !1,
exports: {}
};
return e[t].call(r.exports, r, r.exports, d),
r.l = !0,
r.exports
}
上面這個(gè)t傳入的可以是索引和對(duì)象的key,參數(shù)表示的是列表或?qū)ο蟮男螀?,接下來需要把目?biāo)扣出來,自執(zhí)行函數(shù)只是其中的一步,傳入的t才是關(guān)鍵,如下跳轉(zhuǎn):
直接把所有調(diào)用模塊導(dǎo)出來,放到自執(zhí)行的[]內(nèi),如下所示:
最后我們將算法的調(diào)用集成到Python程序中測試一下效果,如下:文章來源:http://www.zghlxwxcb.cn/news/detail-853288.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-853288.html
到了這里,關(guān)于最新PDD批發(fā)Anti-Content參數(shù)逆向分析與算法還原的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!