作者:你走之后你的美我如何收拾_686 | 来源:互联网 | 2023-09-24 11:02
该SafetyNet Attestation API是谷歌播放服务的API,任何开发人员都能以获得一定程度的保证,使用他们的应用程序正在运行的设备是“CTS兼容。” CTS代表兼容性测试套件,这是测试套件设备必须在发布前通过,才能包含Google Play服务。传统上,设备制造商使用它来确保其设备满足Google的要求。现在,该术语具有更多含义,例如释放后的“设备处于未篡改状态”。篡改状态有多个定义,包括“被扎根”,“被监视”和“被恶意软件感染”。
SafetyNet是一个篡改检测框架,是最新版本的Google Play服务的一部分。只要更新了Play服务软件包,所有使用Android 2.3及更高版本的可启用Play的Android设备都已使用SafetyNet。除其他事项外,该服务还向Google告知每台设备的“安全”状态,并提供与生根,篡改,活动在岗人员等相关的指标。
了解有关开发人员有关如何使用此服务的说明的更多信息。
从说明中可以明显看出,开发人员使用服务的方式具有很大的灵活性。
SafetyNet实施
想象一下,作为开发人员,您有一个与远程Web服务端点进行通信以获取一些重要数据的应用程序。
现在,假设您要确保运行您的应用程序的设备没有植根或被其他方式篡改。应用程序可以选择执行客户端检查,不安全地实现SafetyNet attest(),如以下序列图所示:
这种仅用于客户端的基本实现流程会使您的应用程序容易受到操纵认证响应的琐碎的钩子攻击。绕过SafetyNet的基本实现的Xposed模块已经发布。在此特定Xposed模块中使用的一种此类攻击,是在对名为ctsProfileMatch或isValidSignature的变量的getBoolean的所有调用中返回True。我们希望这种检查存在于移动应用程序的代码中,以便它可以验证AttestationResult。
实施SafetyNet attest()API的一种更安全的方法是利用客户端-服务器体系结构,如以下序列图所述:
在此实现中,WebService将以无法被Google篡改的方式获取Google的CTS兼容性响应。设备上运行的其他应用程序。然后,WebService可以根据设备状态做出适当的反应。
为了使此实现有效,您的Web服务需要配置以下三点:
- 您的应用程序的软件包名称
- 上传到Google Play的APK的SHA-256哈希值
- 用于签署APK的证书的SHA-256签名哈希
工作流程如下所述。
- MobileApp使用getNonce()API从您的WebService请求一个随机值。在一般的Web应用程序中,此现时行为就像CSRF令牌:用于防止重播。
- WebService安全地(例如通过SecureRandom API)生成一个随机数,并将其返回给MobileApp。
- MobileApp执行包含此随机数的attest()请求。此API由Google Play服务SDK提供,并捆绑在应用程序中。必须指出的是,此时无需进行“篡改检查”。设备上的Google Play服务会异步执行并持续执行这些操作。证明请求仅用于向Google查询最近观察到的CTS兼容性状态。
- GoogleServices会以JSON Web签名(JWS)格式(一个签名的JSON对象)的证明结果进行响应。
- MobileApp对要执行的WebService执行REST请求,但在请求中将JWS AttestationResult作为参数。
- 此时,WebService必须首先验证JWS对象确实由GoogleServices签名。有两种方法可以执行此操作:通过与Google的公钥进行比较来手动进行,或者通过要求GoogleServices代表您执行此操作。对于本博文,我们将选择第二种方法。WebService通过Android设备验证API请求将JWS对象转发到Google服务器。
- GoogleServices检查JWS签名
- 如果JWS签名确实由Google创建,则GoogleServices会做出响应,因此JWS对象未被篡改。
- 您的WebService进一步验证JWS对象的有效负载数据是否与原始兼容性检查请求匹配。AttestationResult有效负载是由GoogleServices填充的字典,至少包含以下内容:现时,apkCertificateDigestSha256,时间戳,apkDigestSha256,apkPackageName,ctsProfileMatch
- 检查接收到的随机数是否与上次生成的随机数相匹配(如果保持会话状态,那将是当前会话的最后一个随机数)
- 检查apkCertificateDigestSha256字段是否与用于签署上传到Play商店的APK的证书的SHA-256哈希匹配。
- 与生成随机数相比,检查时间戳是否在适当的范围内
- 检查apkDigestSha256字段是否匹配APK的哈希值
- 检查apkPackageName字段是否与移动应用程序的预期软件包名称匹配
- 最后,Web服务检查ctsProfileMatch字段为true。
- 如果所有检查都成功,则返回对客户端应用程序的REST请求的常规响应。如果检查失败,一种策略是返回该REST API的错误消息。另一个可能是记录错误并将其输入到欺诈检测系统中。
仍然可能对SafetyNet服务进行攻击
开发人员应注意,具有root特权的本地攻击者始终可以通过篡改SafetySafe服务的Google Service提要数据来击败客户端的“篡改检测”检查。
与常规的根检测和篡改检测方法相比,使用SafetyNet的优势似乎在于,它可以按以下方式转移攻击者的工作量:在攻击常规的根检测机制时,攻击者可以检查保护机制的控件是如何设计的,并禁用这些控件控件,或者以他们知道将绕过检查的方式向它们提供操纵数据。相反,SafetyNet的实现方式是只能观察系统的数据收集部分。没有执行大多数检查。例如,SafetyNet能够检索文件系统中所有文件的列表。试图破坏系统的攻击者需要检查所有收集的数据,并对Google认为篡改的迹象做出有根据的猜测。请注意,攻击者将无法观察从非根设备发送到Google的数据的样子;因此,攻击者无法简单地使用该数据。
但是实际上,似乎可以通过将su二进制文件移动到其他位置并挂接一个调用以读取有关该设备的selinux状态信息的文件来轻易破坏当前的SafetyNet实现。
我们预计,将来Google会实施更多检查,例如验证/ system分区的完整性,打开一些当前未启用的检查,并在数据关联方面做得更好。
已经使用不同的生根或篡改检测系统的开发人员可以将SafetyNet证明结果作为其现有实现中的附加机制。
SafetyNet Playground示例应用程序
Synopsys的顾问创建了一个示例应用程序Safety Playground,该应用程序利用客户端-服务器体系结构以上述安全方式使用了证明API。
SafetyNet Playground由一个Android应用程序和一个关联的Web服务组成,可以用作尝试安全使用Google的SafetyNet证明API的开发人员的示例。
该示例应用程序将尝试向示例Web服务发出REST请求。仅当SafetyNet服务证明您的设备通过CTS兼容性检查时,服务器才会返回“成功”响应。
所有Android应用程序开发人员都可以按照我们在概念证明代码中演示的方式使用SafetyNet,以确保不会轻易绕过检查。当然,通过足够的努力,具有更高特权的攻击者可以绕过所有客户端代码。
注意:SafetyNet认证是Google Play服务-如果您希望您的应用程序在非Google Play设备(例如Amazon)上运行,则可能不是您应用程序的最佳方法。
参考文献
- 从Google Play下载SafetyNet Playground。
- 应用程序和Web服务的源代码都是开源的。
- Web服务组件。
- 也可以通过在composer.json中包含“ cigital / safetynet”来找到。
- Android应用程序代码。
- 有关SafetyNet内部的技术细节。
Credits
https://www.synopsys.com/blogs/software-security/using-safetynet-api/
SafetyNet研究:Synopsys的技术策略师John Kozyrakis。
SafetyNet Playground应用程序和Web服务开发:Synopsys的安全顾问Georgi Boiko。