1. 漏洞简介
1.1 什么是业务逻辑漏洞
业务逻辑漏洞是应用程序设计和实现中的缺陷,允许攻击者引发意外行为。这可能使攻击者能够操纵合法功能以实现恶意目标。这些缺陷通常是由于未能预测可能发生的异常应用程序状态,因此无法安全地处理它们。
因为设计和开发团队对用户将如何与应用程序交互做出了有缺陷的假设。这些错误的假设可能导致对用户输入的验证不足。例如,如果开发人员假定用户将通过 Web 浏览器以独占方式传递数据,则应用程序可能完全依赖弱客户端控件来验证输入。攻击者使用拦截代理很容易绕过这些。
1.2 危害
从根本上说,任何逻辑缺陷的影响都取决于它与哪些功能相关。例如,
- 如果该漏洞存在于身份验证机制中,则可能会对您的整体安全性产生严重影响。攻击者可能会利用此漏洞进行权限提升,或完全绕过身份验证,从而获得对敏感数据和功能的访问权限。这也暴露了其他漏洞利用的更多攻击面。
- 金融交易中有缺陷的逻辑显然会通过被盗资金,欺诈等方式导致企业遭受巨大损失。
还应该注意,即使逻辑缺陷可能不允许攻击者直接受益,它们仍然可能允许恶意方以某种方式损害业务。
2. 业务逻辑漏洞的预防
简而言之,防止业务逻辑漏洞的关键是:
- 确保开发人员和测试人员了解应用程序所服务的域
- 避免对用户行为或应用程序其他部分的行为做出隐式假设
您应该确定您对服务器端状态所做的假设,并实现必要的逻辑来验证是否满足这些假设。这包括在继续之前确保任何输入的值都是合理的。
确保开发人员和测试人员能够完全理解这些假设以及应用程序在不同情况下应该如何反应也很重要。这可以帮助团队尽早发现逻辑缺陷。为了促进这一点,开发团队应尽可能遵守以下最佳实践:
- 为所有事务和工作流维护清晰的设计文档和数据流,并注意在每个阶段所做的任何假设。
- 尽可能清楚地编写代码。如果很难理解应该发生什么,就很难发现任何逻辑缺陷。理想情况下,编写良好的代码不需要文档来理解它。在不可避免的复杂情况下,生成清晰的文档对于确保其他开发人员和测试人员知道正在做出的假设以及预期的行为到底是什么至关重要。
- 请注意对使用每个组件的其他代码的任何引用。想想这些依赖关系的任何副作用,如果恶意方以不寻常的方式操纵它们。
由于许多逻辑缺陷的相对独特性,很容易将它们作为人为错误的一次性错误刷掉并继续前进。但是,正如我们已经证明的那样,这些缺陷通常是构建应用程序的初始阶段不良做法的结果。
分析为什么首先存在逻辑缺陷,以及团队如何遗漏它,可以帮助您发现流程中的弱点。通过进行微小的调整,您可以增加在源头上切断类似缺陷或在开发过程早期发现的可能性。
3. 业务逻辑漏洞例子
3.1 对客户端控件的过度信任
依赖客户端验证阻止用户提供恶意输入。
但是,攻击者可以简单地使用Burp Proxy等工具在浏览器发送数据之后但在数据传递到服务器端逻辑之前对其进行篡改。这有效地使客户端控件变得无用。
在不执行适当的完整性检查和服务器端验证的情况下,从表面上接受数据,可能会使攻击者能够以相对最小的工作量造成各种损害。他们能够实现的确切目标取决于功能以及它对可控数据执行的操作。在正确的上下文中,这种缺陷可能会对与业务相关的功能和网站本身的安全性产生破坏性后果。
3.2 无法处理非常规输入
应用程序逻辑的一个目的是将用户输入限制为符合业务规则的值。
例如,应用程序可能被设计为接受某种数据类型的任意值,但逻辑从业务的角度来看决定了该值是否可接受。许多应用程序将数字限制合并到其逻辑中。这可能包括旨在管理库存、应用预算限制、触发供应链阶段等的限制。
让我们以在线商店的简单示例为例。订购产品时,用户通常会指定要订购的数量。例如,尽管任何整数在理论上都是有效的输入,但业务逻辑可能会阻止用户订购比当前库存更多的单位。
为了实现这样的规则,开发人员需要预测所有可能的场景,并将处理它们的方法合并到应用程序逻辑中。换句话说,他们需要告诉应用程序它是否应该允许给定的输入,以及它应该如何根据各种条件做出反应。如果没有用于处理给定案例的显式逻辑,这可能会导致意外和潜在的可利用行为。
例如,数值数据类型可能接受负值。根据相关功能,业务逻辑允许这样做可能没有意义。但是,如果应用程序未执行足够的服务器端验证并拒绝此输入,则攻击者可能能够传入负值并诱发不需要的行为。
考虑在两个银行账户之间进行资金转账。此功能几乎肯定会在完成转账之前检查发件人是否有足够的资金:
但是,如果逻辑不能充分阻止用户在
amount
参数中提供负值,则攻击者可能会利用这一点绕过余额检查并在“错误”方向上转移资金。如果攻击者向受害者的帐户发送了-1000美元,这可能会导致他们从受害者那里收到1000美元。该逻辑将始终评估 -1000 小于当前余额并批准转移。像这样的简单逻辑缺陷如果发生在正确的功能中,可能会造成毁灭性的。在开发和测试期间,它们也很容易被遗漏,特别是考虑到 Web 界面上的客户端控件可能会阻止此类输入。
审核应用程序时,应使用 Burp Proxy 和 Repeater 等工具尝试提交非常规值。特别是,尝试在合法用户不太可能进入的范围内输入。这包括非常高或非常低的数字输入以及基于文本的字段的异常长的字符串。您甚至可以尝试意外的数据类型。通过观察应用程序的响应,您应该尝试回答以下问题:
- 对数据施加任何限制吗?
- 当您达到这些限制时会发生什么?
- 是否正在对输入执行任何转换或规范化?
这可能会暴露弱输入验证,允许您以不寻常的方式操作应用程序。请记住,如果您在目标网站上发现一个表单无法安全地处理非常规输入,则其他表单可能会遇到相同的问题。
3.3 对用户行为做出有缺陷的假设
最常见的根本原因之一是对用户行为做出有缺陷的假设。这可能会导致开发人员没有考虑违反这些假设的潜在危险场景的广泛问题。
3.3.1 受信任的用户不会始终保持可信赖
应用程序可能看起来是安全的,因为它们实现了看似可靠的措施来强制实施业务规则。不幸的是,一些应用程序犯了一个错误,即假设在最初通过这些严格控制之后,用户可以无限期地信任用户及其数据。这可能导致从那时起对相同控件的执行相对宽松。
如果业务规则和安全措施未在整个应用程序中一致地应用,则可能导致攻击者可能利用的潜在危险漏洞。
3.3.2 用户不会总是提供强制输入
一个误解是,用户总是会为必填字段提供值。浏览器可以阻止普通用户在没有所需输入的情况下提交表单,但正如我们所知,攻击者可以在传输过程中篡改参数。这甚至扩展到完全删除参数。
在同一服务器端脚本中实现多个函数的情况下,这是一个特殊问题。在这种情况下,特定参数的存在与否可能决定执行哪些代码。删除参数值可能允许攻击者访问本应无法触及的代码路径。
解决:
在探测逻辑缺陷时,您应该尝试依次删除每个参数,并观察这对响应的影响。您应确保:
- 一次仅删除一个参数,以确保到达所有相关的代码路径。
- 请尝试删除参数的名称以及值。服务器通常会以不同的方式处理这两种情况。
- 遵循多阶段流程直至完成。有时,在一个步骤中篡改参数会对工作流中的另一个步骤产生影响。
这适用于URL和
POST
参数,但不要忘记检查cookie。这个简单的过程可以揭示一些可能被利用的奇怪应用程序行为。3.3.3 用户不会总是遵循预期的顺序
许多事务依赖于由一系列步骤组成的预定义工作流。Web 界面通常会引导用户完成此过程,并在每次完成当前工作流时将他们带到工作流的下一步。但是,攻击者不一定会遵守此预期顺序。未能考虑到这种可能性可能会导致危险的缺陷,这些缺陷可能相对容易利用。
例如,许多实施双因素身份验证(2FA)的网站要求用户在一个页面上登录,然后在另一个页面上输入验证码。假设用户将始终遵循此过程直到完成,因此,不验证他们是否这样做,可能会允许攻击者完全绕过2FA步骤。
对事件序列做出假设可能会导致各种各样的问题,即使在相同的工作流或功能中也是如此。使用Burp Proxy和Reprover等工具,一旦攻击者看到请求,他们就可以随意重放它,并使用强制浏览以他们想要的任何顺序执行与服务器的任何交互。这允许他们在应用程序处于意外状态时完成不同的操作。
解决:
要识别这些类型的缺陷,您应该使用强制浏览以意外的顺序提交请求。例如,您可以跳过某些步骤、多次访问单个步骤、返回到前面的步骤等。记下如何访问不同的步骤。虽然您通常只向特定 URL 提交
GET
或POST
请求,但有时您可以通过向同一 URL 提交不同的参数集来访问步骤。与所有逻辑缺陷一样,请尝试确定开发人员所做的假设以及攻击面所在的位置。然后,您可以寻找违反这些假设的方法。请注意,这种测试通常会导致异常,因为预期变量具有 null 或未初始化的值。到达处于部分定义或不一致状态的位置也可能导致应用程序发生投诉。在这种情况下,请务必密切注意您遇到的任何错误消息或调试信息。
3.4 特定于域的缺失
在许多情况下,您会遇到特定于业务域或站点用途的逻辑缺陷。
在线商店的折扣功能是寻找逻辑缺陷时的典型攻击面。对于攻击者来说,这可能是一个潜在的金矿,折扣应用方式中存在各种基本逻辑缺陷。
例如,假设一家在线商店为超过 1000 美元的订单提供 10% 的折扣。如果业务逻辑无法检查在应用折扣后订单是否已更改,则这可能容易被滥用。在这种情况下,攻击者可以简单地将商品添加到购物车中,直到他们达到$ 1000阈值,然后在下订单之前删除他们不想要的商品。然后,即使订单不再满足预期的标准,他们也将获得折扣。
解决:
您应特别注意根据用户操作确定的标准调整价格或其他敏感值的任何情况。尝试了解应用程序使用哪些算法进行这些调整,以及在何时进行这些调整。这通常涉及操作应用程序,使其处于应用调整与开发人员预期的原始条件不对应的状态。
要识别这些漏洞,您需要仔细考虑攻击者可能具有的目标,并尝试使用提供的功能找到实现此目的的不同方法。这可能需要一定程度的特定领域知识,以便了解在给定上下文中可能有利的知识。
3.5 提供加密预言机
当用户可控制的输入被加密,然后生成的密文以某种方式提供给用户时,可能会发生危险的情况。这种输入有时被称为“加密预言机”。攻击者可以使用此输入通过正确的算法和非对称密钥对任意数据进行加密。
当应用程序中有其他用户可控制的输入需要使用相同的算法加密数据时,这将变得危险。在这种情况下,攻击者可能会使用加密预言机来生成有效的加密输入,然后将其传递到其他敏感函数。
如果站点上存在另一个提供反向功能的用户可控输入,则此问题可能会更加复杂。这将使攻击者能够解密其他数据以识别预期的结构。这为他们节省了创建恶意数据所涉及的一些工作,但不一定是成功利用漏洞所必需的。
加密预言机的严重性取决于哪些功能也使用与预言机相同的算法。
4. 具体
4.1 交易
4.1.1 购买
- 修改支付的价格
- 修改支付的状态
- 修改购买数量为负数
- 修改金额为负数
- 重放成功的请求
- 并发数据库锁处理不当
4.1.2 业务风控
- 刷优惠券
- 套现
4.2 账户
4.2.1 注册
- 覆盖注册
- 尝试重复用户名
- 注册遍历猜解已有账号
4.2.2 密码
- 密码未使用哈希算法保存
- 没有验证用户设置密码的强度
4.2.3 邮箱用户名
- 前后空格
- 大小写变换
4.2.4 Cookie
- 包含敏感信息
- 未验证合法性可伪造
4.2.5 手机号用户名
- 前后空格
- +86
4.2.6 登录
- 撞库设置异地登录检查等机制
- 账号劫持
- 恶意尝试帐号密码锁死账户需要设置锁定机制与解锁机制
- 不安全的传输信道
- 登录凭证存储在不安全的位置
4.2.7 找回密码
- 重置任意用户密码
- 密码重置后新密码在返回包中
- Token验证逻辑在前端
- X-Forwarded-Host处理不正确
- 找回密码功能泄露用户敏感信息
4.2.8 修改密码
- 越权修改密码
- 修改密码没有旧密码验证
4.2.9 申诉
- 身份伪造
- 逻辑绕过
4.2.10 更新
- ORM更新操作不当可更新任意字段
- 权限限制不当可以越权修改
4.2.11 信息查询
- 权限限制不当可以越权查询
- 用户信息ID可以猜测导致遍历
4.3 2FA
- 重置密码后自动登录没有2FA
- OAuth登录没有启用2FA
- 2FA可爆破
- 2FA有条件竞争
- 修改返回值绕过
- 激活链接没有启用2FA
- 可通过CSRF禁用2FA
4.4 验证码
- 验证码可重用
- 验证码可预测
- 验证码强度不够
- 验证码无时间限制或者失效时间长
- 验证码无猜测次数限制
- 验证码传递特殊的参数或不传递参数绕过
- 验证码可从返回包中直接获取
- 验证码不刷新或无效
- 验证码数量有限
- 验证码在数据包中返回
- 修改Cookie绕过
- 修改返回包绕过
- 验证码在客户端生成或校验
- 验证码可OCR或使用机器学习识别
- 验证码用于手机短信/邮箱轰炸
4.5 Session
- Session机制
- Session猜测 / 爆破
- Session伪造
- Session泄漏
- Session Fixation
4.6 越权
- 未授权访问静态文件通过特定url来防止被访问
- 水平越权攻击者可以访问与他拥有相同权限的用户的资源权限类型不变,ID改变
- 垂直越权低级别攻击者可以访问高级别用户的资源权限ID不变,类型改变
- 交叉越权权限ID改变,类型改变
4.7 随机数安全
- 使用不安全的随机数发生器
- 使用时间等易猜解的因素作为随机数种子
4.8 其他
- 用户/订单/优惠券等ID生成有规律,可枚举
- 接口无权限、次数限制
- 加密算法实现误用
- 执行顺序
- 敏感信息泄露
参考文章
本文章仅提供学习使用,有任何问题,欢迎您在底部评论区留言,一起交流~
- Author:KoGe
- URL:https://www.shipangshuo.xyz/article/logic-flaws
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts