1. 移动端风控的“眼睛”与“大脑”:Sensor与BMP初探

大家好,我是老张,在反爬和风控这个领域里摸爬滚打了十来年,跟Akamai、Cloudflare这些“老朋友”没少打交道。今天咱们不聊那些云里雾里的概念,就坐下来,泡杯茶,掰开揉碎了聊聊Akamai在移动端是怎么“看”我们,又是怎么“想”的。核心就两个东西:Sensor(传感器)BMP。你可以把Sensor理解成风控系统的“眼睛”和“耳朵”,它一刻不停地收集你手机的各种细微动作;而BMP呢,就是背后的“大脑”,它处理这些信息,判断你是真人还是机器。

很多刚接触的朋友一听到“风控”、“指纹”就觉得头大,觉得是黑盒,深不可测。其实不然,你把它想象成一个经验老道的保安。一个真人用户操作手机,手指滑动有加速度变化,拿起放下手机有角度偏移,这些动作是连续、自然且带有微小随机性的。而一个自动化脚本或者模拟器,其发出的“动作指令”往往是刻板、精准、缺乏生命感的。Akamai的Sensor数据采集,目的就是捕捉这种“生命感”。它不仅仅收集你点了哪里(Touch Event),更收集你是怎么点的——滑动过程中的加速度变化(陀螺仪)、手机的姿态角度(方向传感器)、甚至一系列连贯操作的时间序列。这些数据经过复杂的算法加工,生成一串独一无二的、表征你当前操作行为的“行为指纹”。

那么BMP又是什么呢?在Akamai的语境里,BMP(Bot Manager Premier)是其顶级的机器人管理解决方案。我们这里讨论的“BMP风控机制”,可以狭义地理解为运行在你设备上的一段JavaScript代码(在Web端)或SDK(在App内)所执行的一整套逻辑。这套逻辑负责调度Sensor采集,对原始数据进行加密、打包,并最终生成那个关键的 x-acf-sensor-data 请求头。服务器拿到这个头,解密后送入风控模型进行评分。所以,整个流程就是:Sensor采集 -> 本地BMP逻辑处理(计算、加密) -> 上传 -> 服务器端风控模型决策。理解了这个闭环,我们才能有的放矢。

2. Sensor数据采集:你的手机正在“告密”

这一节,我们深入“眼睛”和“耳朵”的内部,看看Akamai到底在收集什么。根据我逆向和分析的经验,移动端的Sensor采集远比PC端复杂和精细,因为它能调用的硬件传感器更多。

2.1 核心传感器数据采集

移动端BMP主要盯上了以下几类传感器数据,这些都是模拟器或者纯脚本容易露馅的地方:

  1. 陀螺仪(Gyroscope):测量设备围绕三个轴(x, y, z)的旋转角速度。简单说,就是你转动手机的快慢和方向。真人操作时,即使是想直线滑动,手腕的微小抖动也会让陀螺仪产生细微但连续的数据流。模拟器生成这类数据要么是完美的零(静止),要么是生硬的固定值。
  2. 加速度计(Accelerometer)方向传感器(Orientation):这两者经常一起工作。加速度计测量设备的线性加速度(包括重力),方向传感器则提供设备相对于地磁北和重力方向的姿态(偏航、俯仰、横滚)。你拿起手机、倾斜屏幕观看、放下手机,这一系列动作都会被忠实记录。原始文章代码片段中的 sensorR3sensorR0 很可能就分别对应着方向传感器和陀螺仪处理后的数据对象。
  3. 运动传感器(Motion):这是一个更上层的抽象,可能融合了加速度计、陀螺仪甚至磁力计的数据,提供更直接的运动状态信息,比如设备是否在移动、摇晃。
  4. 触摸与移动事件(Touch/Move Events):这是基础但至关重要的一环。BMP会监听所有的 touchstart, touchmove, touchend 事件,记录每个事件的坐标、时间戳(精确到毫秒甚至微秒)、触发目标元素等。它特别关注事件之间的时间间隔和轨迹。真人滑动轨迹是贝塞尔曲线,带有加速度和减速度;脚本生成的轨迹往往是匀速直线或者简单的数学曲线。

原始文章给出的代码片段很有代表性,我们拆解一下:

str += '-1,2,-94,-111,'; //TAG
str += sensorR3.a.a; //方向传感器数据 A
str += '-1,2,-94,-109,'; //tag
str += sensorR0.a.a; //陀螺仪数据
// ... 后续还有 sensorR3.a.c, sensorR3.a.b 等

这里的 -1,2,-94,-111 这类标签(TAG)就像是数据字段的ID,告诉服务器后面跟着的是什么类型的数据。sensorR3.a.asensorR3.a.bsensorR3.a.c 很可能对应方向传感器处理后的不同维度的值(比如欧拉角或四元数的各个分量)。关键点在于:这些传感器数据并不是直接上传原始值,而是经过了一套浮点算法的预处理。这套算法可能包括归一化、平滑滤波、特征提取等,目的就是将一个连续时间序列的传感器读数,转化成一个或一组能够表征本次操作特征的“指纹值”。逆向这套算法是模拟数据的难点所在。

2.2 设备信息与环境数据

除了动态的行为数据,BMP还会收集一份相对静态的“设备档案”,这与Web端的指纹收集类似,但在移动端维度更多:

  • 基础设备信息:机型、操作系统版本、屏幕分辨率、像素密度、设备名称(如iPhone14,2)。
  • 性能参数:CPU核心数、内存大小、GPU渲染器信息。模拟器与真机在这些参数上常有固定模式或差异。
  • 传感器可用性列表:检查陀螺仪、加速度计、磁力计、距离传感器等是否存在。模拟器可能缺少某些传感器,或者返回固定的“存在”状态。
  • WebView/浏览器环境(针对H5):User-Agent、Canvas指纹、WebGL指纹、字体列表、AudioContext指纹等。这就是为什么原始文章提到“设备信息会跟finger canvas一起注册,可能会产生关联”。

所有这些信息,会被拼接成一个长字符串,并参与校验位的计算。原始文章中 deviceInfo 的生成代码片段就展示了这一点:它包含了随机数、时间戳处理后的值等,最终与其他数据合并。

3. BMP的核心处理流程:从采集到加密上传

Sensor数据采集上来后,BMP并不会立刻发送。它会在本地进行一系列复杂的操作,我把它总结为“计算、加密、打包”三步曲。这个过程是风控逻辑的核心,也是触发BAN的关键环节。

3.1 校验位的生成与作用

这是最容易导致BAN的环节之一。原始文章明确指出:“校验位不对”是首要原因。什么是校验位?你可以把它理解为这包数据的“防伪码”或“摘要”。

BMP会将采集到的所有数据——包括传感器数据、设备信息、时间戳、甚至一些内部状态变量——按照特定顺序拼接起来,然后通过一个不可逆的哈希算法(可能是自定义的变形算法)计算出一个或多个校验值。在原始文章代码中,我们看到:

let total_b = o.d + motions.b + sensorR3.b + sensorR0.b;
let total_c = sensorR0.c + sensorR3.c + motions.j + o.ch;

这里的 total_btotal_c 很可能就是两种不同维度的校验和。o.d, motions.b, sensorR3.b 这些 .b.c 属性,很可能就是各类数据经过初步计算后得到的中间校验值或特征值,它们再经过组合运算,生成最终的校验位。

为什么校验位如此重要? 服务器端拥有同样的算法。它收到数据包后,会用自己的算法重新计算一遍校验位,并与上传数据中的校验位进行比对。如果不匹配,服务器立刻就能断定数据在传输过程中被篡改,或者根本不是由合法的BMP代码生成的,从而直接BAN掉请求。这就像你寄出一封信,信封上有特殊的火漆印章,收信人核对印章真伪,不对就直接拒收。

3.2 加密流程深度解析

数据在离开设备前必须加密,否则在网络上裸奔毫无意义。Akamai采用了一套混合加密策略来保证安全。

  1. 生成会话密钥:在每次会话(或每次需要发送Sensor数据时),BMP代码会在本地生成一对临时的AES对称密钥RSA非对称密钥对。AES用于高效加密大量的传感器数据,RSA则用于加密AES密钥本身。
  2. 数据打包与加密
    • 将传感器数据、设备信息、校验位等,按照固定格式打包成一个数据块(pack数据)。
    • 使用随机生成的AES密钥对这个数据块进行加密,得到密文A。
    • 使用服务器提供的RSA公钥(或硬编码在代码中的公钥)加密刚才生成的AES密钥,得到密文B。
  3. 组装最终载荷:最终要发送的 x-acf-sensor-data 头的内容,通常就是密文A和密文B的某种组合(可能是Base64编码后的拼接)。这样,只有拥有对应RSA私钥的Akamai服务器才能解密出AES密钥,进而解密出真实的传感器数据。

原始文章提到的“生产aeskey和rsakey,放入到pack数据中进行加密后,通过key来加密sensor数据后暂放缓冲区”,描述的就是这个过程。这个加密流程确保了即使请求被拦截,攻击者也无法直接读取或篡改传感器数据。

3.3 数据上传的节奏与缓冲区管理

BMP并不是每次用户交互都立刻上传数据,那样开销太大且不必要。它采用了一种缓冲池机制

  • 收集阶段:用户开始与受保护的页面或应用交互时,BMP开启Sensor监听,将加密后的数据包放入一个本地缓冲区。
  • 上传触发:当满足特定条件时(例如缓冲区满了、达到特定时间、发生关键事件如提交表单),BMP会取出缓冲区中的所有数据,组装成最终的 x-acf-sensor-data 头部,随业务请求(如登录、下单)一起发送。
  • 清空与重置:数据发送后,缓冲区被清空,Sensor收集继续,为下一次上传做准备。原始文章提到“每200多次收集后关闭”,这个“200多次”可能是一个阈值,防止无限收集占用资源,到达阈值后可能会暂时关闭高频率的Sensor采集,或进行一轮数据清理和重置。

理解这个节奏很重要。这意味着你模拟的数据不能只针对一次点击,而需要模拟一个会话期内连续、合理的一系列事件,并按照正确的节奏打包上传。

4. 触发BAN的常见原因分析与实战避坑指南

知道了原理,我们来看看实践中最容易踩的坑。根据我的经验以及原始文章的总结,被Akamai BMP风控拦截,九成以上逃不出下面这几个原因。

4.1 校验位与时间差:两大“低级错误”

  • 校验位不对:这是最直接的死刑判决。导致的原因有:

    • 算法模拟错误:你自己逆向的校验位生成算法有细微偏差。可能某个常量的值不对,或者数据拼接的顺序错了,甚至哈希算法的一个初始参数弄错了。
    • 数据源缺失或错误:你的模拟数据缺少了某个BMP会收集的字段。比如,你只模拟了陀螺仪,却漏了方向传感器,那么用完整算法算出来的校验位肯定对不上。
    • 环境动态变量:算法中引入了一些你未捕获的动态变量,比如设备启动后的毫秒数、某个未公开的全局计数器。 避坑指南:逆向时务必进行“差分分析”。在相同操作下,多次捕获合法的Sensor数据包,对比差异,找出哪些部分变化、哪些部分不变。重点攻击那些不变的、看起来像算法常量的部分,以及变化但有规律的部分(如时间戳)。
  • 时间差不对:这里的时间差有多层含义。

    1. 事件间时间戳差:你模拟的两次 touchmove 事件间隔是恒定的10毫秒,这太假了。真人操作有快有慢,间隔应符合某种概率分布(如正态分布)。
    2. 传感器数据时间同步差:陀螺仪、加速度计的数据理论上应该是同一时刻采集的,它们的时间戳应该高度同步或存在固定的微小偏移。如果你模拟的数据中,这两种数据的时间戳对不上,就会被识别为伪造。
    3. 客户端与服务器时间差:数据包中可能包含客户端当前时间。如果这个时间与服务器接收时间相差过大(比如超过几分钟),可能被视为异常请求。需要保证设备时间基本同步。 避坑指南:使用高精度计时器来生成事件时间戳,并引入符合人类行为的随机延迟。对于传感器数据,确保所有模拟数据引用同一个基准时间源。

4.2 数据逻辑性与真实性:魔鬼在细节里

  • 数据不符合物理规律:这是模拟传感器数据时最难的部分。例如:
    • 手机从静止到快速移动,加速度计数据应该平滑变化,而不是阶跃跳变。
    • 陀螺仪测量的角速度积分后应该能大致反映手机姿态的变化,与方向传感器数据不能有根本性矛盾。
    • 触摸轨迹的坐标变化速度(由触摸事件时间戳算出)与加速度计测得的手机实际移动速度应大致吻合。如果手指在屏幕上飞驰,但加速度计显示手机静止,这就矛盾了。
  • 设备信息与传感器能力矛盾:你报告的设备型号是高端iPhone,但传感器列表里却没有陀螺仪,这说不通。或者,你上报的屏幕分辨率与通过其他API(如Canvas)探测到的分辨率不一致。
  • 行为模式异常:原始文章提到的“事件收集不够”就属于此类。BMP可能要求一个表单提交操作前,必须有至少N次的焦点变化、鼠标移动(或触摸移动)等预备事件。你的脚本如果直接click提交按钮,缺少前置事件流,就会被判定为非人类。

避坑指南:不要试图完美模拟所有物理规律,那几乎不可能。重点是避免明显的矛盾。可以尝试从真实设备上录制一段传感器和触摸事件的数据流,然后在这个“模板”基础上进行小幅度的、合理的随机化修改,这样生成的数据在逻辑上更自洽。

4.3 指纹关联性与环境一致性

原始文章在QA部分提到了一个关键点:“设备信息会跟finger canvas一起注册,可能会产生关联”。这就是环境一致性问题。

Akamai的风控是立体的。它不仅仅看一次请求的Sensor数据,还会将这次请求的浏览器指纹/设备指纹与历史记录进行关联。如果你使用一个全新的、从未见过的浏览器指纹,但配上了一套看似完美的Sensor数据,这本身可能就是一个风险信号。反之,如果一个之前表现良好的指纹,突然其Sensor数据模式发生剧变,也会引起怀疑。

避坑指南:维持指纹的稳定性。如果可能,尽量复用或小范围修改一个真实的、经过验证的设备指纹。避免每次请求都使用完全随机的、全新的指纹。建立你的“指纹池”,让不同的请求看起来像是来自一个真实、稳定的设备群体。

5. 从防御到进攻:构建自有风控系统的思路

研究Akamai,最终目的除了“绕过”,更有价值的是“学习”。对于有自建风控需求的开发者(比如电商防爬、防刷、防作弊),Akamai的这套思路提供了绝佳的范本。原始文章最后也抛出了这个方向,我来展开聊聊我的实战思考。

5.1 设计基石:多维数据采集与可信基线

自建风控,第一步不是写复杂的算法,而是想清楚采集什么以及什么是正常的

  • 数据采集层:你可以借鉴但不必照搬Akamai。对于你的业务,关键数据可能包括:
    • 客户端基础信息:IP、User-Agent、设备基础信息(通过JavaScript或App SDK收集)。
    • 行为序列:页面访问路径、鼠标移动轨迹、点击位置序列、停留时间、输入速度(特别是验证码输入)。这些比传感器数据更容易采集且成本低。
    • 业务关联数据:账号历史行为、本次操作的特征(如秒杀请求的商品ID、时间点)。
    • 网络层特征:TCP/IP指纹、TLS指纹、请求包时序。这在高级对抗中很有效。
  • 建立可信基线:通过大量标注的正常用户数据,为每个数据维度建立“正常范围”。比如,真人从商品列表页点击到详情页的平均耗时是X秒,标准差是Y秒。这就是一个简单的基线。

5.2 核心引擎:规则引擎与机器学习模型双驱动

这是风控系统的“大脑”。我强烈建议采用混合模式,而不是单一依赖某一种技术。

  • 规则引擎(快速响应):处理明确的、已知的恶意模式。规则可以非常直观有效:
    • 基础校验规则:如原始文章所说,“校验时间差,校验数据是否human”。例如:两次请求间隔小于100毫秒(人类不可能做到);鼠标移动轨迹为完美的直线或几何图形。
    • 业务规则:同一个IP在1秒内注册了10个账号;一个新设备首次登录就进行大额转账。 规则引擎的优势是速度快、解释性强,能立刻拦截已知威胁。
  • 机器学习模型(深度挖掘):用于发现未知的、复杂的恶意模式。这也是原始文章提到的“利用真实数据来训练模型”。
    • 特征工程:将采集的原始数据(如鼠标移动坐标序列)转化为模型可理解的特征,例如移动速度的均值/方差、加速度的变化率、轨迹的曲率特征等。
    • 模型选择:对于时序行为数据,可以尝试LSTM等循环神经网络;对于综合特征,GBDT(如XGBoost)、随机森林或深度学习分类模型都可以。
    • 持续迭代:用模型对请求进行评分(如0-100分,分数越高风险越大),将模型判定为可疑但规则未拦截的请求,加入人工审核队列,不断用新数据反馈训练模型。

5.3 系统架构:评分、决策与信用体系

一个完整的风控系统不是一次性判断,而是一个持续的评估过程。

  1. 实时评分管道:每个请求经过数据采集层后,流入实时计算管道。管道内并行运行规则引擎和多个机器学习模型(原始文章提到的“2套风控model”思路很好)。每个组件输出自己的风险分数或标签。
  2. 决策中心:根据预设策略,综合所有组件的输出做出最终决策。策略可以是:任何一条高风险规则命中则直接拦截;或模型A评分>90且模型B评分>85则拦截;或加权平均分超过阈值则要求二次验证(如滑块验证码)。
  3. 信用与关联系统:这是构建长期防御壁垒的关键。原始文章最后一点非常到位:构建账号信用系统。
    • 不仅对单次请求评分,更为每个用户ID、设备指纹、IP地址建立长期的行为档案和信用分。
    • 一次恶意行为会导致关联实体(账号、设备、IP)的信用分下降。
    • 后续请求的决策,会参考该实体的历史信用分。一个信用分极低的设备发起的请求,即使单次行为看起来正常,也可能被施加更严格的检查或直接限制。
    • 通过图数据库分析账号、设备、IP、支付工具之间的关联关系,挖掘团伙作恶。

踩过的坑提醒:自建风控初期,最容易犯两个错误。一是过度拦截,规则设得太严,误伤正常用户,影响业务。一定要设置完善的报警和人工复核通道,并定期回顾误杀案例。二是静态对抗,以为上线一套规则就一劳永逸。对抗是动态的,黑产会快速适应。你必须建立数据闭环,定期分析攻击日志,迭代规则和模型。风控的本质是一场持续的成本与技术的博弈。从理解Akamai这样的顶级玩家开始,逐步构建适合自己业务规模和风险承受能力的防御体系,这条路虽然漫长,但每一步都算数。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐