数千万人正在探索Pokémon Go的全新世界。但事实证明,其中许多用户根本不是人,而是自动化代理,也就是机器人。游戏机器人并非新鲜事物,但Pokémon Go为机器人带来了一些新的应用场景。这些机器人通过大量自动化流量使Pokémon Go服务器不堪重负,已经开始影响所有人的游戏体验。Pokémon Go是研究自动化攻击与防御如何作用于移动API的典型案例。Shape每天都在应对此类攻击,因此我们决定深入了解Pokémon Go API攻击事件的来龙去脉。
Pokémon Go API攻击
Niantic最近发布了一篇博客文章,详细说明了机器人生成自动化流量所造成的问题,这些问题实际上阻碍了Pokémon Go在拉丁美洲的上线。文章中的图表显示,自Niantic于8月3日太平洋时间13:00推出自动化流量应对措施以来,空间查询流量显著下降。自动化流量似乎约为真实玩家流量的两倍。难怪Pokémon Go服务器近几周一直严重过载。

图1. 自Niantic开始阻止抓取工具以来,空间查询流量下降了50%以上。 来源: Niantic博客文章
了解Pokémon机器人
Pokémon机器人分为两类。第一类机器人可自动执行常规游戏操作,在其他游戏应用中也经常被用于违规行为,例如自动四处走动和捕捉Pokémon。这类机器人包括MyGoBot和PokemonGo-Bot。但Pokémon Go也催生了一种名为Tracker或Mapper的新型机器人,用于提供Pokémon的位置信息。这些机器人为Pokémon Go地图服务提供支持,例如Pokevision和Go Radar。
Pokémon Go机器人如何运作
移动API机器人是一种模拟移动应用与其后端服务器通信的程序,在本例中,后端服务器由Niantic提供。该机器人只需将执行的操作告知服务器,并接收服务器的响应。
图2是Pokémon Go地图的屏幕截图,其中标出了指定位置周围3个脚步范围内的Pokémon。为实现这一点,机器人程序制作者通常会执行以下步骤:
- 对移动应用与后端服务器之间的通信协议进行逆向工程。机器人程序制作者通过玩游戏,捕获应用与其服务器之间的通信,并解析协议格式。
- 编写程序,向后端服务器发出一系列“合法”请求以执行操作。在本例中,只需发送一个包含目标GPS坐标的请求,即可获取附近宝可梦的位置,无需实际步行前往相应地点。此类机器人的难点在于绕过服务器的检测,并表现得像真人。
- 提供相关功能,例如与Google Maps集成,或为用户提供机器人自带的地图功能。

图2. Pokémon Go地图截图
移动应用破解与防御
以Pokémon Go应用为例,我们来了解攻击者如何通过逆向工程破解移动应用并揭示其中的秘密。由于攻击者主要利用了Pokémon Go的Android应用,下面将重点介绍Android应用的破解与防御。
对协议进行逆向工程
Pokémon Go应用与后端服务器使用ProtoBuf通过SSL进行通信。ProtoBuf定义了通过网络传输的数据格式。例如,以下是玩家统计信息的ProtoBuf定义节选:

仅仅两周内,Pokémon Go就被POGOProtos完成逆向工程并发布到网上。为何进展如此之快?最初,Niantic并未使用证书固定。
证书固定是防范中间人攻击的常用方法。简而言之,移动应用只信任嵌入应用本身的服务器证书。如果没有证书固定保护,攻击者可以轻松设置代理,例如Mitmproxy或Fiddler,并在手机上安装攻击者制作的证书。然后,攻击者可以配置手机,使流量通过该代理传输,并嗅探Pokémon Go应用与Niantic服务器之间的流量。实际上,有一款专用于Pokémon Go的代理工具可以简化这一过程,名为pokemon-go-mitm。
7月31日,Niantic对其服务器和Pokémon Go应用进行了重大更改。Pokémon Go 0.31.0发布时加入了证书固定保护。遗憾的是,此时为时已晚,通信协议已经在GitHub上公开。此外,正确实施证书固定并非易事。后续章节将介绍攻击者绕过证书固定时常用的一些技术。
APK静态分析
The Android应用程序包(APK)是Android用于安装移动应用的软件包文件格式。Android应用主要使用Java编写,Java代码会编译为dex格式并构建成APK文件。此外,Android应用还可能调用使用原生代码编写的共享库(Android NDK)。
众所周知,使用Baksmali等工具可以轻松将Dex文件反汇编为SMALI语言。随后,dex2jar和jd-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应用信任该证书。
有许多工具可帮助增加攻击者进行反汇编和静态分析的难度。ProGuard和DexGuard是对Java代码和dex文件进行混淆处理的工具。即使经过反编译,混淆后的代码也难以阅读。另一种方法是使用Android加固工具加密Android应用的原始classes.dex文件。加密后的dex文件会在运行时于内存中解密,使大多数攻击者难以甚至无法进行静态分析。使用原生库也可以显著增加应用逆向工程的难度。
对原生库进行逆向工程
“pokemongodev”黑客与Niantic之间最有趣的一场猫鼠游戏,围绕名为“Unknown6”的字段展开。该字段包含在地图请求所发送的签名中,用于获取某个位置附近的宝可梦。“Unknown6”是经过逆向工程的protobuf中尚未识别的字段之一。起初,无论为Unknown6赋予什么值,Niantic服务器都会接受。从8月3日13:00(太平洋时间)开始,所有Pokémon Go机器人突然都无法找到任何宝可梦,最终导致图1中的查询量大幅下降。
随后,黑客注意到协议中“Unknown6”字段的重要性,并初步怀疑Unknown6是某种用于验证请求完整性的摘要或HMAC。这引起了pokemongodev社区的极大兴趣,“Unknown6”团队迅速成立,试图破解这个神秘字段。由于程序员和非程序员都对此广泛关注,Discord频道转为私密频道,但实时更新频道持续向所有人通报破解进展。3天5小时后,即08/06下午,Unknown6团队宣布破解成功,并发布了更新版Pokémon Go API,使其再次能够检索附近的Pokémon。
尽管有关此次破解细节的技术说明尚未发布,但论坛和实时更新中提到了许多相关工具和技术。IDA-Pro是Hex-Rays推出的一款专业工具,可反汇编原生库的ARM代码;新推出的Hex-Rays反编译器则可将二进制代码文件反编译为类似C语言的格式。攻击者可以使用这些工具进行动态分析,在运行时调试移动应用及其库。当然,即使有如此强大的工具,对二进制程序进行逆向工程仍极具挑战性。即使未进行任何有意的混淆处理,反汇编或反编译后的代码也已经很难理解,而且代码量通常非常庞大。实时更新频道及随后的一篇访谈说明了这项工作有多么复杂且难以预测:“Unknown6”的加密函数在数小时内便被识别出来,但团队又花费了大量时间分析另一个名为“Unknown22”的字段,最终发现该字段与Unknown6无关。
因此,混淆对于保护原生库仍有许多实际作用。对二进制文件进行高度混淆,可能会使逆向工程的难度提高数个数量级。然而,Windows及其应用程序的序列号曾多次被成功破解,这表明动机强烈的移动应用破解者往往也能得手。
服务器端保护
服务器端防御的工作方式与客户端防御截然不同。以下是在保护Pokémon Go移动API时采用的一些技术。
速率限制
速率限制是一种常见方法,旨在阻止自动化流量,或至少降低其速度。早期,Pokémon扫描器每秒可以发送数十个请求、扫描数十个单元格,并找到每一只Pokémon。
7月31日,Niantic增加了速率限制保护。如果同一账户在约5秒内发送多个地图请求,Niantic的服务器只会接受第一个请求,并丢弃其余请求。攻击者采取了以下方式应对这些速率限制:a)在扫描程序发送的地图请求之间增加5秒延迟;b)使用多个账户和多个线程绕过速率限制。
以Pokémon Go为例,采用速率限制只会为自动化攻击开辟另一个战场:自动创建账户。攻击者很快发现,虽然速率限制是一种有效的基础技术,可以控制过于激进的抓取工具或初级攻击者发起的自动化操作,但无法阻止高级攻击者成功发送自动化请求。
IP封禁
阻止IP是标准网络防火墙或Web应用防火墙(WAF)用于丢弃来自可疑IP的请求的一种传统技术。许多数据库会跟踪IP信誉,防火墙和WAF可定期获取此类威胁情报。
总体而言,基于IP的封禁既有风险,效果也不理想。盲目封禁流量较大的IP,最终可能会误封某所大学或企业的NAT。同时,许多Pokémon机器人或扫描器可能会使用住宅动态IP地址。这些IP由互联网服务提供商(ISP)的客户共享,因此长期封禁某个IP可能会阻止合法玩家访问。
Amazon Web Services(AWS)和Digital Ocean等托管服务也是攻击者获取虚拟机和新IP地址的渠道。攻击者使用盗取的信用卡时,甚至可以免费获得这些资源。不过,合法用户不会使用托管服务浏览网页或玩游戏,因此,屏蔽托管服务的IP地址是一种安全的防御措施,服务器端通常会采用这种做法。根据这篇论坛帖子,Niantic可能会决定屏蔽AWS的IP地址。
行为分析
行为分析通常是抵御能够绕过其他防御措施的高级攻击者的最后一道防线。机器人的行为与人类截然不同。例如,真人不可能全天候玩游戏,也不可能在1秒内捕捉5只宝可梦。虽然行为分析看似是一种很有前景的方法,但要构建一个准确的检测系统来处理Pokémon Go这类应用产生的海量数据并非易事。
Niantic刚刚对使用GPS欺骗进行“瞬移”(即突然以不可能达到的速度移动)的作弊者实施了软封禁。之所以采用“软封禁”,可能是因为存在误报:家庭成员会共享账号,而且GPS读数可能不准确,导致一些正常使用行为看起来像机器人。
2016年8月12日前后,Niantic在其网站上发布了一则公告,其中指出,违反服务条款可能会导致Pokémon Go账号被永久封禁。此外,还有多项针对机器人的封禁规则被非官方披露。例如,根据Pokémon捕获数量过多规则,如果账号在一天内捕获超过1,000只Pokémon,就会被封禁。此外,Niantic鼓励正常玩家举报作弊者或行为不当的玩家。
根据我们的经验,基于行为建模的检测可能非常有效,但自行构建这类检测能力往往在技术或经济上并不可行。正如Niantic在其博客文章中所说:“处理这个问题也存在机会成本。开发人员不得不花时间控制这一问题,而无法将这些时间用于开发新功能。”更大的问题在于,要构建相应技术来抵御那些目标明确、精通技术,并利用僵尸网络及其他旨在绕过常规防御的工具发起攻击的对手,需要多种高度专业化的技能,并投入大量开发工作。
游戏尚未结束
随着Pokémon Go继续受到玩家喜爱,机器人制作者与Niantic之间的较量也将持续。防御自动化流量不仅是游戏行业面临的挑战,也是所有行业共同面对的问题。类似的攻防活动也在银行、航空公司和零售商的应用中上演,其风险远高于损失几只卡比兽。当不需要的自动化流量导致客户和用户无法访问服务时,机器人及相关攻击工具对企业而言绝非儿戏。
关于作者
相关博客文章
Thingbot正转变为攻击平台
Lori MacVittie重点介绍了F5 Labs对2018年1月至6月全球物联网设备攻击的研究,并指出了其中令人警醒的影响。物联网设备不仅持续遭到利用,还被转变为攻击平台,这意味着攻击者可以更充分地利用这个必然增长的市场。
借助F5全新Quick Start,在AWS上快速开展业务
在AWS re:Invent开幕前,我们很高兴与大家分享F5与AWS之间全新的Quick Start集成。F5的Tom Atkins将介绍该服务如何启动、配置和运行在AWS上部署工作负载所需的计算、网络、存储及其他AWS服务。