起因
眾所周知淘寶滑塊很難過掉,今天博主就專門研究了一下淘寶滑塊,
之前博主也有研究過但是發現並不好過。
今天恰好有個項目需要淘寶登錄,就有滑塊驗證,
說明一下博主做的是瀏覽器插件哦。今天博主打算在研究滑塊。
記錄一下博主的解密過程。
排查
首先咱們打開淘寶登錄頁面,這里我就以阿里媽媽的超級推薦登錄為例登錄地址如下:登錄地址
打開之后我們來到輸入賬戶密碼的地方
由於要實現自動登錄的功能所以需要跟編輯框賦值,
但是淘寶是使用react寫的所以一般情況下是無法外部賦值的
在React和Vue如何使用原生JS賦值中我已經講過如何賦值了,這里就不在多講。
好了我們輸入一個a在用戶名的地方
可以看見滑塊已經出來了
分析
咱們f12打開開發者工具,選中滑塊拖動的span查看一下綁定事件
可以看到只綁定了一個鼠標按下事件,按照正常思路不是應該還有鼠標拖動事件嗎?
別急咱們進入代碼看一下
來到代碼可以看到是進入了i這個方法中,咱們往下找找,下面我把i方法貼出來
function i(i) {
function a() {
s.btn.onmousedown = null,
s.txt.onmousedown = null,
e.removeEvt(l, "mousemove", r),
e.removeEvt(l, "mouseup", f),
e.removeEvt(l, "touchmove", h),
e.removeEvt(l, "touchend", g),
e.removeEvt(s.btn, "touchstart", o),
e.removeEvt(s.txt, "touchstart", o);
var i = {};
i.btn = s.btn,
i.bar = s.bar.childNodes[1],
n(d.actionend),
n(d.slide_end),
t.onScaleReady(i)
}
function r(e) {
m || (n(d.actionstart),
n(d.slide_start),
m = !0);
var t = (e || p.event).clientX
, i = _.min(y, _.max(-2, k + (t - v)));
s.btn.style.left = i + "px",
s.ondrag(_.round(100 * _.max(0, i / y)), i);
var o = x + s.bar.offsetWidth;
if (t >= o && (i < y || t - k < y))
return void f.call(this);
var r = c.getClientRect(s.btn).left;
i != y && t - r - b != y || a()
}
function f() {
var t = parseInt(s.btn.style.left);
t < y && (c.addClass(s.btn, "button_move"),
c.addClass(e.id(u + "_bg"), "bg_move"),
s.btn.style.left = "0px",
s.ondrag(0, 0),
setTimeout(function() {
c.removeClass(s.btn, "button_move"),
c.removeClass(e.id(u + "_bg"), "bg_move")
}, 500)),
e.removeEvt(this, "touchmove", h),
e.removeEvt(l, "touchmove", h),
e.removeEvt(l, "mousemove", r),
e.removeEvt(l, "mouseup", f)
}
function g(e) {
f.call(this, e.touches[0])
}
function h(e) {
e.preventDefault(),
r.call(this, e.touches[0])
}
var m = !1
, v = (i || p.event).clientX
, b = s.btn.offsetWidth
, y = s.bar.offsetWidth - b
, k = s.btn.offsetLeft
, x = c.getClientRect(s.bar).left;
e.addHandler(l, "mousemove", r),
e.addHandler(l, "mouseup", f),
e.addHandler(l, "touchmove", h),
e.addHandler(l, "touchend", g)
}
仔細分析一下上面的代碼可以發現在咱們鼠標按下的時候綁定mousemove
事件也就是鼠標移動事件,
根據以上代碼來到r方法,仔細分析一下r方法的代碼。
可以發現這段代碼
var t = (e || p.event).clientX
獲取了e對象的clientX來進行對比,那么和誰對比呢?下面這句代碼是關鍵
i = _.min(y, _.max(-2, k + (t - v)));
可以看到t-v是取出了差來進行對比的,那么t可以在方法中看到但是v變量呢?
仔細看一下綁定事件之前的代碼可以發現,v是咱們按下時的坐標
v = (i || p.event).clientX
通過上面的分析可以得到的是,鼠標按下獲取了鼠標按下的坐標並綁定了事件。
咱們拖動的時候一直在計算鼠標的差,到這里懂的人應該都可以分析出來了。
沒錯,就是取差來判斷是否拖動到了指定的長度
咱們繼續分析,可以看到r方法最后一句
i != y && t - r - b != y || a()
i!=y就不管他,那么i==y就進入a方法,咱們來看一下y變量在哪里
var m = !1
, v = (i || p.event).clientX
, b = s.btn.offsetWidth
, y = s.bar.offsetWidth - b
, k = s.btn.offsetLeft
, x = c.getClientRect(s.bar).left;
可以看到y其實就是取的容器的長度減去b的長度,而b就是滑塊的長度。
由此已經可以看出來了最關鍵的過程。
處理
好了上面已經分析出過程了,所以咱們接下來寫代碼過掉滑塊
第一步,觸發滑塊id為nc_1_n1z
的mousedown
事件,這里直接觸發
event = document.createEvent('MouseEvents');
event.initEvent('mousedown', true, false);
document.querySelector("#nc_1_n1z").dispatchEvent(event);
在觸發這個事件之后nc_1_n1z
就綁定了mousemove
事件,這里咱們先不觸發,可以把鼠標移上去
在把鼠標移入網頁的一瞬間可以看到滑塊已經過掉了。看懂上面分析過程的孩紙應該都知道這是為什么
好了下面咱們在觸發一下mousemove
事件
event = document.createEvent('MouseEvents');
event.initEvent('mousemove', true, false);
Object.defineProperty(event,'clientX',{get(){return 260;}})
document.querySelector("#nc_1_n1z").dispatchEvent(event);
通過上面的執行可以看到滑塊一下子就過掉了。好了,咱們把代碼合並一下
event = document.createEvent('MouseEvents');
event.initEvent('mousedown', true, false);
document.querySelector("#nc_1_n1z").dispatchEvent(event);
event = document.createEvent('MouseEvents');
event.initEvent('mousemove', true, false);
Object.defineProperty(event,'clientX',{get(){return 260;}})
document.querySelector("#nc_1_n1z").dispatchEvent(event);
下面看一下效果