小小滑块可笑可笑-安卓滑块验证码通杀方案研究(1)

前言

通常我们在做自动化任务时候,经常会遇到一些验证码验证。
其中遇到最多的还是滑块验证码,下面我们来单独探讨这个滑块的过程。

一些说明 因为滑块通常是拼图形式 或者是干脆就是从左到右的滑动就行。

这里只重点讨论滑块的滑部分 关于识别滑动位置 需要单独开文章来讲解

图中的例子

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

核心思想就是对验证的页面进行逆向分析,根据上传的包信息。分析出具体滑动的参数,直接伪造一条滑动参数过去。

服务器后台接收参数之后认为你已经滑动成功,代替手动滑过。

但是要做的这一点需要极高的知识储备,需要很多的逆向知识。

优点是很快 很有针对性

缺点是

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/

在他的安全风控里面我找到了一些有用的的信息:

原来这些验证平台不讲武德,直接配合大数据和AI判断了我的滑动轨迹。

这种匀速的滑动根本过不了验证平台的校验。

类似的还有数美 同盾 网易等验证平台

解决方案:如何做出和真人一样的滑动

首先可以认定的就是 那些普通的自动化工具只能做一些非常机械化的滑动,无论是匀速还是加速减速都显得非常的机械化。

这种机械化的速度变化曲线会非常容易针对,只要做个简单的校验就可以拦住了。

所以我们追求一个更加颗粒度的滑动方案,不是平滑的滑动。也不是一段一段的滑动,而是精确度粒度达到一像素一像素的程度才行。

具体的策略如下:

  1. 生成符合规则的路径曲线 模仿人类的速度 抖动等参数
  2. 使用像素级别的颗粒度的滑动控制工具滑动界面滑块
  3. 调整 适配 再生成曲线 再调整 再适配 提高成功率到满意程度

总结

关于滑动验证码的探究方案到这里了,至于如何做出像素级别得到滑动看下下篇文章的分解。