Business logic vulnerabilities业务逻辑漏洞

@

什么是业务逻辑漏洞?

业务逻辑漏洞是应用程序设计和实现中的缺陷,允许攻击者引发意外行为。这可能使攻击者能够操纵合法功能以实现恶意目标。这些缺陷通常是由于未能预测可能发生的异常应用程序状态,因此未能安全处理它们

注意
在此上下文中,术语“业务逻辑”仅指定义应用程序如何运行的一组规则。由于这些规则并不总是与业务直接相关,因此相关漏洞也称为“应用程序逻辑漏洞”或简称为“逻辑缺陷”。

逻辑缺陷对于没有明确寻找它们的人来说通常是不可见的,因为它们通常不会通过应用程序的正常使用而暴露出来。但是,攻击者可能能够通过以开发人员从未想过的方式与应用程序交互来利用行为怪癖

业务逻辑的主要目的之一是强制执行在设计应用程序或功能时定义的规则和约束。从广义上讲,业务规则规定了应用程序在给定场景发生时应如何反应。这包括阻止用户做会对业务产生负面影响或根本没有意义的事情。

逻辑上的缺陷可以让攻击者绕过这些规则。例如,他们可能无需经过预期的购买工作流程即可完成交易。在其他情况下,用户提供的数据的验证损坏或不存在可能允许用户对事务关键值进行任意更改或提交无意义的输入。通过将意外值传递到服务器端逻辑,攻击者可能会诱使应用程序执行不应该执行的操作

基于逻辑的漏洞可能非常多样化,并且通常是应用程序及其特定功能所独有的。识别它们通常需要一定数量的人类知识,例如对业务领域的理解或攻击者在给定上下文中可能具有的目标。这使得使用自动漏洞扫描程序很难检测到它们。因此,逻辑缺陷通常是漏洞赏金猎人和手动测试人员的重要目标。

业务逻辑漏洞是如何产生的?

业务逻辑漏洞经常出现,因为设计和开发团队对用户将如何与应用程序交互做出有缺陷的假设。这些错误的假设可能导致对用户输入的验证不充分。例如,如果开发人员假设用户将专门通过 Web 浏览器传递数据,则应用程序可能完全依赖弱客户端控件来验证输入。这些很容易被攻击者使用拦截代理绕过。

最终,这意味着当攻击者偏离预期的用户行为时,应用程序无法采取适当的步骤来防止这种情况发生,从而无法安全地处理这种情况。

逻辑缺陷在过于复杂的系统中尤为常见,甚至开发团队自己也无法完全理解。为了避免逻辑缺陷,开发人员需要从整体上理解应用程序。这包括了解如何以意想不到的方式组合不同的功能。处理大型代码库的开发人员可能无法深入了解应用程序的所有领域是如何工作的。处理一个组件的人可能会对另一个组件的工作方式做出有缺陷的假设,从而在不经意间引入严重的逻辑缺陷。如果开发人员没有明确记录正在做出的任何假设,这些类型的漏洞很容易蔓延到应用程序中。

业务逻辑漏洞有什么影响?

有时,业务逻辑漏洞的影响可能相当微不足道。这是一个广泛的类别,影响是高度可变的。但是,如果攻击者能够以正确的方式操纵应用程序,则任何意外行为都可能导致高严重性攻击。出于这个原因,即使您自己无法弄清楚如何利用它,理想情况下也应该修复古怪的逻辑。总是有其他人能够做到的风险。

从根本上说,任何逻辑缺陷的影响取决于它所关联的功能。例如,如果该缺陷存在于身份验证机制中,则可能会对您的整体安全产生严重影响。攻击者可能会利用此漏洞进行权限提升,或完全绕过身份验证,从而获得对敏感数据和功能的访问权限。这也暴露了其他漏洞的攻击面增加。

金融交易中存在缺陷的逻辑显然会通过资金被盗、欺诈等导致企业遭受巨大损失。

您还应该注意,即使逻辑缺陷可能不允许攻击者直接受益,它们仍然可能允许恶意方以某种方式破坏业务。

业务逻辑漏洞示例

业务逻辑漏洞相对特定于它们发生的上下文。然而,尽管逻辑缺陷的个别实例差异很大,但它们可以共享许多共同的主题。特别是,可以根据最初引入漏洞的初始错误对它们进行松散的分组。

在本节中,我们将查看设计和开发团队所犯的一些典型错误的示例,并向您展示它们如何直接导致业务逻辑缺陷。无论您是在开发自己的应用程序,还是审核现有的应用程序,您都可以从这些示例中吸取经验教训,并将相同的批判性思维应用于您遇到的其他应用程序。

逻辑缺陷的例子包括:

  • 对客户端控制过度信任
  • 无法处理非常规输入
  • 对用户行为做出有缺陷的假设
  • 特定领域的缺陷
  • 提供加密预言机

对客户端控制的过度信任

一个根本有缺陷的假设是,用户只会通过提供的 Web 界面与应用程序交互。这尤其危险,因为它导致进一步假设客户端验证将阻止用户提供恶意输入。然而,攻击者可以简单地使用诸如 Burp Proxy 之类的工具来篡改浏览器发送的数据,但在数据传递到服务器端逻辑之前。这有效地使客户端控件无用。

接受表面价值的数据,而不执行适当的完整性检查和服务器端验证,可以让攻击者以相对最小的努力进行各种破坏。他们究竟能够实现什么取决于功能以及它对可控数据的作用。在正确的上下文中,这种缺陷会对与业务相关的功能和网站本身的安全性产生毁灭性的后果。
靶场链接:
https://www.cnblogs.com/Zeker62/p/15166703.html
https://blog.csdn.net/ZripenYe/article/details/119802547

对用户行为做出有缺陷的假设

逻辑漏洞 最常见的根本原因之一是对用户行为做出有缺陷的假设。这可能会导致广泛的问题,其中开发人员没有考虑违反这些假设的潜在危险场景。在本节中,我们将提供一些应避免的常见假设的警示示例,并演示它们如何导致危险的逻辑缺陷。

受信任的用户并不总是值得信赖的

应用程序可能看起来是安全的,因为它们实施了看似强大的措施来执行业务规则。不幸的是,一些应用程序错误地认为,最初通过这些严格的控制后,用户及其数据可以无限期地信任。从那时起,这可能导致相同控制措施的执行相对宽松。

如果业务规则和安全措施在整个应用程序中的应用不一致,这可能会导致潜在的危险漏洞,可能会被攻击者利用。

用户不会总是提供强制输入

一种误解是用户将始终为必填输入字段提供值。浏览器可能会阻止普通用户在没有必需输入的情况下提交表单,但正如我们所知,攻击者可以篡改传输中的参数。这甚至扩展到完全删除参数。

在同一个服务器端脚本中实现多个功能的情况下,这是一个特殊问题。在这种情况下,特定参数的存在与否可以决定执行哪个代码。删除参数值可能允许攻击者访问本应无法访问的代码路径。

在探查逻辑缺陷时,您应该尝试依次删除每个参数并观察这对响应有什么影响。您应该确保:

一次只删除一个参数以确保到达所有相关的代码路径。
尝试删除参数的名称以及值。服务器通常会以不同的方式处理这两种情况。
遵循多阶段流程直至完成。有时,在一个步骤中篡改参数会对工作流程中的另一个步骤产生影响。
这适用于 URL 和POST参数,但也不要忘记检查 cookie。这个简单的过程可以揭示一些可能被利用的奇怪的应用程序行为。

用户不会总是遵循预期的顺序

许多交易依赖于由一系列步骤组成的预定义工作流程。Web 界面通常会引导用户完成此过程,并在他们每次完成当前工作时将他们带到工作流的下一步。然而,攻击者不一定会遵守这个预期的顺序。不考虑这种可能性可能会导致危险的缺陷,而这些缺陷可能相对容易利用。

例如,许多实施双因素身份验证 (2FA) 的网站要求用户先在一个页面上登录,然后再在单独的页面上输入验证码。假设用户将始终遵循此过程直到完成,因此,如果不验证他们是否这样做,则可能允许攻击者完全绕过 2FA 步骤。

即使在相同的工作流程或功能中,对事件的顺序进行假设也会导致范围广泛的问题。使用 Burp Proxy 和 Repeater 等工具,一旦攻击者看到一个请求,他们就可以随意重放它,并使用强制浏览以他们想要的任何顺序与服务器进行任何交互。这允许他们在应用程序处于意外状态时完成不同的操作。

要识别这些类型的缺陷,您应该使用强制浏览以非预期的顺序提交请求。例如,您可能会跳过某些步骤、多次访问单个步骤、返回到先前的步骤等。请注意如何访问不同的步骤。尽管您通常只向特定 URL提交一个GET或POST请求,但有时您可以通过向同一 URL 提交不同的参数集来访问步骤。与所有逻辑缺陷一样,尝试确定开发人员所做的假设以及攻击面所在。然后,您可以寻找违反这些假设的方法。

请注意,这种测试通常会导致异常,因为预期变量具有空值或未初始化的值。到达处于部分定义或不一致状态的位置也可能导致应用程序抱怨。在这种情况下,请务必密切注意您遇到的任何错误消息或调试信息。这些可以成为信息披露的宝贵来源,可以帮助您微调攻击并了解有关后端行为的关键细节。

特定领域的缺陷

在许多情况下,您会遇到特定于业务领域或站点目的的逻辑缺陷。

在寻找逻辑缺陷时,在线商店的折扣功能是一个典型的攻击面。这对于攻击者来说可能是一个潜在的金矿,在应用折扣的方式中会出现各种基本的逻辑缺陷。

例如,假设一家在线商店为超过 1000 美元的订单提供 10% 的折扣。如果在应用折扣后业务逻辑未能检查订单是否已更改,则这可能容易被滥用。在这种情况下,攻击者可以简单地将商品添加到他们的购物车,直到他们达到 1000 美元的门槛,然后在下订单之前删除他们不想要的商品。即使订单不再满足预期标准,他们也会收到折扣。

您应特别注意根据用户操作确定的标准调整价格或其他敏感值的任何情况。尝试了解应用程序使用什么算法来进行这些调整,以及在什么时候进行这些调整。这通常涉及操纵应用程序,使其处于应用调整不符合开发人员预期的原始标准的状态。

要识别这些漏洞,您需要仔细考虑攻击者可能具有的目标,并尝试使用提供的功能找到实现此目标的不同方法。这可能需要一定程度的特定领域知识,以便了解在给定上下文中什么可能是有利的。举个简单的例子,你需要了解社交媒体,才能理解强迫大量用户关注你的好处。

如果不了解该领域,您可能会忽视危险行为,因为您根本没有意识到其潜在的连锁反应。同样,您可能很难将这些点连在一起,并注意到两个功能是如何以有害的方式组合在一起的。为简单起见,本主题中使用的示例特定于所有用户都已经熟悉的域,即在线商店。但是,无论您是赏金猎人还是渗透测试,甚至只是试图编写更安全代码的开发人员,您可能会在某个时候遇到来自不太熟悉的领域的应用程序。在这种情况下,您应该阅读尽可能多的文档,并在可能的情况下与该领域的主题专家交谈以获取他们的见解。这听起来像是很多工作,但域越模糊,其他测试人员就越有可能遗漏大量错误。

提供加密预言机

当用户可控的输入被加密并且生成的密文以某种方式提供给用户时,可能会发生危险的情况。这种输入有时被称为“加密预言机”。攻击者可以使用此输入使用正确的算法和非对称密钥来加密任意数据。

当应用程序中有其他用户可控的输入需要使用相同算法加密的数据时,这会变得很危险。在这种情况下,攻击者可能会使用加密预言机生成有效的加密输入,然后将其传递给其他敏感功能。

如果站点上有另一个用户可控制的输入提供反向功能,则此问题可能会更加复杂。这将使攻击者能够解密其他数据以识别预期结构。这为他们节省了创建恶意数据所涉及的一些工作,但不一定是成功利用的必要条件。

加密预言机的严重性取决于哪些功能也使用与预言机相同的算法。

无法处理非常规输入

应用程序逻辑的目标之一是将用户输入限制为符合业务规则的值。例如,应用程序可能被设计为接受某种数据类型的任意值,但从业务的角度来看,该逻辑决定了该值是否可接受。许多应用程序将数字限制纳入其逻辑。这可能包括旨在管理库存、应用预算限制、触发供应链阶段等的限制。

让我们以网上商店的简单例子为例。订购产品时,用户通常会指定他们想要订购的数量。例如,尽管任何整数理论上都是有效的输入,但业务逻辑可能会阻止用户订购比当前库存更多的单位。

为了实现这样的规则,开发人员需要预测所有可能的场景,并将处理它们的方法融入到应用程序逻辑中。换句话说,他们需要告诉应用程序它是否应该允许给定的输入以及它应该如何根据各种条件做出反应。如果没有用于处理给定案例的明确逻辑,这可能会导致意外和潜在的可利用行为。

例如,数字数据类型可能接受负值。根据相关的功能,业务逻辑允许这样做可能没有意义。但是,如果应用程序未执行足够的服务器端验证并拒绝此输入,则攻击者可能能够传递负值并引发不需要的行为。

考虑两个银行账户之间的资金转账。此功能几乎肯定会在完成转账之前检查发件人是否有足够的资金:

$transferAmount = $_POST['amount'];
$currentBalance = $user->getBalance();

if ($transferAmount <= $currentBalance) {
    // Complete the transfer
} else {
    // Block the transfer: insufficient funds
}

但是,如果该逻辑不能充分阻止用户在amount参数中提供负值,则攻击者可能会利用这一点绕过余额检查并以“错误”的方向转移资金。如果攻击者向受害者的帐户发送 -$1000,这可能会导致他们从受害者那里收到 1000 美元。该逻辑将始终评估 -1000 小于当前余额并批准转移。

如果出现在正确的功能中,像这样的简单逻辑缺陷可能是毁灭性的。它们在开发和测试过程中也很容易错过,特别是考虑到此类输入可能被 Web 界面上的客户端控件阻止。

在审核应用程序时,您应该使用 Burp Proxy 和 Repeater 等工具尝试提交非常规值。特别是,尝试在合法用户不太可能输入的范围内输入。这包括基于文本字段的异常高或异常低的数字输入和异常长的字符串。您甚至可以尝试意外的数据类型。通过观察应用程序的响应,您应该尝试回答以下问题:

  • 是否对数据施加了任何限制?
  • 当你达到这些限制时会发生什么?
  • 是否对您的输入执行任何转换或规范化?

这可能会暴露弱输入验证,允许您以不寻常的方式操作应用程序。请记住,如果您在目标网站上发现一种无法安全处理非常规输入的表单,则其他表单很可能会遇到同样的问题。
靶场链接:

如何防范业务逻辑漏洞

总之,防止业务逻辑漏洞的关键是:

  • 确保开发人员和测试人员了解应用程序服务的领域
  • 避免对用户行为或应用程序其他部分的行为做出隐含的假设

您应该确定您对服务器端状态做出了哪些假设,并实施必要的逻辑来验证这些假设是否得到满足。这包括在继续之前确保任何输入的值是合理的。

确保开发人员和测试人员都能够完全理解这些假设以及应用程序在不同场景中应该如何反应也很重要。这可以帮助团队尽早发现逻辑缺陷。为促进这一点,开发团队应尽可能遵守以下最佳实践:

  • 为所有事务和工作流维护清晰的设计文档和数据流,注意在每个阶段所做的任何假设。
  • 尽可能清楚地编写代码。如果很难理解应该发生什么,就很难发现任何逻辑缺陷。理想情况下,编写良好的代码不需要文档来理解它。在不可避免的复杂情况下,制作清晰的文档对于确保其他开发人员和测试人员知道正在做出什么假设以及确切的预期行为是至关重要的。
  • 请注意对使用每个组件的其他代码的任何引用。如果恶意方以不寻常的方式操纵它们,请考虑这些依赖项的任何副作用。

由于许多逻辑缺陷的相对独特性,很容易将它们作为人为错误造成的一次性错误清除并继续前进。然而,正如我们已经证明的,这些缺陷通常是在构建应用程序的初始阶段的不良做法的结果。分析为什么首先存在逻辑缺陷,以及团队如何忽略它,可以帮助您发现流程中的弱点。通过进行细微的调整,您可以增加在源头切断或在开发过程的早期发现类似缺陷的可能性。

posted @ 2021-08-20 20:47  Zeker62  阅读(222)  评论(0编辑  收藏  举报