4.渗透测试指南-认证测试

默认凭据测试

ID
WSTG-ATHN-02

概述

许多 Web 应用程序和硬件设备的内置管理账户都设有默认密码。虽然在某些情况下,这些密码可能是随机生成的,但通常是固定的,这意味着攻击者可以轻易猜出或获取这些密码。

此外,当应用程序创建新用户时,可能会为其设置预定义的密码。这些密码可能由应用程序自动生成,也可能由工作人员手动设置。无论哪种情况,如果密码不是以安全的方式生成,攻击者就有可能猜出这些密码。

测试目标

  • 确定应用程序是否存在使用默认密码的用户账户。
  • 检查新用户账户是否使用了弱密码或可预测的密码。

测试方法

供应商默认凭据测试

识别默认密码的第一步是确定正在使用的软件。本指南的信息收集部分详细介绍了这一点。

确定软件后,尝试查找该软件是否使用默认密码,如果使用,具体是什么。这可以通过以下方式进行:

  • 在搜索引擎中搜索“[软件名称] 默认密码”。
  • 查看软件手册或供应商文档。
  • 检查常见的默认密码数据库,例如 CIRT.netSecLists 默认密码库默认凭据速查表
  • 检查应用程序的源代码(如果可用)。
  • 在虚拟机上安装该应用程序并进行检查。
  • 检查物理硬件上的标签(网络设备上经常会有)。

如果找不到默认密码,可以尝试常见的选项,例如:

  • “admin”、“password”、“12345” 或其他常见的默认密码
  • 空密码。
  • 设备的序列号或 MAC 地址。

如果用户名未知,可以参考账户枚举测试指南中讨论的各种用户枚举方法。另外,也可以尝试常见的用户名,如 “admin”、“root” 或 “system”。

组织默认密码测试

当组织内的工作人员手动为新账户创建密码时,可能会采用可预测的方式。常见的情况包括:

  • 使用单一的通用密码,如 “Password1”。
  • 使用与组织相关的特定信息,如组织名称或地址。
  • 遵循简单模式的密码,例如如果账户在周一创建,则使用 “Monday123”。

从黑盒测试的角度来看,这类密码通常很难识别,除非能够成功猜出或通过暴力破解得到。然而,在进行灰盒或白盒测试时,识别这些密码相对容易。

应用程序生成的默认密码测试

如果应用程序自动为新用户账户生成密码,这些密码也可能是可预测的。为了测试这些密码,可以在应用程序上同时创建多个信息相似的账户,并比较分配给它们的密码。

这些密码可能基于以下因素:

  • 所有账户共享的单个静态字符串。
  • 账户信息的哈希或混淆部分,例如 md5($username)
  • 基于时间的算法。
  • 弱伪随机数生成器(PRNG)。

从黑盒测试的角度来看,这类问题通常很难识别。

工具

参考资料

弱锁定机制测试

编号
WSTG - ATHN - 03

概述

账户锁定机制用于缓解暴力破解攻击。使用锁定机制可以抵御以下一些攻击:

  • 登录密码或用户名猜测攻击。
  • 任何双因素认证(2FA)功能或安全问题的代码猜测攻击。

账户锁定机制需要在保护账户免遭未经授权的访问和保护用户不被拒绝合法访问之间取得平衡。通常,账户在 3 到 5 次登录尝试失败后会被锁定,并且只能在预定的时间段之后、通过自助解锁机制或管理员干预才能解锁。

尽管进行暴力破解攻击很容易,但成功攻击的后果非常危险,因为攻击者将完全访问用户账户及其可使用的所有功能和服务。

测试目标

  • 评估账户锁定机制缓解暴力破解密码猜测攻击的能力。
  • 评估解锁机制抵御未经授权解锁账户的能力。

测试方法

锁定机制

要测试锁定机制的强度,你需要有一个愿意或能够承受被锁定的账户。如果你只有一个可以登录到 Web 应用程序的账户,请在测试计划结束时进行此测试,以避免因账户被锁定而浪费测试时间。

为了评估账户锁定机制缓解暴力破解密码猜测攻击的能力,先用错误密码进行多次无效登录尝试,然后使用正确密码验证账户是否被锁定。以下是一个示例测试步骤:

  1. 使用错误密码尝试登录 3 次。
  2. 使用正确密码成功登录,这表明锁定机制在 3 次错误认证尝试后未触发。
  3. 使用错误密码尝试登录 4 次。
  4. 使用正确密码成功登录,这表明锁定机制在 4 次错误认证尝试后未触发。
  5. 使用错误密码尝试登录 5 次。
  6. 使用正确密码尝试登录,应用程序返回“你的账户已被锁定”,从而确认账户在 5 次错误认证尝试后被锁定。
  7. 5 分钟后使用正确密码尝试登录,应用程序返回“你的账户已被锁定”,这表明锁定机制在 5 分钟后不会自动解锁。
  8. 10 分钟后使用正确密码尝试登录,应用程序返回“你的账户已被锁定”,这表明锁定机制在 10 分钟后不会自动解锁。
  9. 15 分钟后使用正确密码成功登录,这表明锁定机制在 10 到 15 分钟后会自动解锁。
独特的锁定机制

目前还存在一些独特但可接受的锁定机制实现方式。其中之一是亚马逊网络服务(AWS)的 Cognito。它使用一种简单的缩放算法,在缓解暴力破解攻击的同时,避免对受影响用户进行长期的拒绝服务攻击。用户使用密码进行 5 次登录尝试失败后,将被锁定 1 秒钟。每次失败尝试后,锁定持续时间翻倍,最长锁定时间为 15 分钟。在锁定期间进行的登录尝试会引发异常,称为“密码尝试次数已超过限制”,在大多数实现中,这些异常不会返回给发起登录的用户。如果用户看不到这些异常,测试人员可能会认为没有使用锁定机制,因为快速进行 200 次登录尝试会产生大量此类异常,而合法的失败登录尝试却很少。

该机制背后的数学公式为:2^(n - 5),其中 n 是失败登录尝试的次数。计算结果即为用户被锁定的秒数。要将锁定计数重置为零,用户必须成功登录或等待 15 分钟。

要使用模糊测试工具(如 Burp Suite 的 Intruder)对此进行测试,导航到“资源池”,然后将最大并发请求数设置为 1,请求之间的延迟设置为 2 秒。进行 200 次无效认证尝试,然后在模糊测试工具完成后立即使用有效凭证进行 3 次登录尝试。等待 2 分钟后再尝试登录。如果此时登录成功,则可能使用了 Cognito。可以通过尝试提高锁定时间来进一步测试以验证是否使用了 Cognito,但与客户确认此信息可能会更简单。

验证码(CAPTCHA)可以阻碍暴力破解攻击,但它们本身也可能存在弱点,因此不应替代锁定机制。如果验证码机制实现不当,可能会被绕过。验证码的漏洞包括:

  1. 容易破解的挑战,如算术题或有限的问题集。
  2. 验证码检查 HTTP 响应代码而非响应是否成功。
  3. 验证码服务器端逻辑默认判定为成功通过。
  4. 验证码挑战结果从未在服务器端进行验证。
  5. 验证码输入字段或参数被手动处理,且验证或转义不当。

要评估验证码的有效性,可以采取以下步骤:

  1. 评估验证码挑战,并根据难度尝试自动解决。
  2. 尝试不通过正常用户界面机制解决验证码就提交请求。
  3. 尝试故意使验证码挑战失败后提交请求。
  4. 使用测试代理(直接向服务器端提交请求),尝试不解决验证码就提交请求(假设客户端代码可能会传递一些默认值等)。
  5. 如果存在验证码数据输入点,尝试使用常见的注入有效负载或特殊字符序列进行模糊测试。
  6. 检查验证码的解决方案是否可能是图像的替代文本、文件名或关联隐藏字段中的值。
  7. 尝试重新提交之前确定的已知有效响应。
  8. 检查清除 cookie 是否会绕过验证码(例如,如果验证码仅在多次失败后才显示)。
  9. 如果验证码是多步骤流程的一部分,尝试直接访问或完成验证码之后的步骤(例如,如果验证码是登录过程的第一步,尝试直接提交第二步[用户名和密码])。
  10. 检查是否存在可能未强制使用验证码的替代方法,如用于方便移动应用访问的 API 端点。

对每个可能需要锁定机制的功能重复此过程。

解锁机制

要评估解锁机制抵御未经授权解锁账户的能力,启动解锁机制并查找其弱点。典型的解锁机制可能涉及安全问题或通过电子邮件发送的解锁链接。解锁链接应该是唯一的一次性链接,以防止攻击者猜测或重放该链接并批量进行暴力破解攻击。

请注意,解锁机制仅应用于解锁账户,它与密码恢复机制不同,但可以遵循相同的安全实践。

修复措施

根据风险级别应用账户解锁机制。按保证程度从低到高的顺序排列如下:

  1. 基于时间的锁定和解锁。
  2. 自助解锁(向注册电子邮件地址发送解锁邮件)。
  3. 管理员手动解锁。
  4. 管理员手动解锁并进行用户身份验证。

实施账户锁定机制时需要考虑的因素:

  1. 针对该应用程序进行暴力破解密码猜测的风险有多大?
  2. 验证码是否足以缓解此风险?
  3. 是否使用了客户端锁定机制(例如 JavaScript)?(如果是,请禁用客户端代码进行测试。)
  4. 锁定前允许的登录失败尝试次数。如果锁定阈值过低,合法用户可能会经常被锁定;如果锁定阈值过高,攻击者在账户被锁定之前可以进行更多的暴力破解尝试。根据应用程序的用途,5 到 10 次失败尝试是典型的锁定阈值范围。
  5. 账户将如何解锁?
    1. 由管理员手动解锁:这是最安全的锁定方法,但可能会给用户带来不便,并占用管理员的“宝贵”时间。
      1. 请注意,管理员在其账户被锁定的情况下也应有恢复方法。
      2. 如果攻击者的目标是锁定 Web 应用程序所有用户的账户,这种解锁机制可能会导致拒绝服务攻击。
    2. 在一段时间后解锁:锁定持续时间是多少?对于受保护的应用程序来说是否足够?例如,5 到 30 分钟的锁定持续时间可能是缓解暴力破解攻击和避免给合法用户带来不便之间的一个很好的折衷方案。
    3. 通过自助机制解锁:如前所述,这种自助机制必须足够安全,以防止攻击者自行解锁账户。

参考资料

绕过身份验证方案测试

ID
WSTG-ATHN-04

概述

在计算机安全领域,身份验证是指尝试验证通信发送方数字身份的过程。登录过程就是这种验证过程的一个常见示例。测试身份验证方案意味着了解身份验证过程的工作原理,并利用这些信息绕过身份验证机制。

虽然大多数应用程序需要身份验证才能访问私有信息或执行任务,但并非每种身份验证方法都能提供足够的安全性。疏忽、无知或对安全威胁的简单低估,往往会导致身份验证方案存在漏洞,攻击者只需跳过登录页面,直接访问那些本应在身份验证后才能访问的内部页面,就能绕过身份验证。

此外,攻击者通常还可以通过篡改请求,诱使应用程序认为用户已经通过身份验证,从而绕过身份验证措施。这可以通过修改给定的URL参数、操纵表单或伪造会话来实现。

与身份验证方案相关的问题可能出现在软件开发生命周期(SDLC)的不同阶段,如设计、开发和部署阶段:

  • 设计阶段:错误可能包括对需要保护的应用程序部分定义错误、选择不应用强加密协议来保护凭证传输等。
  • 开发阶段:错误可能包括输入验证功能的错误实现,或未遵循特定语言的安全最佳实践。
  • 应用程序部署阶段:由于缺乏所需的技术技能或缺乏完善的文档,在应用程序设置(安装和配置活动)过程中可能会出现问题。

测试目标

  • 确保身份验证应用于所有需要它的服务。

测试方法

有几种方法可以绕过Web应用程序使用的身份验证方案:

  • 直接页面请求(强制浏览
  • 参数修改
  • 会话ID预测
  • SQL注入

直接页面请求

如果Web应用程序仅在登录页面上实现访问控制,则可能会绕过身份验证方案。例如,如果用户通过强制浏览直接请求不同的页面,该页面在授予访问权限之前可能不会检查用户的凭据。可以尝试通过浏览器的地址栏直接访问受保护的页面,以此来进行测试。

在这里插入图片描述

图4.4.4 - 1:直接请求受保护页面

参数修改

身份验证设计的另一个问题是,当应用程序基于固定值参数验证登录是否成功时,用户可以修改这些参数,从而在不提供有效凭据的情况下访问受保护区域。在以下示例中,“authenticated”参数被更改为“yes”,从而允许用户获得访问权限。在这个例子中,参数位于URL中,但也可以使用代理来修改参数,特别是当参数作为POST请求中的表单元素发送,或者参数存储在cookie中时。

https://www.site.com/page.asp?authenticated=no

raven@blackbox /home $nc www.site.com 80
GET /page.asp?authenticated=yes HTTP/1.0

HTTP/1.1 200 OK
Date: Sat, 11 Nov 2006 10:22:44 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
</HEAD><BODY>
<H1>You Are Authenticated</H1>
</BODY></HTML>

在这里插入图片描述

图4.4.4 - 2:参数修改后的请求

会话ID预测

许多Web应用程序使用会话标识符(会话ID)来管理身份验证。因此,如果会话ID的生成是可预测的,恶意用户就有可能找到有效的会话ID,并冒充之前通过身份验证的用户,未经授权访问应用程序。

在下图中,cookie中的值呈线性增长,因此攻击者很容易猜测出有效的会话ID。

在这里插入图片描述

图4.4.4 - 3:随时间变化的cookie值

在下图中,cookie中的值仅部分更改,因此可以将暴力破解攻击限制在以下所示的定义字段内。

在这里插入图片描述

图4.4.4 - 4:部分更改的cookie值

SQL注入(HTML表单身份验证)

SQL注入是一种广为人知的攻击技术。本节不会详细描述这种技术,因为本指南中有多个章节对注入技术进行了超出本节范围的解释。

在这里插入图片描述

图4.4.4 - 5:SQL注入

下图显示,通过简单的SQL注入攻击,有时可以绕过身份验证表单。

在这里插入图片描述

图4.4.4 - 6:简单的SQL注入攻击

PHP宽松比较

如果攻击者通过利用先前发现的漏洞(例如目录遍历)或从Web存储库(开源应用程序)中获取了应用程序源代码,则有可能针对身份验证过程的实现进行精细攻击。

在以下示例(PHPBB 2.0.12 - 身份验证绕过漏洞)中,第2行的unserialize()函数解析用户提供的cookie,并将值设置在$sessiondata数组中。在第7行,将存储在后端数据库中的用户MD5密码哈希值($auto_login_key)与用户提供的密码哈希值($sessiondata['autologinid'])进行比较。

1. if (isset($HTTP_COOKIE_VARS[$cookiename . '_sid'])) {
2.     $sessiondata = isset($HTTP_COOKIE_VARS[$cookiename . '_data']) ? unserialize(stripslashes($HTTP_COOKIE_VARS[$cookiename . '_data'])) : array();
3.     $sessionmethod = SESSION_METHOD_COOKIE;
4. }
5. $auto_login_key = $userdata['user_password'];
6. // 我们必须自动登录
7. if( $sessiondata['autologinid'] == $auto_login_key )
8. {
9.     // autologinid 与密码匹配
10.     $login = 1;
11.     $enable_autologin = 1;
12. }

在PHP中,字符串值与布尔值true的比较结果始终为true(因为字符串包含值)。因此,通过向unserialize()函数提供以下字符串,可以绕过身份验证控制并以管理员身份登录(管理员的userid为2):

a:2:{s:11:"autologinid";b:1;s:6:"userid";s:1:"2";}  // 原始值: a:2:{s:11:"autologinid";s:32:"8b8e9715d12e4ca12c4c3eb4865aaf6a";s:6:"userid";s:4:"1337";}

让我们拆解一下这个字符串的操作:

  1. autologinid现在是一个布尔值,设置为true:可以通过将密码哈希的MD5值(s:32:"8b8e9715d12e4ca12c4c3eb4865aaf6a")替换为b:1来看到这一点。
  2. userid现在设置为管理员ID:可以在字符串的最后部分看到,我们将常规用户ID(s:4:"1337")替换为s:1:"2"

工具

参考资料

易受攻击的记住密码功能测试

编号
WSTG-ATHN-05

概述

凭证是应用最为广泛的身份验证技术。由于用户名 - 密码组合的广泛使用,用户已难以妥善管理其在众多应用程序中使用的凭证。

为帮助用户管理凭证,多种技术应运而生:

  • 应用程序提供“记住我”功能,使用户能够长时间保持登录状态,无需再次输入凭证。
  • 密码管理器(包括浏览器自带的密码管理器),使用户能够安全地存储其凭证,并在需要时自动填充到用户表单中,无需用户手动干预。

测试目标

  • 验证生成的会话是否得到安全管理,确保用户凭证不会面临风险。

测试方法

虽然这些方法提升了用户体验,使用户无需记住凭证,但同时也扩大了攻击面。部分应用程序存在以下问题:

  • 以编码形式将凭证存储在浏览器的存储机制中。可通过遵循Web 存储测试场景会话分析场景进行验证。凭证不应以任何方式存储在客户端应用程序中,而应使用服务器端生成的令牌代替。
  • 自动填充用户凭证,这可能会被以下攻击方式利用:
  • 应分析令牌的生命周期,某些令牌永不过期,一旦被盗取,将使用户面临风险。务必遵循会话超时测试场景

修复建议

  • 遵循会话管理的最佳实践。
  • 确保凭证不以明文形式存储,也不以容易检索的编码或加密形式存储在浏览器的存储机制中;凭证应存储在服务器端,并遵循良好的密码存储实践。

浏览器缓存漏洞测试

ID
WSTG - ATHN - 06

概述

在此阶段,测试人员需检查应用程序是否正确指示浏览器不要保留敏感数据。

浏览器会出于缓存和历史记录的目的存储信息。缓存用于提高性能,这样之前显示过的信息就无需再次下载。历史记录机制则是为了方便用户,使用户能够准确查看资源检索时所看到的内容。如果向用户显示了敏感信息(如他们的地址、信用卡详情、社会安全号码或用户名),那么这些信息可能会被存储用于缓存或历史记录,因此可以通过检查浏览器缓存或简单地按下浏览器的“后退”按钮来获取。

测试目标

  • 审查应用程序是否在客户端存储敏感信息。
  • 审查是否可以在未经授权的情况下访问这些信息。

测试方法

浏览器历史记录

从技术上讲,“后退”按钮属于历史记录而非缓存(参见[HTTP 中的缓存:历史列表](https://www.w3.org/Protocols/rfc2616/rfc2616 - sec13.html#sec13.13))。缓存和历史记录是两个不同的概念。然而,它们都存在显示之前显示过的敏感信息的相同风险。

第一个也是最简单的测试是,在应用程序中输入敏感信息,然后注销。接着,测试人员点击浏览器的“后退”按钮,检查在未认证的情况下是否可以访问之前显示的敏感信息。

如果按下“后退”按钮后,测试人员可以访问之前的页面,但无法访问新页面,那么这不是认证问题,而是浏览器历史记录问题。如果这些页面包含敏感数据,这意味着应用程序没有禁止浏览器存储这些数据。

测试不一定需要涉及认证。例如,当用户输入他们的电子邮件地址以订阅时事通讯时,如果处理不当,这些信息可能会被获取。

可以通过以下方法阻止“后退”按钮显示敏感数据:

  • 通过 HTTPS 传输页面。
  • 设置 Cache - Control: must - revalidate

浏览器缓存

在此,测试人员要检查应用程序是否不会将任何敏感数据泄露到浏览器缓存中。为此,他们可以使用代理(如 ZAP),并搜索属于该会话的服务器响应,检查每个包含敏感信息的页面,服务器是否指示浏览器不要缓存任何数据。可以在 HTTP 响应头中使用以下指令来发出此类指示:

  • Cache - Control: no - cache, no - store
  • Expires: 0
  • Pragma: no - cache

这些指令通常很有效,不过,为了更好地防止文件系统上的持久链接文件被缓存,Cache - Control 头可能需要额外的标志。这些标志包括:

  • Cache - Control: must - revalidate, max - age = 0, s - maxage = 0
HTTP/1.1:
Cache-Control: no-cache
HTTP/1.0:
Pragma: no-cache
Expires: "过去的日期或非法值(例如,0)"

例如,如果测试人员正在测试一个电子商务应用程序,他们应该查找所有包含信用卡号码或其他财务信息的页面,并检查所有这些页面是否强制执行了 no - cache 指令。如果他们发现包含关键信息的页面未能指示浏览器不要缓存其内容,他们就知道敏感信息将被存储在磁盘上,他们可以通过在浏览器缓存中查找该页面来再次确认。

该信息的确切存储位置取决于客户端操作系统和所使用的浏览器。以下是一些示例:

  • Mozilla Firefox:
    • Unix/Linux:~/.cache/mozilla/firefox/
    • Windows:C:\Users\<用户名>\AppData\Local\Mozilla\Firefox\Profiles\<配置文件 ID>\Cache2\
  • Internet Explorer:
    • C:\Users\<用户名>\AppData\Local\Microsoft\Windows\INetCache\
  • Chrome:
    • Windows:C:\Users\<用户名>\AppData\Local\Google\Chrome\User Data\Default\Cache
    • Unix/Linux:~/.cache/google-chrome
查看缓存信息

Firefox 提供了查看缓存信息的功能,这对测试人员可能会有帮助。当然,行业内也开发了各种扩展和外部应用程序,你可能会更喜欢或需要用于 Chrome、Internet Explorer 或 Edge。

大多数现代浏览器的开发者工具也可以查看缓存详细信息,如 FirefoxChrome 和 Edge。在 Firefox 中,还可以使用 about:cache URL 来检查缓存详细信息。

检查移动浏览器的处理情况

移动浏览器对缓存指令的处理可能完全不同。因此,测试人员应该以干净的缓存开始新的浏览会话,并利用 Chrome 的 设备模式 或 Firefox 的 响应式设计模式 等功能,重新测试或单独测试上述概念。

此外,像 ZAP 和 Burp Suite 这样的个人代理允许测试人员指定其爬虫应发送的 User - Agent。可以将其设置为匹配移动浏览器的 User - Agent 字符串,以查看被测试应用程序发送的缓存指令。

灰盒测试

测试方法与黑盒测试情况相同,因为在这两种情况下,测试人员都可以完全访问服务器响应头和 HTML 代码。然而,在灰盒测试中,测试人员可能可以访问账户凭证,这将使他们能够测试只有经过认证的用户才能访问的敏感页面。

工具

参考资料

白皮书

  • [HTTP 中的缓存](https://www.w3.org/Protocols/rfc2616/rfc2616 - sec13.html)

弱认证方法测试

编号
WSTG-ATHN-07

概述

最常见且最易于管理的认证机制是静态密码。密码就像是进入王国的钥匙,但用户常常为了追求易用性而忽视其安全性。在近期多起泄露用户凭证的重大黑客攻击事件中,令人遗憾的是,最常用的密码仍然是 123456passwordqwerty

此外,应用程序可能会使用一些替代凭证,这些凭证在认证过程中与密码的作用相同,但安全性却大大降低,例如出生日期、社会安全号码、个人识别码(PIN)或安全问题的答案。在某些情况下,这些更容易被猜到的凭证可能是用户进行认证时唯一提供的值。

测试目标

通过评估密码的长度、复杂度、复用性和使用期限要求,确定应用程序对使用可用密码字典进行暴力猜解密码攻击的抵抗能力。

测试方法

  1. 密码允许和禁止使用哪些字符?是否要求用户使用不同字符集的字符,如大小写字母、数字和特殊符号?
  2. 用户可以多久更改一次密码?用户在上一次更改密码后多久可以再次更改密码?用户可能会通过连续更改 5 次密码来绕过密码历史记录要求,从而在最后一次更改后重新使用初始密码。
  3. 用户必须在什么时候更改密码?
    • 美国国家标准与技术研究院(NIST)(https://pages.nist.gov/800 - 63 - 3/sp800 - 63b.html#memsecretver)和英国国家网络安全中心(NCSC)(https://www.ncsc.gov.uk/collection/passwords/updating - your - approach#PasswordGuidance:UpdatingYourApproach - Don’tenforceregularpasswordexpiry)都不建议强制定期更换密码,尽管某些标准(如支付卡行业数据安全标准 PCI DSS)可能有此要求。
  4. 用户可以多久复用一次密码?应用程序是否会记录用户之前使用过的 8 个密码?
  5. 下一个密码与上一个密码之间的差异必须达到多大?
  6. 是否禁止用户在密码中使用其用户名或其他账户信息(如名或姓)?
  7. 可以设置的密码最小和最大长度是多少?这些长度对于账户和应用程序的敏感程度是否合适?
  8. 是否可以设置常见密码,如 Password1123456
  9. 应用程序是否为用户选择了替代凭证,如社会安全号码或出生日期?替代标准密码使用的凭证是否容易获取、可预测或容易受到暴力攻击?

修复建议

为了降低因容易被猜到的密码而导致未经授权访问的风险,有两种解决方案:引入额外的认证控制(即双因素认证)或实施严格的密码策略。其中最简单且成本最低的方法是实施严格的密码策略,确保密码的长度、复杂度、复用性和使用期限符合要求;不过,理想情况下,两种方法都应该实施。

参考资料

弱安全问题答案测试

编号
WSTG-ATHN-08

概述

安全问题及其答案通常被称为“秘密”问题和答案,常被用于找回遗忘的密码(参见弱密码更改或重置功能测试),或者作为密码之外的额外安全保障。

这些问题通常在创建账户时生成,要求用户从预先生成的问题中进行选择,并提供合适的答案。有些系统可能允许用户自行创建问题和答案对。但这两种方式都存在安全隐患。理想情况下,安全问题的答案应该只有用户自己知道,且不能被其他人猜测或发现,然而实际做到这一点比听起来要困难。

安全问题及其答案依赖于答案的保密性。问题和答案的选择应确保只有账户持有者知晓答案。不过,尽管很多答案可能并非公开信息,但大多数网站采用的问题所引出的答案往往只是伪私密的。

预先生成的问题

大多数预先生成的问题本质上相当简单,可能导致不安全的答案。例如:

  • 答案可能为用户的家人或密友所知,例如“你母亲的娘家姓是什么?”“你的出生日期是什么?”
  • 答案可能很容易被猜到,例如“你最喜欢的颜色是什么?”“你最喜欢的棒球队是哪个?”
  • 答案可能容易被暴力破解,例如“你高中最喜欢的老师的名字是什么?”——答案可能会出现在一些容易下载到的常用名字列表中,因此可以编写简单的暴力破解脚本进行攻击。
  • 答案可能可以在公开渠道找到,例如“你最喜欢的电影是什么?”——答案可能很容易在用户的社交媒体个人资料页面上找到。

用户自行生成的问题

允许用户自行生成问题的弊端在于,用户可能会生成非常不安全的问题,甚至完全违背设置安全问题的初衷。以下是一些现实中的例子:

  • “1 + 1 等于多少?”
  • “你的用户名是什么?”
  • “我的密码是 S3curIty!”

测试目标

  • 确定问题的复杂程度和直接程度。
  • 评估可能的用户答案以及暴力破解的可能性。

测试方法

预先生成的弱问题测试

尝试通过创建新账户或按照“我忘记密码”的流程来获取安全问题列表。尽可能多地生成问题,以便全面了解所询问的安全问题类型。如果任何安全问题属于上述类别,那么它们就容易受到攻击(被猜测、暴力破解、从社交媒体获取等)。

用户自行生成的弱问题测试

尝试通过创建新账户或配置现有账户的密码找回属性来创建安全问题。如果系统允许用户自行生成安全问题,那么就可能存在创建不安全问题的风险。如果系统在忘记密码功能中使用用户自行生成的安全问题,并且用户名可以被枚举(参见账户枚举和可猜测用户账户测试),那么测试人员应该能够轻松枚举大量用户自行生成的问题。使用这种方法应该可以发现一些弱的用户自行生成的问题。

可暴力破解答案的测试

使用弱锁定机制测试中描述的方法,确定多次提供错误的安全问题答案是否会触发锁定机制。

尝试利用安全问题时,首先要考虑的是需要回答的问题数量。大多数应用程序只要求用户回答一个问题,而一些关键应用程序可能要求用户回答两个或更多问题。

下一步是评估安全问题的强度。答案能否通过简单的谷歌搜索或社会工程学攻击获得?作为渗透测试人员,以下是利用安全问题方案的详细步骤:

  • 应用程序是否允许最终用户选择需要回答的问题?如果是,应关注以下类型的问题:
    • 答案为“公开”信息的问题,例如可以通过简单的搜索引擎查询找到的内容。
    • 答案为事实性信息的问题,如“第一所学校”或其他可以查询到的事实。
    • 可能答案较少的问题,例如“你的第一辆车是什么型号”。这类问题会为攻击者提供一个简短的可能答案列表,攻击者可以根据统计数据对答案从最有可能到最不可能进行排序。
  • 尽可能确定允许尝试猜测的次数。
    • 密码重置功能是否允许无限制尝试?
    • 在输入 X 次错误答案后是否有锁定期?请记住,锁定系统本身也可能存在安全问题,因为攻击者可以利用它对合法用户发起拒绝服务攻击。
    • 根据上述分析选择合适的问题,并进行研究以确定最有可能的答案。

成功利用和绕过弱安全问题方案的关键在于找到一个或一组能够轻松找到答案的问题。如果对所有答案都不确定,始终要寻找那些能让你有最大统计概率猜对正确答案的问题。归根结底,一个安全问题方案的强度取决于其中最弱的问题。

参考资料

弱密码更改或重置功能测试

编号
WSTG-ATHN-09

概述

对于任何要求用户使用密码进行身份验证的应用程序,必须有一种机制,让用户在忘记密码时能够重新访问其账户。虽然有时这可能是一个手动过程,需要联系网站所有者或支持团队,但通常会允许用户进行自助式密码重置,并通过提供其他身份验证信息来重新访问其账户。

由于此功能为攻击者入侵用户账户提供了直接途径,因此安全地实现该功能至关重要。

测试目标

  • 确定密码更改和重置功能是否会导致账户被入侵。

测试方法

信息收集

第一步是收集有关应用程序中可供用户重置密码的机制的信息。如果同一网站存在多个接口(如 Web 接口、移动应用程序和 API),则应对所有这些接口进行审查,以防它们提供不同的功能。

确定这些信息后,明确用户发起密码重置所需的信息。这可能是用户名或电子邮件地址(这两者都可能从公开信息中获取),也可能是内部生成的用户 ID。

一般注意事项

无论使用何种具体方法重置密码,都有一些常见的方面需要考虑:

  • 密码重置过程是否比身份验证过程更弱?

    密码重置过程提供了访问用户账户的另一种机制,因此至少应与常规身份验证过程一样安全。然而,它可能为入侵账户提供更便捷的途径,特别是当它使用较弱的身份验证因素(如安全问题)时。

    此外,密码重置过程可能会绕过多因素身份验证(MFA)的要求,这会显著降低应用程序的安全性。

  • 是否有速率限制或其他防止自动化攻击的保护措施?

    与任何身份验证机制一样,密码重置过程应具备防止自动化或暴力攻击的保护措施。可以使用多种不同的方法来实现这一点,例如速率限制或使用验证码(CAPTCHA)。在触发外部操作(如发送电子邮件或短信)的功能中,或者在用户输入密码重置令牌时,这些措施尤为重要。

    也可以通过在连续多次尝试失败后锁定账户的密码重置功能来防止暴力攻击。然而,这也可能会阻止合法用户重置密码并重新访问其账户。

  • 是否容易受到常见攻击?

    除了本指南中讨论的特定方面,检查是否存在其他常见漏洞(如 SQL 注入或跨站脚本攻击)也很重要。

  • 重置过程是否允许用户枚举?

    有关更多信息,请参阅账户枚举测试指南。

通过电子邮件发送新密码

在这种模式下,用户证明其身份后,系统会通过电子邮件向其发送新密码。这种方法被认为不太安全,主要有两个原因:

  • 密码以未加密的形式发送给用户。
  • 请求发出后,账户密码会被更改,这实际上会使用户在收到电子邮件之前无法访问其账户。通过重复请求,有可能阻止用户访问其账户。

如果采用这种方法,应审查以下方面:

  • 用户首次登录时是否必须更改密码?

    新密码通过未加密的电子邮件发送,如果用户不删除该邮件,它可能会无限期地留在用户的收件箱中。因此,用户首次登录时应被要求更改密码。

  • 密码是否安全生成?

    密码应使用加密安全的伪随机数生成器(CSPRNG)生成,并且长度应足够长,以防止密码猜测或暴力攻击。为了提供安全且用户友好的体验,应使用安全的密码短语方式(即组合多个单词)生成密码,而不是使用随机字符串。

  • 是否将用户的现有密码发送给他们?

    一些应用程序不是为用户生成新密码,而是将其现有密码发送给他们。这是一种非常不安全的方法,因为它会通过未加密的电子邮件暴露用户的当前密码。此外,如果网站能够恢复现有密码,这意味着密码要么使用可逆加密存储,要么(更有可能)以未加密的明文形式存储,这两者都代表着严重的安全漏洞。

  • 电子邮件是否从具有反欺骗保护的域名发送?

    域名应实施 SPF、DKIM 和 DMARC,以防止攻击者伪造来自该域名的电子邮件,这些伪造的邮件可能会被用于社会工程攻击。

  • 是否认为电子邮件足够安全?

    电子邮件通常以未加密的形式发送,而且在很多情况下,用户的电子邮件账户不会受到 MFA 的保护。此外,电子邮件账户可能会被多个人共享,特别是在企业环境中。

    根据正在测试的应用程序的上下文,考虑基于电子邮件的密码重置功能是否合适。

通过电子邮件发送链接

在这种模式下,系统会向用户发送包含令牌的链接。用户可以点击该链接,然后在网站上被提示输入新密码。这是最常用的密码重置方法,但比前面讨论的方法更复杂。需要测试的关键方面包括:

  • 链接是否使用 HTTPS?

    如果令牌通过未加密的 HTTP 发送,攻击者可能会拦截它。

  • 链接是否可以多次使用?

    链接使用后应过期,否则它们会为账户提供一个持久的后门。

  • 链接如果未使用是否会过期?

    链接应该有时间限制。具体的时间长度应根据网站而定,但通常不应超过一小时。

  • 令牌是否足够长且随机?

    该过程的安全性完全依赖于攻击者无法猜测或暴力破解令牌。令牌应使用加密安全的伪随机数生成器(CSPRNG)生成,并且长度应足够长,使攻击者无法猜测或暴力破解。至少 128 位(或 32 个十六进制字符)是使此类在线攻击不可行的最低要求。

    令牌绝不能基于已知值生成,例如通过对用户的电子邮件进行 MD5 哈希处理(md5($email)),或者使用可能使用不安全 PRNG 函数的 GUID,或者根据类型甚至可能不是随机的。

    另一种替代随机令牌的方法是使用加密签名的令牌,如 JWT。在这种情况下,应进行常规的 JWT 检查(签名是否验证、是否可以使用“none”算法、HMAC 密钥是否可以被暴力破解等)。有关更多信息,请参阅JSON Web 令牌测试指南。

  • 链接是否包含用户 ID?

    有时密码重置链接可能会同时包含用户 ID 和令牌,例如 reset.php?userid=1&token=123456。在这种情况下,可能可以修改 userid 参数来重置其他用户的密码。

  • 是否可以注入不同的主机头?

    如果应用程序信任 Host 头的值并使用它来生成密码重置链接,则可能可以通过在请求中注入修改后的 Host 头来窃取令牌。有关更多信息,请参阅主机头注入测试指南。

  • 链接是否会暴露给第三方?

    如果用户被重定向到的页面包含来自其他方的内容(例如从其他域名加载脚本),则 URL 中的重置令牌可能会在这些请求发送的 HTTP Referer 头中暴露。可以使用 Referrer-Policy HTTP 头来防止这种情况,因此要检查该页面是否定义了该头。

    此外,如果页面包含任何跟踪、分析或广告脚本,令牌也会暴露给它们。

  • 电子邮件是否从具有反欺骗保护的域名发送?

    域名应实施 SPF、DKIM 和 DMARC,以防止攻击者伪造来自该域名的电子邮件,这些伪造的邮件可能会被用于社会工程攻击。

  • 是否认为电子邮件足够安全?

    电子邮件通常以未加密的形式发送,而且在很多情况下,用户的电子邮件账户不会受到 MFA 的保护。此外,电子邮件账户可能会被多个人共享,特别是在企业环境中。

    根据正在测试的应用程序的上下文,考虑基于电子邮件的密码重置功能是否合适。

通过短信或电话发送令牌

除了通过电子邮件发送令牌外,另一种方法是通过短信或自动电话呼叫发送令牌,用户随后在应用程序中输入该令牌。需要测试的关键方面包括:

  • 令牌是否足够长且随机?

    通过这种方式发送的令牌通常较短,因为它们是供用户手动输入的,而不是嵌入在链接中。应用程序通常使用六位数字,这仅提供约 20 位的安全性(对于在线暴力攻击来说是可行的),而不像通常较长的电子邮件令牌。

    这使得保护密码重置功能免受暴力攻击变得更加重要。

  • 令牌是否可以多次使用?

    令牌使用后应失效,否则它们会为账户提供一个持久的后门。

  • 令牌如果未使用是否会过期?

    由于较短的令牌更容易受到暴力攻击,因此应设置较短的过期时间,以限制攻击者进行攻击的时间窗口。

  • 是否有适当的速率限制和限制措施?

    向用户发送短信或触发自动电话呼叫比发送电子邮件更具干扰性,可能会被用于骚扰用户,甚至对其手机进行拒绝服务攻击。应用程序应实施速率限制以防止这种情况。

    此外,短信和电话呼叫通常会给发送方带来财务成本。如果攻击者能够导致大量消息被发送,这可能会给网站运营商带来巨大成本。如果发送到国际或高价号码,情况尤其如此。然而,允许使用国际号码可能是应用程序的要求。

  • 是否认为短信或电话足够安全?

    多种攻击方式已被证明可以让攻击者有效地劫持短信,对于短信是否足够安全以用作身份验证因素存在不同观点。

    通常,在无需任何 PIN 或指纹解锁手机的情况下,只要物理上能够访问设备就可以接听自动电话。在某些情况下(如共享办公环境),这可能会使内部攻击者在用户离开办公室时轻松走到其办公桌前重置其他用户的密码。

    根据正在测试的应用程序的上下文,考虑短信或自动电话呼叫是否合适。

安全问题

除了发送链接或新密码外,安全问题也可以用作验证用户身份的机制。这种方法被认为是较弱的,如有更好的选择,不应使用。

有关更多信息,请参阅弱安全问题测试指南。

认证身份和配置更改

如果应用程序支持修改账户的主要标识符(如电子邮件地址或电话号码),而这些标识符又用于密码更改和重置功能,则应要求用户重新进行身份验证。当密码更改功能中使用的主要标识符可以在不重新进行身份验证的情况下被修改时,就可以绕过密码更改功能中的重新身份验证。总体而言,任何影响账户安全的设置(电子邮件、MFA、备份设置等)在修改之前都应要求重新进行身份验证。

例如:一个应用程序的密码重置流程是向账户的电子邮件地址发送重置链接。如果从已认证用户的角度尝试更改密码,该应用程序也要求重新进行身份验证。如果攻击者获得了账户访问权限(通过窃取的 cookie、物理访问计算机等),并且在无需重新进行身份验证的情况下更改了账户的电子邮件地址,那么就可以使用密码重置流程来更改密码,从而绕过已认证的密码更改流程。

已认证用户的密码更改

一旦用户证明了自己的身份(可以通过密码重置链接、恢复码或在应用程序中登录),他们应该能够更改自己的密码。需要测试的关键方面如下:

  • 设置密码时,能否指定用户 ID?

    如果密码重置请求中包含用户 ID 且未对其进行验证,那么就有可能对其进行修改,从而更改其他用户的密码。

  • 是否要求用户重新进行身份验证?

    如果已登录的用户尝试更改密码,应该要求他们使用当前密码重新进行身份验证,以防止攻击者临时获取无人值守的会话权限。如果用户启用了多因素身份验证(MFA),则通常应使用 MFA 进行重新身份验证,而不是使用密码。

  • 密码更改表单是否容易受到跨站请求伪造(CSRF)攻击?

    如果不要求用户重新进行身份验证,那么就有可能针对密码重置表单实施 CSRF 攻击,从而导致用户账户被盗用。更多信息请参阅跨站请求伪造测试指南。

  • 是否应用了强大且有效的密码策略?

    密码策略应在注册、密码更改和密码重置功能中保持一致。更多信息请参阅弱身份验证方法测试指南。

参考资料

测试替代通道中的弱身份验证

编号
WSTG-ATHN-10

概述

即使主要身份验证机制不存在任何漏洞,同一用户账户的合法替代身份验证用户通道中仍可能存在漏洞。应进行测试以识别这些替代通道,并根据测试范围确定是否存在漏洞。

这些替代用户交互通道可能被用于绕过主要通道,或者泄露可用于攻击主要通道的信息。其中一些通道本身可能是使用不同主机名或路径的独立 Web 应用程序。例如:

  • 标准网站
  • 针对移动设备或特定设备优化的网站
  • 针对无障碍访问优化的网站
  • 不同国家和语言版本的网站
  • 使用相同用户账户的并行网站(例如,同一组织提供不同功能的另一个网站、共享用户账户的合作伙伴网站)
  • 标准网站的开发、测试、用户验收测试(UAT)和预发布版本

但它们也可能是其他类型的应用程序或业务流程:

  • 移动设备应用程序
  • 桌面应用程序
  • 呼叫中心操作员
  • 交互式语音应答或电话菜单系统

请注意,此测试的重点是替代通道;一些身份验证替代方案可能表现为通过同一网站提供的不同内容,这些内容几乎肯定在测试范围内。这里不再进一步讨论这些内容,它们应该在信息收集和主要身份验证测试期间被识别出来。例如:

  • 改变功能的渐进式增强和优雅降级
  • 不使用 cookie 的网站访问
  • 不使用 JavaScript 的网站访问
  • 不使用 Flash 和 Java 等插件的网站访问

即使测试范围不允许对替代通道进行测试,也应记录它们的存在。这些替代通道可能会削弱身份验证机制的可信度,并且可能是进行额外测试的前奏。

示例

主要网站为 https://www.example.com,身份验证功能始终在使用 TLS 的页面 https://www.example.com/myaccount/ 上进行。

然而,存在一个单独的针对移动设备优化的网站,该网站根本不使用 TLS,并且其密码恢复机制较弱,网址为 https://m.example.com/myaccount/

测试目标

  • 识别替代身份验证通道。
  • 评估替代通道使用的安全措施,以及是否存在绕过机制。

测试方法

了解主要机制

对网站的主要身份验证功能进行全面测试。这应确定账户是如何发放、创建或更改的,以及密码是如何恢复、重置或更改的。此外,还应了解任何高级权限身份验证和身份验证保护措施。这些前期工作对于与任何替代通道进行比较是必要的。

识别其他通道

可以使用以下方法找到其他通道:

  • 阅读网站内容,特别是主页、联系我们、帮助页面、支持文章、常见问题解答(FAQ)、条款与条件、隐私声明、robots.txt 文件和任何 sitemap.xml 文件。
  • 在之前信息收集和测试期间记录的 HTTP 代理日志中搜索 URL 路径和正文内容中的字符串,如“mobile”、“android”、“blackberry”、“ipad”、“iphone”、“mobile app”、“e-reader”、“wireless”、“auth”、“sso”、“single sign on”。
  • 使用搜索引擎查找同一组织的不同网站,或使用相同域名且主页内容相似或也具有身份验证机制的网站。

对于每个可能的通道,确认用户账户是否在这些通道之间共享,或者是否提供相同或相似的功能。

枚举身份验证功能

对于用户账户或功能共享的每个替代通道,确定主要通道的所有身份验证功能是否可用,以及是否存在额外的功能。创建如下所示的表格可能会很有用:

主要通道移动应用呼叫中心合作伙伴网站
注册--
登录是(单点登录)
注销---
密码重置-
-修改密码--

在这个示例中,移动应用有一个额外的功能“修改密码”,但不提供“注销”功能。通过拨打呼叫中心电话也可以完成有限的任务。呼叫中心可能很关键,因为它们的身份确认检查可能比网站的更弱,这使得该通道可被用于协助攻击用户账户。

在枚举这些功能时,值得注意会话管理是如何进行的,以防任何通道之间存在重叠(例如,作用域为同一父域名的 cookie,允许跨通道但不允许在同一通道上进行并发会话)。

审查和测试

即使替代通道被标记为“仅作信息参考”或“不在测试范围内”,也应在测试报告中提及它们。在某些情况下,测试范围可能包括替代通道(例如,因为它只是目标主机名上的另一个路径),或者在与所有通道的所有者讨论后可能会将其添加到测试范围内。如果允许并授权进行测试,则应执行本指南中的所有其他身份验证测试,并与主要通道进行比较。

相关测试用例

应使用所有其他身份验证测试的测试用例。

修复建议

确保在所有通道上应用一致的身份验证策略,以确保它们具有同等的安全性。

多因素身份验证(MFA)测试

编号
WSTG-ATHN-11

概述

许多应用程序将多因素身份验证(MFA)作为额外的安全层,以保护登录过程。这也被称为双因素身份验证(2FA)或两步验证(2SV),不过严格来说,它们并不完全相同。MFA 意味着在用户登录时,要求其提供至少两种不同的身份验证因素

MFA 给身份验证功能以及其他与安全相关的领域(如凭证管理和密码恢复)带来了额外的复杂性。这意味着,以正确且可靠的方式实现 MFA 至关重要。

测试目标

  • 识别应用程序所使用的 MFA 类型。
  • 确定 MFA 的实现是否稳健且安全。
  • 尝试绕过 MFA。

测试方法

MFA 的类型

MFA 意味着进行身份验证时需要至少满足以下两种因素:

因素示例
你知道的信息密码、PIN 码和安全问题。
你拥有的物品硬件或软件令牌、证书、电子邮件*、短信和电话。
你的生物特征指纹、面部识别、虹膜扫描、掌纹扫描和行为因素。
位置源 IP 地址范围和地理位置。
  • 只有当电子邮件账户本身使用 MFA 进行保护时,电子邮件才能真正算作“你拥有的物品”。因此,它应被视为比证书或基于时间的一次性密码(TOTP)等其他方式更弱的验证方式,并且在某些定义下,它可能不被视为 MFA。

请注意,要求提供单一因素的多个示例(例如同时需要密码和 PIN 码)并不构成 MFA,尽管与简单密码相比,它可能会提供一定的安全优势,并且可能被视为两步验证(2SV)。

由于在基于浏览器的环境中实现生物识别技术具有复杂性,“你的生物特征”在 Web 应用程序中很少使用,不过随着 WebAuthn 等标准的出现,这种情况开始有所改变。最常见的第二因素是“你拥有的物品”。

检查 MFA 绕过漏洞

测试 MFA 的第一步是识别应用程序中的所有身份验证功能,这些功能可能包括:

  • 主登录页面。
  • 安全关键功能(如禁用 MFA 或更改密码)。
  • 联合登录提供商。
  • API 端点(包括主 Web 界面和移动应用的端点)。
  • 替代(非 HTTP)协议。
  • 测试或调试功能。

应该审查所有不同的登录方法,以确保 MFA 得到一致执行。如果某些方法不需要 MFA,那么攻击者可以利用这些方法轻松绕过 MFA。

如果身份验证分多个步骤进行,那么攻击者可能会在完成身份验证过程的第一步(输入用户名和密码)后,通过直接浏览应用程序或直接进行 API 请求,而不完成第二步(输入 MFA 代码)来绕过 MFA。

如果身份验证使用的是允许自定义身份验证流程(或策略)的 OpenID Connect(OIDC)提供商(如 Azure B2C),可能会定义多个流程,其中一些可能不需要 MFA。例如,如果应用程序使用名为 B2C_1_SignInWithMFA 的流程进行身份验证,那么可以尝试将其篡改 为 B2C_1_SignInB2C_1_SignInWithoutMFA 或其他类似的值。

在某些情况下,可能还会有意实现 MFA 绕过机制,例如在以下情况下不要求使用 MFA:

  • 从特定 IP 地址访问(这些 IP 地址可能可以通过 X-Forwarded-For HTTP 标头进行伪造)。
  • 当设置了特定的 HTTP 标头时(例如非标准标头 X-Debug)。
  • 对于特定的硬编码账户(如“root”或“应急”账户)。

如果应用程序同时支持本地登录和联合登录,并且这两种类型的账户之间没有进行严格的分离,那么就有可能绕过 MFA。例如,如果用户注册了一个本地账户并为其配置了 MFA,但在联合登录提供商的账户上没有配置 MFA,攻击者可能会通过攻破用户在联合登录提供商的账户,在目标应用程序上重新注册(或关联)一个具有相同电子邮件地址的联合账户。

最后,如果 MFA 是在与主应用程序不同的系统上实现的(例如在反向代理上,以保护本身不支持 MFA 的旧应用程序),那么根据映射应用程序架构指南中所述,攻击者可能会通过直接连接到后端应用程序服务器来绕过 MFA。

检查 MFA 管理功能

应该测试用户账户内用于管理 MFA 的功能是否存在漏洞,包括:

检查 MFA 恢复选项

许多应用程序会为用户提供一种在无法使用第二因素进行身份验证时(例如丢失手机)重新访问其账户的方法。这些机制通常代表了应用程序的一个重大弱点,因为它们实际上允许绕过第二个身份验证因素。

恢复码

一些应用程序会在用户启用 MFA 时为其提供一组恢复码或备用码,用户可以使用这些代码进行登录。应该检查这些代码是否满足以下条件:

  • 代码足够长且复杂,以防止暴力破解攻击。
  • 代码是安全生成的。
  • 代码只能使用一次。
  • 有防止暴力破解的保护机制(如账户锁定)。
  • 当代码被使用时,用户会收到通知(通过电子邮件、短信等)。

有关更多详细信息,请参阅 OWASP 忘记密码备忘单 中的“备用代码”部分。

MFA 重置流程

如果应用程序实现了 MFA 重置流程,应该按照测试密码重置流程的相同方式对其进行测试。重要的是,这个流程的安全性至少要与应用程序的 MFA 实现一样强。

替代身份验证方式

一些应用程序允许用户通过其他方式证明其身份,例如使用安全问题。这通常代表了一个重大弱点,因为安全问题提供的安全级别远低于 MFA。

一次性密码

最常见的 MFA 形式是一次性密码(OTP),通常是六位数字代码(尽管长度可能不同)。这些代码可以由服务器和用户双方生成(例如使用身份验证器应用程序),也可以由服务器生成并发送给用户。有多种方式可以向用户提供 OTP,包括:

类型描述
HMAC 一次性密码(HOTP)基于密钥和共享计数器的 HMAC 生成代码。
基于时间的一次性密码(TOTP)基于密钥和当前时间的 HMAC 生成代码。
电子邮件通过电子邮件发送代码。
短信通过短信发送代码。
电话通过语音通话将代码发送到用户的电话号码。

通常,用户在提供用户名和密码后需要输入 OTP。应该进行以下各种检查:

  • 多次 MFA 尝试失败后,账户是否会被锁定?
  • 不同账户多次 MFA 尝试失败后,用户的 IP 地址是否会被阻止?
  • MFA 尝试失败是否会被记录?
  • 表单是否容易受到注入攻击,包括 SQL 通配符注入

根据所使用的 OTP 类型,还应该进行一些其他特定的检查:

  • OTP 是如何发送给用户的(电子邮件、短信、电话等)
    • 是否有速率限制,以防止短信/电话垃圾攻击造成费用损失?
  • OTP 的强度如何(长度和密钥空间)?
  • OTP 的有效期是多久?
  • 是否同时有多个 OTP 有效?
  • OTP 是否可以多次使用?
  • OTP 是否与正确的用户账户绑定,还是可以在其他账户上使用它们进行身份验证?
HOTP 和 TOTP

HOTP 和 TOTP 代码都基于服务器和用户之间共享的密钥。对于 TOTP 代码,通常会以二维码的形式提供给用户,用户使用身份验证器应用程序扫描该二维码(也可以以文本密钥的形式提供,让用户手动输入)。

如果密钥是在服务器上生成的,应该检查其是否足够长且复杂(RFC 4226 建议至少 160 位),并且是否使用安全的随机函数生成。

如果密钥可以由用户提供,应该强制执行适当的最小长度,并检查输入是否存在常见的注入攻击。

TOTP 代码通常有效期为 30 秒,但有些应用程序会选择接受多个代码(如前一个、当前和下一个代码),以处理服务器和用户设备上系统时间的差异。有些应用程序可能允许在当前代码两侧的多个代码有效,这可能会使攻击者更容易猜测或暴力破解代码。下表显示了在攻击者每秒可以进行 10 次请求的情况下,对于只接受当前代码或接受多个代码的应用程序,成功暴力破解 OTP 代码的概率(有关表格背后的计算,请参阅 这篇文章)。

有效代码数量1 小时后的成功率4 小时后的成功率12 小时后的成功率24 小时后的成功率
14%13%35%58%
310%35%72%92%
516%51%88%99%
722%63%95%99%
电子邮件、短信和电话

如果代码由服务器生成并发送给客户端,应该考虑以下方面:

  • 传输机制(电子邮件、短信或语音)对于应用程序来说是否足够安全?
  • 代码是否足够长且复杂?
  • 代码是否使用安全的随机函数生成?
  • 代码的有效期是多久?
  • 是否同时有多个代码有效,或者生成新代码是否会使之前的代码失效?
    • 是否可以通过反复请求代码来阻止用户访问账户?
  • 是否有足够的速率限制,以防止攻击者请求大量代码?
    • 大量的电子邮件代码可能会导致服务器因发送垃圾邮件而被封锁。
    • 大量的短信或语音通话可能会产生费用,或者被用于骚扰用户。

移动应用和推送通知

除了 OTP 代码之外,另一种方法是向用户的手机发送推送通知,用户可以选择批准或拒绝。这种方法不太常见,因为它要求用户安装特定应用程序的身份验证器。

要正确评估这种方法的安全性,需要将测试范围扩大到涵盖移动应用以及它所使用的任何支持 API 或服务;这通常超出了传统 Web 应用程序测试的范围。然而,即使不测试移动应用,也可以进行一些简单的检查,包括:

  • 通知是否提供了足够的上下文信息(IP 地址、位置等),以便用户能够做出明智的决定是否批准或拒绝?
  • 是否有任何挑战和响应机制(例如在网站上提供一个代码,用户需要在应用程序中输入该代码,通常称为“数字匹配”或“数字挑战”)?
  • 是否有速率限制或机制来防止用户被大量通知轰炸,从而盲目接受其中一个?

IP地址和位置过滤

多因素身份验证(MFA)有时会使用位置因素(“你所在的位置”),不过这是否能算作一种合适的身份验证因素存在争议。在Web应用程序的场景中,这通常意味着将访问限制在特定的IP地址,或者只要用户从特定的受信任IP地址连接,就不要求其提供第二个身份验证因素。常见的情况是,用户从办公室IP范围连接时,仅使用密码进行身份验证;而从其他地方连接时,则需要提供一次性密码(OTP)代码。

根据具体的实现方式,用户有可能通过设置X-Forwarded-For请求头来伪造受信任的IP地址,从而绕过此检查。需要注意的是,如果应用程序没有正确对该请求头的内容进行清理,那么还可能会在此处发起诸如SQL注入之类的攻击。如果应用程序支持IPv6,也应该检查是否对这些连接应用了适当的限制。

此外,应该对受信任的IP地址进行审查,以确保它们不存在任何弱点,例如包含以下情况:

  • 可能被不受信任的用户访问的IP地址(例如办公室中的访客无线网络)。
  • 可能会发生变化的动态分配IP地址。
  • 攻击者可以在其中托管自己系统的公共网络范围(例如Azure或AWS)。

证书和智能卡

传输层安全协议(TLS)通常用于加密客户端和服务器之间的通信流量,并为客户端提供一种确认服务器身份的机制(通过将证书上的通用名称(CN)或主题备用名称(SAN)与所请求的域名进行比较)。不过,它也可以为服务器提供一种确认客户端身份的机制,即客户端证书认证或双向TLS(mTLS)。本指南不详细讨论客户端证书认证,但关键原理是用户出示一个数字证书(存储在他们的机器或智能卡上),该证书由服务器进行验证。

测试时的第一步是确定目标应用程序是否限制了被信任颁发证书的证书颁发机构(CA)。可以使用各种工具来获取此信息,也可以手动检查TLS握手。最简单的方法是使用OpenSSL的s_client命令:

$ openssl s_client -connect example:443
[...]
可接受的客户端证书CA名称
C = US, ST = Example, L = Example, O = Example Org, CN = Example Org Root Certificate Authority
客户端证书类型:RSA签名、DSA签名、ECDSA签名

如果没有限制,那么就有可能使用来自不同CA的证书进行身份验证。如果有限制但实现不当,那么就有可能创建一个名称正确的本地CA(如上述示例中的“Example Org Root Certificate Authority”),并使用这个新的CA来签署客户端证书。

如果能够获得有效的证书,还应该验证该证书只能供其颁发对象的用户使用(即不能使用颁发给Alice的证书来在Bob的账户上进行身份验证)。此外,应该检查证书是否未过期且未被吊销。

相关测试用例

修复建议

确保做到以下几点:

  • 为应用程序上所有相关的账户和功能实现多因素身份验证(MFA)。
  • 所支持的MFA方法适合该应用程序。
  • 用于实现MFA的机制得到了适当的保护,能够抵御暴力破解攻击。
  • 对所有与MFA相关的活动进行适当的审计和日志记录。

有关更多建议,请参阅OWASP多因素身份验证备忘单

参考资料

务器进行验证。

测试时的第一步是确定目标应用程序是否限制了被信任颁发证书的证书颁发机构(CA)。可以使用各种工具来获取此信息,也可以手动检查TLS握手。最简单的方法是使用OpenSSL的s_client命令:

$ openssl s_client -connect example:443
[...]
可接受的客户端证书CA名称
C = US, ST = Example, L = Example, O = Example Org, CN = Example Org Root Certificate Authority
客户端证书类型:RSA签名、DSA签名、ECDSA签名

如果没有限制,那么就有可能使用来自不同CA的证书进行身份验证。如果有限制但实现不当,那么就有可能创建一个名称正确的本地CA(如上述示例中的“Example Org Root Certificate Authority”),并使用这个新的CA来签署客户端证书。

如果能够获得有效的证书,还应该验证该证书只能供其颁发对象的用户使用(即不能使用颁发给Alice的证书来在Bob的账户上进行身份验证)。此外,应该检查证书是否未过期且未被吊销。

相关测试用例

修复建议

确保做到以下几点:

  • 为应用程序上所有相关的账户和功能实现多因素身份验证(MFA)。
  • 所支持的MFA方法适合该应用程序。
  • 用于实现MFA的机制得到了适当的保护,能够抵御暴力破解攻击。
  • 对所有与MFA相关的活动进行适当的审计和日志记录。

有关更多建议,请参阅OWASP多因素身份验证备忘单

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值