1. 程式人生 > 其它 >小小滑塊可笑可笑-安卓滑塊驗證碼通殺方案研究(1)

小小滑塊可笑可笑-安卓滑塊驗證碼通殺方案研究(1)

技術標籤:閒魚爬蟲pythonandroidjava

說明

文章首發於HURUWO的部落格小站,本平臺做同步備份釋出。
如有瀏覽或訪問異常圖片載入失敗或者相關疑問可前往原部落格下評論瀏覽。

小小滑塊可笑可笑-安卓滑塊驗證碼通殺方案研究(1)

直接點選即可前往訪問。

前言

通常我們在做自動化任務時候,經常會遇到一些驗證碼驗證。
其中遇到最多的還是滑塊驗證碼,下面我們來單獨探討這個滑塊的過程。

一些說明 因為滑塊通常是拼圖形式 或者是乾脆就是從左到右的滑動就行。

這裡只重點討論滑塊的滑部分 關於識別滑動位置 需要單獨開文章來講解

圖中的例子

由於CDN設定時間戳,圖片可能失效,請前往原文地址瀏覽

逆向抓包攔截方案(好用但不通用)

核心思想就是對驗證的頁面進行逆向分析,根據上傳的包資訊。分析出具體滑動的引數,直接偽造一條滑動引數過去。

伺服器後臺接收引數之後認為你已經滑動成功,代替手動滑過。

但是要做的這一點需要極高的知識儲備,需要很多的逆向知識。

優點是很快 很有針對性

缺點是

1.難度大 通常還有很多的引數校驗 需要一一破解

2.不夠通用也不夠靈活 一個新的app或者新的滑塊都需要重寫全部邏輯

所以我們探討一種通用的 滑動協議 就是使用自動化的方式代替我們去滑動。

自動化滑動方案(通用但是不夠好)

既然討論的是滑動 當然就是關於如何自動化而不是手動,不然所有討論都沒有意義。

關於自動化 類似的方案有:

1.adb
2.appium 測試框架 等 方案
3.無障礙 類似auto.js 等 方案

現在測試下三種方案的滑動程式碼

1.adb 滑動程式碼

adb shell input swipe 250 250 300 300

指的就是從 250,250 滑動到 300,300 座標 可以多段座標移動 勻速的

2.appium滑動程式碼

關於appium 我用的不多,我只能直接從網上抓到一部分程式碼

http://appium.io/ 文件裡關於滑動這一塊的:

Android 4.3+: 谷歌的 UiAutomator / UiAutomator2Android 2.3+: 谷歌的 Instrumentation. (通過繫結獨立的專案—— Selendroid 提供對 Instrumentation 的支援)

因為appium是基於谷歌的測試框架的 所以邏輯類似:

https://appium.io/docs/en/writing-running-appium/touch-actions/

https://appium.io/docs/en/writing-running-appium/android/android-mobile-gestures/

這是關於點選操作的文件地址

關於滑動手勢swipeGesture

該手勢在給定的元素/區域上執行滑動手勢。自Appium v​​1.19起可用

支援的引數
elementId:要刷卡的元素的ID。如果缺少元素ID,則必須提供滑動邊界區域。如果同時提供了元素ID和滑動邊界區域,則該區域將被有效忽略。
left:滑動邊界區域的左座標
top:滑動邊界區域的頂部座標
width:滑動邊界區域的寬度
height:滑動邊界區域的高度
方向:滑動方向。強制值。可接受的值為:up,down,left和right(不區分大小寫)
percent:滑動的大小佔滑動區域大小的百分比。有效值必須是0..1範圍內的浮點數,其中1.0是100%。強制值。
speed:執行此手勢的速度,以每秒畫素為單位。該值不能為負。預設值為5000 * displayDensity

程式碼示例:

((JavascriptExecutor) driver).executeScript("mobile: swipeGesture", ImmutableMap.of(
    "left", 100, "top", 100, "width", 200, "height", 200,
    "direction", "left",
    "percent", 0.75
));

同樣可以從a點移動到b點 速度也是勻速的。這裡額外的有一個傳入元素id功能,可以直接對應滑過指定控制元件,比adb更方便和高效一點。

3.無障礙的滑動程式碼

直接使用無障礙方式滑動,關於滑動這個動作。無障礙在7.0版本上新增了dispatchGesture 這個動作來來滑動。

具體可以這樣寫:

Path path1 = new Path();
                        path1.moveTo(x1, y1);
                        path1.lineTo(x1, y2);
 GestureDescription.Builder builder = new GestureDescription.Builder();
                        GestureDescription gestureDescription = builder
                                .addStroke(new GestureDescription.StrokeDescription(path1, 0, 1000))
                                .build();
                        service.dispatchGesture(gestureDescription, null, null);

這就從x1滑動到了x2了,甚至可以多家幾條path達到控制速度的調整。

                        int y1 = 800;
                        int y2 = 1000;
                        int x1 = 200;
                        int x2 = 400;
                        int x3 = 600;
                        int x4 = 800;

                        Path path1 = new Path();
                        path1.moveTo(x1, y1);
                        path1.lineTo(x1, y2);

                        Path path2 = new Path();
                        path2.moveTo(x1, y2);
                        path2.lineTo(x2, y2);

                        Path path3 = new Path();
                        path3.moveTo(x2, y2);
                        path3.lineTo(x4, y2);

                        GestureDescription.Builder builder = new GestureDescription.Builder();
                        GestureDescription gestureDescription = builder
                                .addStroke(new GestureDescription.StrokeDescription(path1, 1000, 1000))
                                .addStroke(new GestureDescription.StrokeDescription(path2, 1900, 1000))
                                .addStroke(new GestureDescription.StrokeDescription(path3, 2800, 1000))
                                .build();
                        service.dispatchGesture(gestureDescription, null, null);

三條路徑滑動 間隔連上就會變成一個了。但是系統做了限制,最多最多新增10條路徑,否則會丟擲異常。

測試滑動驗證效果

自行編寫的滑塊驗證碼

關於這一點 我為了方便快速測試,自己找了一些開源的驗證碼模組改了改。

通過要求只有一點: 只要使用者能從A劃到B點末端就算成功

三種方式的測試成功率都很高,因為這種簡單的從左滑到右都是秒過的。

至此大功告成,三種方案通殺了安卓客戶端的驗證碼模組(我以為)

第三方平臺驗證碼

這次挑了幾個大廠的app 故意跑出來驗證碼:

嘗試直接滑過,結果就是雖然滑倒了指定的地方。但是直接返回了一個大大的失敗二字。

這裡涉及的app有 快手 閒魚 小紅書等等幾大平臺。正因為我在做日常的閒魚爬蟲
以及更多資料爬蟲的時候會遇上這些煩人的滑塊。

驗證結果:

快手:失敗 100%
閒魚:失敗 100%
小紅書:失敗 100%

可知所有的app都能輕易的知道我是用自動化方式劃過的,而且直接拒絕了這次的滑動驗證請求。

分析失敗原因和解決思路

失敗原因:為何第三方app校驗不通過

在分析這個滑動校驗原理的過程中,我發現了一個專門做滑動驗證的廠商–極驗

http://www.geetest.com/

由於CDN設定時間戳,圖片可能失效,請前往原文地址瀏覽

在他的安全風控裡面我找到了一些有用的的資訊:

由於CDN設定時間戳,圖片可能失效,請前往原文地址瀏覽

原來這些驗證平臺不講武德,直接配合大資料和AI判斷了我的滑動軌跡。

由於CDN設定時間戳,圖片可能失效,請前往原文地址瀏覽

這種勻速的滑動根本過不了驗證平臺的校驗。

類似的還有數美 同盾 網易等驗證平臺

由於CDN設定時間戳,圖片可能失效,請前往原文地址瀏覽

解決方案:如何做出和真人一樣的滑動

首先可以認定的就是 那些普通的自動化工具只能做一些非常機械化的滑動,無論是勻速還是加速減速都顯得非常的機械化。

這種機械化的速度變化曲線會非常容易針對,只要做個簡單的校驗就可以攔住了。

所以我們追求一個更加顆粒度的滑動方案,不是平滑的滑動。也不是一段一段的滑動,而是精確度粒度達到一畫素一畫素的程度才行。

具體的策略如下:

  1. 生成符合規則的路徑曲線 模仿人類的速度 抖動等引數

  2. 使用畫素級別的顆粒度的滑動控制工具滑動介面滑塊

  3. 調整 適配 再生成曲線 再調整 再適配 提高成功率到滿意程度

總結

關於滑動驗證碼的探究方案到這裡了,至於如何做出畫素級別得到滑動看下下篇文章的分解。