移动应用网络通信¶
几乎所有网络连接的移动应用都依赖超文本传输协议(HTTP)或其安全版本 HTTPS(使用传输层安全协议 TLS)与远程端点交换数据。如果未安全实现,这种通信可能容易受到基于网络的攻击,如数据包嗅探和中间人(MITM)攻击。在本章中,我们将探讨潜在的漏洞、测试技术以及保护移动应用网络通信的最佳实践。
安全连接¶
仅仅使用明文 HTTP 的时代早已过去,现在使用 HTTPS 来保护 HTTP 连接通常是轻而易举的。HTTPS 本质上是基于另一个协议(即传输层安全协议 TLS)的 HTTP。TLS 使用公钥密码学执行握手,完成后会建立一个安全连接。
HTTPS 连接因以下三个特性而被视为安全
- 保密性: TLS 在通过网络发送数据之前对其进行加密,这意味着中间人无法读取数据。
- 完整性: 数据在未经检测的情况下无法被篡改。
- 认证: 客户端可以验证服务器的身份,以确保连接是与正确的服务器建立的。
服务器信任评估¶
证书颁发机构(CA)是安全客户端-服务器通信不可或缺的一部分,它们预定义在每个操作系统的信任存储中。例如,在 iOS 上安装了 200 多个根证书(参见 Apple 文档 - Apple 操作系统中可用的受信任根证书)
CA 可以通过用户手动添加、MDM 管理企业设备或通过恶意软件添加到信任存储中。问题是:“您能信任所有这些 CA 吗?您的应用应该依赖默认的信任存储吗?”毕竟,曾有 CA 被攻破或被欺骗而向冒名顶替者颁发证书的知名案例。CA 泄露和失败的详细时间线可以在 sslmate.com 找到。
Android 和 iOS 都允许用户安装额外的 CA 或信任锚点。
应用可能希望信任一组自定义的 CA,而不是平台默认的 CA。最常见的原因是:
- 连接到具有自定义证书颁发机构(CA,系统尚未知晓或信任)的主机,例如自签名或公司内部颁发的 CA。
- 将 CA 集合限制为特定的受信任 CA 列表。
- 信任系统中未包含的其他 CA。
关于信任存储¶
扩展信任¶
每当应用程序连接到其证书是自签名或系统未知的服务器时,安全连接都将失败。这通常适用于任何非公共 CA,例如由政府、公司或教育机构等组织为其自身使用而颁发的 CA。
Android 和 iOS 都提供了扩展信任的方法,即包含额外的 CA,以便应用程序信任系统的内置 CA 和自定义 CA。
但是,请记住设备用户始终能够包含额外的 CA。因此,根据应用程序的威胁模型,可能需要避免信任添加到用户信任存储中的任何证书,甚至进一步仅信任预定义或特定的一组证书。
对于许多应用程序而言,移动平台提供的“默认行为”对其用例来说已经足够安全(在系统信任的 CA 被攻破的极少数情况下,应用程序处理的数据不被认为是敏感的,或者已采取其他安全措施,即使面对此类 CA 泄露也能保持弹性)。然而,对于金融或健康等应用程序,即使 CA 泄露的情况很少发生,也必须考虑其风险。
限制信任:身份固定¶
一些应用程序可能需要通过限制其信任的 CA 数量来进一步提高安全性。通常,只有开发者使用的 CA 会被明确信任,而其他所有 CA 则被忽略。这种信任限制被称为_身份固定(Identity Pinning)_,通常以_证书固定(Certificate Pinning)_或_公钥固定(Public Key Pinning)_的形式实现。
在 OWASP MASTG 中,我们将此术语称为“身份固定”、“证书固定”、“公钥固定”或简称为“固定”。
固定是将远程端点与特定身份(例如 X.509 证书或公钥)关联的过程,而不是接受由受信任 CA 签名的任何证书。在固定服务器身份(或某个集合,即_pinset_)后,移动应用程序只有在身份匹配时才会连接到这些远程端点。撤销对不必要 CA 的信任可以减少应用程序的攻击面。
通用指南¶
OWASP 证书固定备忘单提供了以下基本指导:
- 何时建议固定以及可能适用的例外情况。
- 何时进行固定:开发时(预加载)或首次遇到时(首次使用时信任)。
- 固定什么:证书、公钥或哈希。
Android 和 iOS 的建议都符合“最佳实践”,即:
- 仅固定开发者控制的远程端点。
- 在开发时通过 (NSC/ATS) 进行。
- 固定 SPKI
subjectPublicKeyInfo
的哈希值。
自几年前引入以来,固定获得了不好的声誉。我们想澄清几点,这些至少对移动应用安全是有效的:
- 不好的声誉是由于操作原因(例如,实现/固定管理复杂性),而不是缺乏安全性。
- 如果应用程序未实现固定,这不应被报告为漏洞。但是,如果应用程序必须针对 MASVS-L2 进行验证,则必须实现固定。
- Android 和 iOS 都使得固定的实现非常简单,并且遵循了最佳实践。
- 固定可以防止被攻破的 CA 或安装在设备上的恶意 CA。在这些情况下,固定将阻止操作系统与恶意服务器建立安全连接。然而,如果攻击者控制了设备,他们可以轻易禁用任何固定逻辑,从而仍然允许连接发生。因此,这并不能阻止攻击者访问您的后端并滥用服务器端漏洞。
- 移动应用中的固定与 HTTP 公钥固定(HPKP)不同。HPKP 头部不再在网站上推荐使用,因为它可能导致用户被锁定在网站之外,并且无法恢复锁定。对于移动应用来说,这不是问题,因为在出现任何问题时,应用程序始终可以通过带外渠道(即应用商店)进行更新。
关于 Android 开发者平台上的固定(Pinning)建议¶
Android 开发者网站包含以下警告:
注意:不建议将证书固定用于 Android 应用程序,因为未来服务器配置变更(例如更换到另一个证书颁发机构)的风险很高,这可能导致应用程序无法连接到服务器,除非接收到客户端软件更新。
他们还包括以下说明:
请注意,在使用证书固定时,您应始终包含一个备用密钥,这样,如果您被迫切换到新密钥或更改 CA(当固定到 CA 证书或该 CA 的中间证书时),您的应用程序连接不会受到影响。否则,您必须推送应用程序更新以恢复连接。
第一条声明可能被错误地解释为他们“不推荐证书固定”。第二条声明澄清了这一点:实际的建议是,如果开发者想实现固定,他们必须采取必要的预防措施。
关于 Apple 开发者平台上的固定(Pinning)建议¶
Apple 建议着眼长远并创建适当的服务器认证策略。
OWASP MASTG 建议¶
固定是一种推荐的做法,特别是对于 MASVS-L2 应用程序。然而,开发者必须仅针对其控制的端点实施固定,并确保包含备用密钥(又称备用固定)并制定适当的应用程序更新策略。
了解更多¶
验证 TLS 设置¶
移动应用程序的核心功能之一是通过不受信任的网络(如互联网)发送/接收数据。如果数据在传输过程中未得到适当保护,拥有网络基础设施任何部分(例如 Wi-Fi 接入点)访问权限的攻击者可能会拦截、读取或修改它。这就是为什么明文网络协议很少可取的原因。
绝大多数应用程序依赖 HTTP 与后端进行通信。HTTPS 将 HTTP 封装在加密连接中(HTTPS 这个缩写最初指代 HTTP over Secure Socket Layer (SSL);SSL 是 TLS 的废弃前身)。TLS 允许对后端服务进行认证,并确保网络数据的机密性和完整性。
推荐的 TLS 设置¶
确保服务器端 TLS 配置的正确性也很重要。SSL 协议已被弃用,不应再使用。此外,TLS v1.0 和 TLS v1.1 存在已知漏洞,并且到 2020 年,所有主流浏览器都已弃用它们的用法。TLS v1.2 和 TLS v1.3 被认为是安全数据传输的最佳实践。从 Android 10(API 级别 29)开始,TLS v1.3 将默认启用,以实现更快、更安全的通信。TLS v1.3 的主要变化是无法再自定义密码套件,并且在启用 TLS v1.3 时所有密码套件都会被启用,而零往返时间(0-RTT)模式则不支持。
当客户端和服务器都由同一组织控制并仅用于彼此通信时,您可以通过强化配置来提高安全性。
如果移动应用程序连接到特定服务器,其网络堆栈可以进行调整,以确保服务器配置达到最高的安全级别。底层操作系统缺乏支持可能会迫使移动应用程序使用较弱的配置。
密码套件术语¶
密码套件具有以下结构:
Protocol_KeyExchangeAlgorithm_WITH_BlockCipher_IntegrityCheckAlgorithm
此结构包括:
- 密码使用的协议
- 服务器和客户端在 TLS 握手期间用于认证的密钥交换算法
- 用于加密消息流的分组密码
- 用于认证消息的完整性检查算法
示例:TLS_RSA_WITH_3DES_EDE_CBC_SHA
在上述示例中,密码套件使用:
- TLS 作为协议
- RSA 非对称加密用于认证
- 3DES 用于对称加密,采用 EDE_CBC 模式
- SHA 哈希算法用于完整性
请注意,在 TLSv1.3 中,密钥交换算法不属于密码套件的一部分,而是在 TLS 握手期间确定。
在下面的列表中,我们将展示密码套件每个部分的不同算法。
协议
SSLv1
SSLv2
- RFC 6176SSLv3
- RFC 6101TLSv1.0
- RFC 2246TLSv1.1
- RFC 4346TLSv1.2
- RFC 5246TLSv1.3
- RFC 8446
密钥交换算法
DSA
- RFC 6979ECDSA
- RFC 6979RSA
- RFC 8017DHE
- RFC 2631 - RFC 7919ECDHE
- RFC 4492PSK
- RFC 4279DSS
- FIPS186-4DH_anon
- RFC 2631 - RFC 7919DHE_RSA
- RFC 2631 - RFC 7919DHE_DSS
- RFC 2631 - RFC 7919ECDHE_ECDSA
- RFC 8422ECDHE_PSK
- RFC 8422 - RFC 5489ECDHE_RSA
- RFC 8422
分组密码
DES
- RFC 4772DES_CBC
- RFC 18293DES
- RFC 24203DES_EDE_CBC
- RFC 2420AES_128_CBC
- RFC 3268AES_128_GCM
- RFC 5288AES_256_CBC
- RFC 3268AES_256_GCM
- RFC 5288RC4_40
- RFC 7465RC4_128
- RFC 7465CHACHA20_POLY1305
- RFC 7905 - RFC 7539
完整性检查算法
请注意,密码套件的效率取决于其算法的效率。
以下资源包含使用 TLS 的最新推荐密码套件:
- IANA 推荐的密码套件可在TLS 密码套件中找到。
- OWASP 推荐的密码套件可在TLS 密码字符串备忘单中找到。
某些 Android 和 iOS 版本不支持部分推荐的密码套件,因此出于兼容性考虑,您可以检查Android和iOS版本支持的密码套件,并选择支持程度最高的密码套件。
如果您想验证您的服务器是否支持正确的密码套件,有多种工具可供使用:
- nscurl - 更多详情请参阅iOS 网络通信。
- testssl.sh,它是一个“免费命令行工具,用于检查服务器服务在任何端口上对 TLS/SSL 密码、协议以及一些加密漏洞的支持情况”。
最后,验证 HTTPS 连接终止的服务器或终止代理是否按照最佳实践进行了配置。另请参阅OWASP 传输层保护备忘单和Qualys SSL/TLS 部署最佳实践。
通过中间人攻击(MITM)拦截网络流量¶
拦截移动应用程序流量是安全测试的关键方面,它使测试人员、分析师或渗透测试人员能够分析和操纵网络通信以识别漏洞。此过程中的关键技术是中间机器(MITM)攻击(也称为“中间人(Man-in-the-Middle)”(传统上),MITRE 和 CAPEC 等称之为“中间对手(Adversary-in-the-Middle)”等),其中_攻击者_将其机器放置在两个通信实体之间,通常是移动应用程序(客户端)和其通信的服务器。通过这样做,攻击者的机器会拦截和监控不同方之间传输的数据。
这项技术具有双重性:
- 通常**被恶意攻击者使用**来拦截、监控并可能更改通信,而通信双方(应用程序或服务器)都毫不知情。这允许进行恶意活动,例如窃听、注入恶意内容或操纵正在交换的数据。
- 然而,**在 OWASP MASTG 和移动应用安全测试的背景下**,我们将其作为技术的一部分,允许应用程序测试人员审查、分析或修改流量,以识别未加密通信或弱安全控制等漏洞。
所使用的具体拦截方法取决于应用程序的安全机制以及传输数据的性质。每种方法在复杂性和有效性上各不相同,具体取决于加密和应用程序抵抗干扰的能力等因素。
以下是不同网络层面的拦截技术概述:
拦截技术 | 示例工具 | 备注 |
---|---|---|
API 挂钩 (HttpUrlConnection , NSURLSession , WebRequest ) |
Frida | 修改应用程序处理网络请求的方式。 |
挂钩 TLS 函数 (SSL_read , SSL_write ) |
Frida, SSL Kill Switch | 在加密数据到达应用程序之前对其进行拦截。 |
代理拦截 | Burp Suite, ZAP, mitmproxy | 要求应用程序遵守代理设置。 |
数据包嗅探 | tcpdump , Wireshark |
捕获所有 TCP/UDP 流量,但不解密 HTTPS。 |
通过 ARP 欺骗进行中间人攻击 | bettercap | 欺骗设备即使在攻击者未控制网络的情况下,也通过攻击者的机器发送流量。 |
恶意 Wi-Fi AP | hostapd , dnsmasq , iptables , wpa_supplicant , airmon-ng |
使用由攻击者完全控制的接入点。 |
您可以在相应的技术页面中找到有关这些技术的更多信息:
- 通过挂钩应用程序层网络 API 拦截 HTTP 流量
- 使用拦截代理拦截 HTTP 流量
- 使用拦截代理拦截非 HTTP 流量
- 被动窃听
- 通过 ARP 欺骗实现中间人攻击位置
- 使用恶意接入点实现中间人攻击位置
关于证书固定的注意事项: 如果应用程序使用证书固定,一旦您开始拦截流量,上述技术可能看起来会失败,但您可以使用不同的方法绕过它。有关更多信息,请参阅以下技术: