博客

Pokémon Go API – 深入了解自动攻击

F5 缩略图
F5
2016 年 8 月 16 日发布

数千万人正在探索 Pokémon Go 的新世界。 事实证明,许多用户根本不是人,而是自动代理或机器人。 游戏机器人并不是一个新现象,但 Pokémon Go 为机器人提供了一些新的用例。 这些机器人开始通过自动流量淹没 Pokémon Go 服务器,干扰大家的乐趣。 Pokémon Go 是研究自动攻击和防御如何针对移动 API 发挥作用的完美案例。 在 Shape,我们每天都会处理此类攻击,因此我们想仔细研究一下 Pokémon Go API 攻击发生的情况。

Pokémon Go API 攻击

Niantic 最近发布了一篇博文,详细介绍了机器人通过生成自动流量所造成的问题,这些问题实际上阻碍了他们在拉丁美洲的推出。 文章中包含的图表显示,自 Niantic 于太平洋时间 8 月 3 日下午 1 点推出自动化对策以来,空间查询流量显着下降。 自动流量似乎是真实人类玩家流量的两倍。 难怪最近几周 Pokémon Go 服务器严重超载。

 

服务器资源
图 1. 自从 Niantic 开始阻止抓取工具以来,空间查询流量下降了 50% 以上。 来源: Niantic 博客文章

了解 Pokémon 机器人

有两种类型的 Pokémon 机器人。 第一类机器人可以自动化常规游戏,是其他游戏应用中的常见机器人,可以自动化走动和捕捉口袋妖怪等活动。 此类机器人的例子包括 MyGoBot 和PokemonGo-Bot 。 但是 Pokémon Go 启发了一种新型机器人的开发,称为 Tracker 或 Mapper,它可以提供 Pokémon 的位置。 这些机器人为PokevisionGo Radar等 Pokémon Go 地图服务提供支持。

Pokémon Go Bot 的工作原理

移动 API 机器人是一种模仿移动应用程序与其后端服务器(在本例中是来自 Niantic 的服务器)之间通信的程序。 该机器人只是告诉服务器采取了什么操作并使用服务器的响应。

图 2 显示了 Pokémon Go 地图的屏幕截图,该地图标记了给定位置 3 英尺范围内附近的 Pokémon。 为了实现这一点,机器人制造商通常遵循以下步骤:

  1. 对移动应用程序和后端服务器之间的通信协议进行逆向工程。 机器人制造者玩游戏,捕获应用程序与其服务器之间的通信,并破译协议格式。
  2. 编写一个程序,向后端服务器发出一系列“合法”请求以采取行动。 在这种情况下,获取附近的神奇宝贝的位置只需通过目标 GPS 坐标发出请求,无需真正步行到实际位置。 对机器人的挑战是绕过服务器的检测并看起来像真人
  3. 提供相关功能,例如与 Google 地图集成,或为用户包含机器人自己的地图功能。

地图
图 2. Pokémon Go 地图的屏幕截图

移动应用程序破解与防御

以 Pokémon Go 应用程序为例,让我们研究如何通过逆向工程破解移动应用程序以揭示其秘密。 由于攻击者主要利用了Pokémon Go的Android应用程序,因此我们将重点关注Android应用程序的破解和防御。

对协议进行逆向工程

Pokémon Go 应用程序和后端服务器使用 SSL 上的ProtoBuf进行通信。 ProtoBuf定义了在网络上传输的数据格式。 例如,以下是玩家统计数据的 ProtoBuf 定义的摘录:

玩家统计数据的 ProtoBuf 定义

Pokémon Go 仅用两周时间就被POGOProtos逆向工程并在线发布。 这件事怎么发生得这么快? 最初,Niantic 并没有使用证书固定

证书固定是抵御中间人攻击的常用方法。 简而言之,移动应用程序只信任嵌入在应用程序本身的服务器证书。 如果没有证书固定保护,攻击者可以轻松设置MitmproxyFiddler等代理,并将攻击者制作的证书安装到她的手机上。 接下来,她可以配置她的手机通过代理路由流量并嗅探 Pokémon Go 应用程序和 Niantic 服务器之间的流量。 实际上有一款专门用于 Pokémon Go 的代理工具可以实现这一功能,叫做pokemon-go-mitm

7 月 31 日,Niantic 对其服务器和 Pokémon Go 应用进行了重大更改。Pokémon Go 0.31.0 发布了,具有证书固定保护功能。 不幸的是,秘密已经泄露,通信协议已经在 GitHub 上公开。 此外,正确实施证书固定并不总是那么容易。 在后面的章节中,我们将介绍攻击者常用的一些绕过证书固定的技术。

APK 静态分析

Android应用包(APK)是Android用于安装移动应用程序的文件格式。 Android应用程序主要用Java编写,Java代码被编译为dex格式并构建到apk文件中。 此外,Android 应用程序还可以调用用本机代码( Android NDK )编写的共享库。

众所周知,使用Baksmali等工具,Dex 文件很容易被反汇编成 SMALI 语言。 然后通过dex2jarjd-gui等工具进一步将dex文件反编译为Java代码,比较容易阅读。 利用这些技术,攻击者将 Pokémon Go Android 应用程序(版本 0.29.0 和 0.31.0)反编译为 Java 代码。 下面显示的示例代码com.nianticlabs.nia.network.NianticTrustManager类实现证书固定。

示例代码

当应用源代码被公开时,逆向工程就变得轻而易举了。 Pokemon Go Xposed使用不到 100 行 Java 代码来欺骗 Pokémon Go 应用程序,使其相信来自 MITMProxy 的证书是来自 Niantic 的真实证书。

Pokemon Go Xposed 是如何实现这一目标的? 相当容易。 该工具只是挂钩到上面代码片段中提到的函数checkServerTrusted的调用。 该钩子将函数的第一个参数chain更改为 Niantic 证书的值。 这意味着无论代理使用什么未经授权的证书,Pokémon Go 应用程序都会被诱骗信任该证书。

有许多工具可以帮助攻击者更加困难地进行反汇编和静态分析。 ProGuardDexGuard是对 Java 代码和 dex 文件进行混淆的工具。 混淆会使代码难以阅读,即使是反编译形式。 另一种方法是使用Android打包程序加密Android应用程序的原始classes.dex文件。 加密的 dex 文件在运行时在内存中解密,这使得大多数攻击者无法进行静态分析。 使用本机库是显著增加对应用程序进行逆向工程的难度的另一种方法。

对本机库进行逆向工程

pokemongodev黑客和 Niantic 之间最有趣的猫捉老鼠游戏围绕着名为“Unknown6”的字段展开,该字段包含在地图请求中发送的签名中,用于在某个位置获取附近的 Pokémon。 “Unknown6” 是逆向工程 protobuf 中未识别的字段之一。 最初,Unknown6 的赋值是什么并不重要;Niantic 服务器只是接受它。 从 8 月 3 日太平洋时间下午 1 点开始,所有 Pokémon Go 机器人突然无法找到任何 Pokémon,最终导致图 1 中的查询量大幅下降。

黑客随后注意到协议中“Unknown6”字段的重要性,并最初怀疑 Unknown6 是某种摘要或 HMAC,用于验证请求的完整性。 这引起了pokemongodev社区的极大兴趣,并很快成立了“Unknown6”团队来尝试破解这个神秘领域。 由于程序员和非程序员的广泛兴趣, Discord频道已变为私人频道,但实时更新频道让每个人都了解破解工作的进展。 经过 3 天 5 小时,即 08/06 下午,Unknown6 团队宣告胜利,发布了更新的Pokémon Go API ,该 API 再次能够检索附近的 Pokémon。

虽然有关黑客攻击细节的技术描述尚未发布,但论坛和实时更新中提到了许多相关工具和技术。 IDA-专业版 来自 Hex-Rays 的是一款能够反汇编本机库的 ARM 代码的专业工具,而新的 Hex-Rays 反编译器 可以将二进制代码文件反编译为 C 风格格式。 这些工具允许攻击者执行动态分析,在运行时调试移动应用程序及其库。 当然,即使有了如此强大的工具,对二进制程序进行逆向工程仍然极具挑战性。 如果没有任何刻意的混淆,反汇编或反编译后的代码已经很难理解,而且代码量通常很大。 为了说明所需工作的复杂性和不可预测性,现场更新频道和随后的采访描述了如何在数小时内识别出“Unknown6”的加密函数,但团队花费了大量额外的时间分析另一个名为“Unknown22”的字段,结果证明该字段与 Unknown6 无关。

因此,混淆对于保护本机库仍然具有许多实际好处。 二进制文件中高级别的混淆可能会使逆向工程的难度增加几个数量级。 然而,正如许多成功破解 Windows 和 Windows应用序列代码的情况所示,有动机的移动破解者经常会获得成功。

服务器端保护

服务器端防御的工作方式与客户端防御完全不同。 以下是保护 Pokémon Go 移动 API 中使用的一些技术。

速率限制

速率限制是一种试图阻止或至少减慢自动流量的常用方法。 早期的神奇宝贝扫描仪每秒可以发送数十个请求,扫描数十个单元,并找到每个神奇宝贝。

7 月 31 日,Niantic 添加了速率限制保护。 如果一个帐户在约 5 秒内发送多个地图请求,Niantic 的服务器将只接受第一个请求并丢弃其余请求。 攻击者对这些速率限制的反应是:a)在他们的扫描程序的地图请求之间添加延迟(5 秒)b)使用多个帐户和多个线程来绕过速率限制

在 Pokémon Go 案例中,使用速率限制为自动攻击开辟了另一个战场:自动账户创建。 他们很快发现,虽然速率限制是一种很好的基本技术,可以控制过于激进的抓取工具或新手攻击者的自动化攻击,但它并不能阻止高级对手获取自动请求。

IP 阻止

阻止 IP 是标准网络防火墙或Webapplication防火墙(WAF) 使用的一种传统技术,用于删除来自可疑 IP 的请求。 有许多数据库可以跟踪 IP 信誉,并且防火墙和 WAF 可以定期检索此类情报。

总体来说,基于IP的封锁是有风险而且无效的。 盲目地封锁一个流量很大的IP最终可能会导致大学或公司的NAT被封锁。 同时,许多 Pokémon 机器人或扫描仪可能使用住宅动态 IP 地址。 这些 IP 由 ISP 的客户共享,因此长期禁止某个 IP 可能会阻止合法玩家。

亚马逊网络服务 (AWS) 和 Digital Ocean 等托管服务也是攻击者获取虚拟机和新 IP 的来源。 当攻击者使用被盗的信用卡时,他们甚至可以免费获得这些资源。 但是,合法用户永远不会使用托管服务来浏览网页或玩游戏,因此阻止托管服务的 IP 是一种安全的防御措施,并且通常在服务器端使用。 根据此论坛帖子,Niantic 可能决定禁止来自 AWS 的 IP。

行为分析

行为分析通常是抵御能够绕过其他防御措施的高级攻击者的最后一道防线。 机器人的行为与人类有很大不同。 比如,现实中的人不可能每周 7 天、每天 24 小时玩游戏,也不可能在一秒钟内抓到 5 只口袋妖怪。 虽然行为分析听起来是一种很有前途的方法,但建立一个准确的检测系统来处理像 Pokémon Go 这样的庞大数据量并不是一件容易的事。

Niantic 刚刚对使用 GPS 欺骗“传送”(即突然以极快的速度移动)的作弊者实施了软禁令。 这可能是由于误报而导致的“软禁令”;家庭共享账户,GPS 读数可能不准确,使得一些合法用例看起来像机器人。

2016 年 8 月 12 日左右,Niantic在其网站上发布了一则通知,并概述了违反其服务条款可能会导致永久禁止 Pokémon Go 帐户。 针对机器人的多项禁令规则也被非正式地披露。 例如,《口袋妖怪过度捕捉规则》规定,如果用户一天内捕捉的口袋妖怪超过一千只,系统就会封禁其账号。 此外,Niantic 鼓励合法玩家举报作弊者或不当玩家

根据我们的经验,基于行为建模的检测可能非常有效,但在内部构建通常在技术上或经济上不可行。 正如 Niantic 在其博客文章中所评论的,“解决这个问题也有机会成本。 与构建新功能相比,开发人员必须花时间控制这个问题。” 更大的问题是,构建技术来防御专门的、技术精湛的对手(他们使用僵尸网络和其他旨在绕过常规防御的工具),需要许多高度专业化的技能和巨大的开发工作。

游戏尚未结束

随着Pokémon Go持续受到玩家的喜爱,机器人制造商和Niantic之间的博弈也将继续下去。 防御自动化流量不仅对游戏行业而且对所有行业都是一个挑战。 类似的攻击和防御活动正在银行、航空公司和零售商应用程序中发生,其风险比丢失几只卡比兽要高出几个数量级。 当客户和用户因为不必要的自动流量而无法访问服务时,机器人和相关的攻击工具对公司来说就不再是乐趣和游戏了。