Skip to content

Business logic vulnerabilities

Justki
Published date:
Edit this post

Business logic vulnerabilities

什么是业务逻辑漏洞?

Business logic vulnerabilities are flaws in the design and implementation of an application that allow an attacker to elicit unintended behavior. This potentially enables attackers to manipulate legitimate functionality to achieve a malicious goal. These flaws are generally the result of failing to anticipate unusual application states that may occur and, consequently, failing to handle them safely. 业务逻辑漏洞是应用程序设计和实现中的缺陷,允许攻击者引发意外行为。这可能使攻击者能够操纵合法功能来实现恶意目标。这些缺陷通常是由于未能预见可能发生的异常应用程序状态而导致的,因此未能安全地处理它们。

[!NOTE]

In this context, the term “business logic” simply refers to the set of rules that define how the application operates. As these rules aren’t always directly related to a business, the associated vulnerabilities are also known as “application logic vulnerabilities” or simply “logic flaws”. 在这种情况下,术语“业务逻辑”仅指定义应用程序如何运行的一组规则。由于这些规则并不总是与业务直接相关,因此相关的漏洞也称为“应用程序逻辑漏洞”或简称为“逻辑缺陷”。

Logic flaws are often invisible to people who aren’t explicitly looking for them as they typically won’t be exposed by normal use of the application. However, an attacker may be able to exploit behavioral quirks by interacting with the application in ways that developers never intended. 对于没有明确寻找逻辑缺陷的人来说,逻辑缺陷通常是不可见的,因为它们通常不会通过正常使用应用程序而暴露出来。但是,攻击者可能能够通过以开发人员从未想过的方式与应用程序交互来利用行为怪癖。

One of the main purposes of business logic is to enforce the rules and constraints that were defined when designing the application or functionality. Broadly speaking, the business rules dictate how the application should react when a given scenario occurs. This includes preventing users from doing things that will have a negative impact on the business or that simply don’t make sense. 业务逻辑的主要目的之一是强制执行在设计应用程序或功能时定义的规则和约束。从广义上讲,业务规则规定了当给定场景发生时应用程序应如何反应。这包括防止用户做会对业务产生负面影响或根本没有意义的事情。

Flaws in the logic can allow attackers to circumvent these rules. For example, they might be able to complete a transaction without going through the intended purchase workflow. In other cases, broken or non-existent validation of user-supplied data might allow users to make arbitrary changes to transaction-critical values or submit nonsensical input. By passing unexpected values into server-side logic, an attacker can potentially induce the application to do something that it isn’t supposed to. 逻辑缺陷可能使攻击者能够规避这些规则。例如,他们可能无需经过预期的购买工作流程即可完成交易。在其他情况下,用户提供的数据的验证损坏或不存在可能允许用户对事务关键值进行任意更改或提交无意义的输入。通过将意外值传递到服务器端逻辑,攻击者可能会诱使应用程序执行不应该执行的操作。

Logic-based vulnerabilities can be extremely diverse and are often unique to the application and its specific functionality. Identifying them often requires a certain amount of human knowledge, such as an understanding of the business domain or what goals an attacker might have in a given context. This makes them difficult to detect using automated vulnerability scanners. As a result, logic flaws are a great target for bug bounty hunters and manual testers in general. 基于逻辑的漏洞可能极其多样化,并且通常对于应用程序及其特定功能来说是唯一的。识别它们通常需要一定量的人类知识,例如了解业务领域或攻击者在给定上下文中可能有什么目标。这使得使用自动漏洞扫描器很难检测到它们。因此,逻辑缺陷通常是错误赏金猎人和手动测试人员的重要目标。

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

Business logic vulnerabilities often arise because the design and development teams make flawed assumptions about how users will interact with the application. These bad assumptions can lead to inadequate validation of user input. For example, if the developers assume that users will pass data exclusively via a web browser, the application may rely entirely on weak client-side controls to validate input. These are easily bypassed by an attacker using an intercepting proxy. 业务逻辑漏洞经常出现,因为设计和开发团队对用户如何与应用程序交互做出了有缺陷的假设。这些错误的假设可能会导致用户输入的验证不充分。例如,如果开发人员假设用户仅通过 Web 浏览器传递数据,则应用程序可能完全依赖弱客户端控件来验证输入。攻击者使用拦截代理很容易绕过这些。

Ultimately, this means that when an attacker deviates from the expected user behavior, the application fails to take appropriate steps to prevent this and, subsequently, fails to handle the situation safely. 最终,这意味着当攻击者偏离预期的用户行为时,应用程序无法采取适当的步骤来防止这种情况,并且随后无法安全地处理这种情况。

Logic flaws are particularly common in overly complicated systems that even the development team themselves do not fully understand. To avoid logic flaws, developers need to understand the application as a whole. This includes being aware of how different functions can be combined in unexpected ways. Developers working on large code bases may not have an intimate understanding of how all areas of the application work. Someone working on one component could make flawed assumptions about how another component works and, as a result, inadvertently introduce serious logic flaws. If the developers do not explicitly document any assumptions that are being made, it is easy for these kinds of vulnerabilities to creep into an application. 逻辑缺陷在过于复杂的系统中尤其常见,甚至连开发团队自己也不能完全理解。为了避免逻辑缺陷,开发人员需要从整体上理解应用程序。这包括了解如何以意想不到的方式组合不同的功能。使用大型代码库的开发人员可能无法深入了解应用程序的所有区域是如何工作的。研究一个组件的人可能会对另一个组件的工作方式做出有缺陷的假设,从而无意中引入严重的逻辑缺陷。如果开发人员没有明确记录所做的任何假设,则此类漏洞很容易渗透到应用程序中。

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

The impact of business logic vulnerabilities can, at times, be fairly trivial. It is a broad category and the impact is highly variable. However, any unintended behavior can potentially lead to high-severity attacks if an attacker is able to manipulate the application in the right way. For this reason, quirky logic should ideally be fixed even if you can’t work out how to exploit it yourself. There is always a risk that someone else will be able to. 有时,业务逻辑漏洞的影响可能相当微不足道。这是一个广泛的类别,其影响也存在很大差异。但是,如果攻击者能够以正确的方式操纵应用程序,则任何意外行为都可能导致严重程度较高的攻击。因此,即使您自己无法弄清楚如何利用它,理想的情况下也应该修复奇怪的逻辑。总是存在其他人能够做到的风险。

Fundamentally, the impact of any logic flaw depends on what functionality it is related to. If the flaw is in the authentication mechanism, for example, this could have a serious impact on your overall security. Attackers could potentially exploit this for privilege escalation, or to bypass authentication entirely, gaining access to sensitive data and functionality. This also exposes an increased attack surface for other exploits. 从根本上来说,任何逻辑缺陷的影响取决于它所涉及的功能。例如,如果身份验证机制存在缺陷,则可能会对您的整体安全产生严重影响。攻击者可能会利用此漏洞进行权限升级,或者完全绕过身份验证,从而获得对敏感数据和功能的访问权限。这也暴露了其他漏洞的更多攻击面。

Flawed logic in financial transactions can obviously lead to massive losses for the business through stolen funds, fraud, and so on. 金融交易中的逻辑缺陷显然会导致资金被盗、欺诈等导致企业遭受巨大损失。

You should also note that even though logic flaws may not allow an attacker to benefit directly, they could still allow a malicious party to damage the business in some way. 您还应该注意,即使逻辑缺陷可能不允许攻击者直接受益,但它们仍然可能允许恶意方以某种方式损害业务。

业务逻辑漏洞示例

Business logic vulnerabilities are relatively specific to the context in which they occur. However, although individual instances of logic flaws differ hugely, they can share many common themes. In particular, they can be loosely grouped based on the initial mistakes that introduced the vulnerability in the first place. 业务逻辑漏洞相对特定于它们发生的上下文。然而,尽管逻辑缺陷的个别实例差异很大,但它们可以共享许多共同的主题。特别是,可以根据最初引入漏洞的最初错误对它们进行松散的分组。

In this section, we’ll look at examples of some typical mistakes that design and development teams make and show you how they can directly lead to business logic flaws. Whether you’re developing your own applications, or auditing existing ones, you can take the lessons learned from these examples and apply the same critical thinking to other applications that you encounter. 在本节中,我们将查看设计和开发团队所犯的一些典型错误的示例,并向您展示它们如何直接导致业务逻辑缺陷。无论您是开发自己的应用程序,还是审核现有应用程序,您都可以从这些示例中吸取教训,并将相同的批判性思维应用于您遇到的其他应用程序。

过度信任客户端控制

A fundamentally flawed assumption is that users will only interact with the application via the provided web interface. This is especially dangerous because it leads to the further assumption that client-side validation will prevent users from supplying malicious input. However, an attacker can simply use tools such as Burp Proxy to tamper with the data after it has been sent by the browser but before it is passed into the server-side logic. This effectively renders the client-side controls useless. 一个根本上有缺陷的假设是用户只能通过提供的 Web 界面与应用程序交互。这是特别危险的,因为它导致进一步假设客户端验证将阻止用户提供恶意输入。然而,攻击者可以简单地使用 Burp Proxy 等工具在浏览器发送数据后但在将数据传递到服务器端逻辑之前篡改数据。这实际上使客户端控件变得无用。

Accepting data at face value, without performing proper integrity checks and server-side validation, can allow an attacker to do all kinds of damage with relatively minimal effort. Exactly what they are able to achieve is dependent on the functionality and what it is doing with the controllable data. In the right context, this kind of flaw can have devastating consequences for both business-related functionality and the security of the website itself. 仅从表面上接受数据,而不执行适当的完整性检查和服务器端验证,可能会让攻击者以相对最小的努力造成各种损害。他们究竟能够实现什么取决于功能以及它对可控数据的作用。在适当的情况下,这种缺陷可能会对业务相关功能和网站本身的安全造成毁灭性后果。

Lab 1 过度信任客户端控制

Excessive trust in client-side controls

一个好习惯就是,开着BP把所有功能都尝试一遍,然后去检查请求和响应。

在下单的请求中似乎没有漏洞,但

在 添加商品的请求中,

productId=1&redir=PRODUCT&quantity=1&price=133700

可以任意修改价格。

Lab 2 2FA 破坏逻辑

2FA broken logic

先看看登录过程:

输入用户名、密码,重定向到填写邮箱验证码,

POST /login HTTP/2
Cookie: verify=wiener; session=DdROp7QStTaI4gD0GUVQdDknZksNSGaT
username=wiener&password=peter
HTTP/2 302 Found
Location: /login2
Set-Cookie: verify=wiener; HttpOnly
Set-Cookie: session=5QAGWQ6E9NwO9rFapFghr3SQsie4A0O6; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

再 Email Client 中查看验证码,并填写,再次被重定向,

POST /login2 HTTP/2
Cookie: verify=wiener; session=5QAGWQ6E9NwO9rFapFghr3SQsie4A0O6
mfa-code=1911
HTTP/2 302 Found
Location: /my-account?id=wiener
Set-Cookie: session=BkjHbXYIUVhXcsoui0dEFFdetYy7z3VN; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

进入重置邮箱页面,

GET /my-account?id=wiener HTTP/2
Cookie: verify=wiener; session=BkjHbXYIUVhXcsoui0dEFFdetYy7z3VN

/login2 中,我们发现 cookie 中有 verify=wiener,所以我们尝试修改成 carlos,看看 mfa-code 有没有与 verify 绑定。(当然,前面登录我们使用 wiener,你想想,如果没有强绑定,那是不是就意味着我绕过了密码输入的阶段。)

在重发中,去除 session ,仍然可以正常跳转;但是没有 verify 不行,会响应为:Internal Server Error

那么这个时候,我们去掉 session,将 verify 修改为 carlos,然后放到 Intruder 去爆破 mfa-code(因为修改 carlos 后,服务器会向 carlos 的邮箱发送 mfa-code,但是我们并不知道,所以要用 Intruder。)

然后从响应中得到 carlos 的session,就可以成功进入 my-account 了。

无法处理非常规输入

One aim of the application logic is to restrict user input to values that adhere to the business rules. For example, the application may be designed to accept arbitrary values of a certain data type, but the logic determines whether or not this value is acceptable from the perspective of the business. Many applications incorporate numeric limits into their logic. This might include limits designed to manage inventory, apply budgetary restrictions, trigger phases of the supply chain, and so on. 应用程序逻辑的目标之一是将用户输入限制为符合业务规则的值。例如,应用程序可能被设计为接受某种数据类型的任意值,但从业务的角度来看,逻辑确定该值是否可接受。许多应用程序将数字限制纳入其逻辑中。这可能包括旨在管理库存、应用预算限制、触发供应链阶段等的限制。

Let’s take the simple example of an online shop. When ordering products, users typically specify the quantity that they want to order. Although any integer is theoretically a valid input, the business logic might prevent users from ordering more units than are currently in stock, for example. 让我们以网上商店为例。订购产品时,用户通常会指定他们想要订购的数量。例如,虽然理论上任何整数都是有效输入,但业务逻辑可能会阻止用户订购比当前库存更多的单位。

To implement rules like this, developers need to anticipate all possible scenarios and incorporate ways to handle them into the application logic. In other words, they need to tell the application whether it should allow a given input and how it should react based on various conditions. If there is no explicit logic for handling a given case, this can lead to unexpected and potentially exploitable behavior. 为了实现这样的规则,开发人员需要预测所有可能的场景并将处理它们的方法合并到应用程序逻辑中。换句话说,他们需要告诉应用程序是否应该允许给定的输入以及它应该如何根据各种条件做出反应。如果没有明确的逻辑来处理给定的情况,这可能会导致意外且可能被利用的行为。

For example, a numeric data type might accept negative values. Depending on the related functionality, it may not make sense for the business logic to allow this. However, if the application doesn’t perform adequate server-side validation and reject this input, an attacker may be able to pass in a negative value and induce unwanted behavior. 例如,数字数据类型可能接受负值。根据相关功能,业务逻辑允许这样做可能没有意义。但是,如果应用程序未执行足够的服务器端验证并拒绝此输入,则攻击者可能能够传入负值并引发不需要的行为。

Consider a funds transfer between two bank accounts. This functionality will almost certainly check whether the sender has sufficient funds before completing the transfer: 考虑两个银行账户之间的资金转账。此功能几乎肯定会在完成转账之前检查发送者是否有足够的资金:

$transferAmount = $_POST['amount']; 
$currentBalance = $user->getBalance(); 
if ($transferAmount <= $currentBalance) {   
	// Complete the transfer 
} else {    
	// Block the transfer: insufficient funds 
}

But if the logic doesn’t sufficiently prevent users from supplying a negative value in the amount parameter, this could be exploited by an attacker to both bypass the balance check and transfer funds in the “wrong” direction. If the attacker sent -$1000 to the victim’s account, this might result in them receiving $1000 from the victim instead. The logic would always evaluate that -1000 is less than the current balance and approve the transfer. 但是,如果逻辑不能充分阻止用户在 amount 参数中提供负值,则攻击者可能会利用这一点绕过余额检查并向“错误”方向转移资金。如果攻击者向受害者的帐户发送 -$1000,这可能会导致他们从受害者那里收到 1000 美元。逻辑将始终评估 -1000 小于当前余额并批准转账。

Simple logic flaws like this can be devastating if they occur in the right functionality. They are also easy to miss during both development and testing, especially given that such inputs may be blocked by client-side controls on the web interface. 像这样的简单逻辑缺陷如果出现在正确的功能中,可能会造成毁灭性的后果。在开发和测试过程中也很容易错过它们,特别是考虑到此类输入可能会被 Web 界面上的客户端控件阻止。

When auditing an application, you should use tools such as Burp Proxy and Repeater to try submitting unconventional values. In particular, try input in ranges that legitimate users are unlikely to ever enter. This includes exceptionally high or exceptionally low numeric inputs and abnormally long strings for text-based fields. You can even try unexpected data types. By observing the application’s response, you should try and answer the following questions: 在审核应用程序时,您应该使用 Burp Proxy 和 Repeater 等工具来尝试提交非常规值。特别是,尝试在合法用户不太可能输入的范围内进行输入。这包括异常高或异常低的数字输入以及基于文本的字段的异常长字符串。您甚至可以尝试意想不到的数据类型。通过观察应用程序的响应,您应该尝试回答以下问题:

This may expose weak input validation that allows you to manipulate the application in unusual ways. Keep in mind that if you find one form on the target website that fails to safely handle unconventional input, it’s likely that other forms will have the same issues. 这可能会暴露弱输入验证,从而允许您以不寻常的方式操纵应用程序。请记住,如果您发现目标网站上的一种表单无法安全地处理非常规输入,则其他表单可能会出现相同的问题。

Lab 3 高级逻辑漏洞

High-level logic vulnerability

经过尝试,我们会发现,

productId=2&redir=PRODUCT&quantity=1

中的 quantity 可以成功修改为负数,所以,先加入几件 皮夹克,再加入 负数件其他商品,会使得总价降低。

Lab 4 低级逻辑缺陷

Low-level logic flaw

通过修改 quantity 可知只能 <100,通过 Intruder 不断地加数量,发现加到一个超大值,金额突然变成了负数,再继续加大,又开始向 0 趋近。循环往复。

所以我们就通过加数量,再用其他商品凑一下,就可以用100$买下很多皮夹克。

Lab 5 对异常输入的处理不一致

Inconsistent handling of exceptional input

再Email Client 中可以看到我们的唯一邮箱,

Your email address is attacker@exploit-0a150078045d22168043c55b01e10034.exploit-server.net

当我们将 attacker 替换为 非常长的字符串,

attackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattacker@exploit-0a150078045d22168043c55b01e10034.exploit-server.net

会发现邮箱会正常接收验证链接,也可以注册成功。但是登录后会发现邮箱被截断了,只剩下 255 个字符,

attackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattacke

同时在BP中,Site map —> 右键url —>Engagement tools —> Discover content —> Session is not running —> Site map,这是一个扫描接口的功能,在里面我们会发现有一个接口 /admin,查看响应,有这么一个提示,

Admin interface only available if logged in as a DontWannaCry user

再回到注册页面,其实有这么一个提示,

If you work for DontWannaCry, please use your @dontwannacry.com email address

也就是在告诉我们,只用用这个公司的邮箱才能访问 /admin

所以我们构造一个邮箱使得 邮箱刚好在 @dontwannacry.com (17个字符)中的 m 处被截断,

attackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattackerattack@dontwannacry.com.exploit-0a150078045d22168043c55b01e10034.exploit-server.net

注册,登录后多了一个功能点 Admin panel,进去就可以删除用户了。

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

One of the most common root causes of logic vulnerabilities is making flawed assumptions about user behavior. This can lead to a wide range of issues where developers have not considered potentially dangerous scenarios that violate these assumptions. In this section, we’ll provide some cautionary examples of common assumptions that should be avoided and demonstrate how they can lead to dangerous logic flaws. 逻辑漏洞最常见的根本原因之一是对用户行为做出有缺陷的假设。这可能会导致广泛的问题,因为开发人员没有考虑违反这些假设的潜在危险场景。在本节中,我们将提供一些应避免的常见假设的警示示例,并演示它们如何导致危险的逻辑缺陷。

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

Applications may appear to be secure because they implement seemingly robust measures to enforce the business rules. Unfortunately, some applications make the mistake of assuming that, having passed these strict controls initially, the user and their data can be trusted indefinitely. This can result in relatively lax enforcement of the same controls from that point on. 应用程序可能看起来很安全,因为它们实施了看似强大的措施来执行业务规则。不幸的是,一些应用程序错误地认为,在最初通过这些严格的控制后,用户及其数据可以无限期地受到信任。这可能会导致从那时起相同控制措施的执行相对宽松。

If business rules and security measures are not applied consistently throughout the application, this can lead to potentially dangerous loopholes that may be exploited by an attacker. 如果业务规则和安全措施未在整个应用程序中一致应用,则可能会导致潜在的危险漏洞,并可能被攻击者利用。

Lab 5 安全控制不一致

Inconsistent security controls

用唯一邮箱注册后,会发现可以任意修改邮箱,甚至可以修改为其公司邮箱,导致拥有本不属于我的权限 — Admin panel。

然后就可以进行修改了。

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

One misconception is that users will always supply values for mandatory input fields. Browsers may prevent ordinary users from submitting a form without a required input, but as we know, attackers can tamper with parameters in transit. This even extends to removing parameters entirely. 一种误解是用户总是会为必填输入字段提供值。浏览器可能会阻止普通用户在没有所需输入的情况下提交表单,但正如我们所知,攻击者可以篡改传输中的参数。这甚至扩展到完全删除参数。

This is a particular issue in cases where multiple functions are implemented within the same server-side script. In this case, the presence or absence of a particular parameter may determine which code is executed. Removing parameter values may allow an attacker to access code paths that are supposed to be out of reach. 当在同一个服务器端脚本中实现多个函数时,这是一个特殊的问题。在这种情况下,特定参数的存在或不存在可以确定执行哪个代码。删除参数值可能会允许攻击者访问本应无法访问的代码路径。

When probing for logic flaws, you should try removing each parameter in turn and observing what effect this has on the response. You should make sure to: 在探测逻辑缺陷时,您应该尝试依次删除每个参数并观察这对响应有何影响。您应该确保:

This applies to both URL and POST parameters, but don’t forget to check the cookies too. This simple process can reveal some bizarre application behavior that may be exploitable. 这适用于 URL 和 POST 参数,但也不要忘记检查 cookie。这个简单的过程可以揭示一些可能被利用的奇怪的应用程序行为。

Lab 6 双用端点上的弱隔离

Weak isolation on dual-use endpoint

同样扫描接口,发现 /admin,一样有报错,但内容不一样,

Admin interface only available if logged in as an administrator

我们在密码重置页面,看看能不能修改 administrator 的密码。发现需要输入 current password,但真的需要吗?

打开开发者工具,在元素中删除表单中 current password 对应的部分,只输入新密码,发现修改成功。

Lab 7 密码重置破坏逻辑

Password reset broken logic

扫描接口,发现 /forgot-password。发现要在邮箱中接收的链接中修改,所以我们先用 wiener 的账户试试,发现在

GET /forgot-password?temp-forgot-password-token=jqjz4wj0bxljeqy630ewgnq2k34nf9m9 

Cookie: session=Hd2BPhntsBKzEu0T4PEEWuvEN2vX8Ggp

并不会校验 cookie 。那就放包,去输入新密码,再抓包,删除 cookie,修改 username 为 carlos ,

POST /forgot-password?temp-forgot-password-token=jqjz4wj0bxljeqy630ewgnq2k34nf9m9 

temp-forgot-password-token=jqjz4wj0bxljeqy630ewgnq2k34nf9m9&username=carlos&new-password-1=wiener&new-password-2=wiener

修改成功。

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

Many transactions rely on predefined workflows consisting of a sequence of steps. The web interface will typically guide users through this process, taking them to the next step of the workflow each time they complete the current one. However, attackers won’t necessarily adhere to this intended sequence. Failing to account for this possibility can lead to dangerous flaws that may be relatively simple to exploit. 许多事务依赖于由一系列步骤组成的预定义工作流程。 Web 界面通常会引导用户完成此过程,并在每次完成当前步骤时将他们带到工作流程的下一步。然而,攻击者不一定会遵守这个预期的顺序。未能考虑到这种可能性可能会导致危险的缺陷,而这些缺陷可能相对容易被利用。

For example, many websites that implement two-factor authentication (2FA) require users to log in on one page before entering a verification code on a separate page. Assuming that users will always follow this process through to completion and, as a result, not verifying that they do, may allow attackers to bypass the 2FA step entirely. 例如,许多实施双因素身份验证 (2FA) 的网站要求用户先在一个页面上登录,然后再在另一个页面上输入验证码。假设用户始终遵循此过程直至完成,因此,如果不验证他们是否这样做,攻击者可能会完全绕过 2FA 步骤。

Lab 8 2FA 简单旁路

2FA simple bypass

这一关模拟的是,在我知道 carlos 的账户、密码的情况下,我可以不需要邮箱验证码,进入 carlos 的 my-account。

输入用户名、密码后,跳转到输入邮箱验证码,但在这里我们不输入验证码(我们也无从知道),直接修改 URL,将 login2 修改为 my-account ,就实现登录了。

Query 1 是哪里出现了什么逻辑问题呢?

服务器过早创建了登录态

正常逻辑应该是:

输入账号密码

验证正确

进入“待完成 2FA”状态

验证码正确

服务器才真正登录用户

而漏洞站点实际上变成了:

输入账号密码

服务器直接创建 session

只是在前端“要求”继续输入验证码

也就是说:

2FA 只是页面流程的一部分
而不是服务端权限校验的一部分

Making assumptions about the sequence of events can lead to a wide range of issues even within the same workflow or functionality. Using tools like Burp Proxy and Repeater, once an attacker has seen a request, they can replay it at will and use forced browsing to perform any interactions with the server in any order they want. This allows them to complete different actions while the application is in an unexpected state. 即使在相同的工作流程或功能中,对事件顺序做出假设也可能会导致各种各样的问题。使用 Burp Proxy 和 Repeater 等工具,一旦攻击者看到请求,他们就可以随意重放该请求,并使用强制浏览以他们想要的任何顺序与服务器执行任何交互。这允许他们在应用程序处于意外状态时完成不同的操作。

To identify these kinds of flaws, you should use forced browsing to submit requests in an unintended sequence. For example, you might skip certain steps, access a single step more than once, return to earlier steps, and so on. Take note of how different steps are accessed. Although you often just submit a GET or POST request to a specific URL, sometimes you can access steps by submitting different sets of parameters to the same URL. As with all logic flaws, try to identify what assumptions the developers have made and where the attack surface lies. You can then look for ways of violating these assumptions. 要识别此类缺陷,您应该使用强制浏览以非预期的顺序提交请求。例如,您可能会跳过某些步骤、多次访问单个步骤、返回到之前的步骤等等。请注意如何访问不同的步骤。尽管您通常只是向特定 URL 提交 GET 或 POST 请求,但有时您可以通过向同一 URL 提交不同的参数集来访问步骤。与所有逻辑缺陷一样,尝试确定开发人员做出了哪些假设以及攻击面位于何处。然后您可以寻找违反这些假设的方法。

Note that this kind of testing will often cause exceptions because expected variables have null or uninitialized values. Arriving at a location in a partly defined or inconsistent state is also likely to cause the application to complain. In this case, be sure to pay close attention to any error messages or debug information that you encounter. These can be a valuable source of information disclosure, which can help you fine-tune your attack and understand key details about the back-end behavior. 请注意,这种测试通常会导致异常,因为预期变量具有 null 或未初始化的值。到达处于部分定义或不一致状态的位置也可能导致应用程序抱怨。在这种情况下,请务必密切注意遇到的任何错误消息或调试信息。这些可能是信息泄露的宝贵来源,可以帮助您微调攻击并了解有关后端行为的关键细节。

Lab 9 工作流程验证不足

Insufficient workflow validation

下单后,第一个请求时,

POST /cart/checkout HTTP/2

然后会被重定向到,

GET /cart?err=INSUFFICIENT_FUNDS HTTP/2

这是余额不够的。那如果余额够呢?我们换一个可以买得起的,

GET /cart/order-confirmation?order-confirmed=true HTTP/2

把这个包放到 Repeater,我们再回去买 皮夹克,将 POST /cart/checkout HTTP/2 放到 Repeater ,send; 然后回到 GET /cart/order-confirmation?order-confirmed=true HTTP/2,send,购买成功。

想到这样,主要是 GET /cart/order-confirmation?order-confirmed=true HTTP/2 只有session,没有其他用于绑定某一商品的令牌,所以就用来试试。

准确的解释一下吧:

服务器只验证了 /cart/checkout,有没有余额。

但是,后续真正“确认订单”的接口 GET /cart/order-confirmation?order-confirmed=true

没有再次验证:

服务器居然只看 参数是 true 或者 session 存在 就认为订单已完成,

没有验证 这个订单是否真的支付成功。

真正确认订单时 GET /cart/order-confirmation?order-confirmed=true,于是,攻击者可以 伪造流程状态,直接进入 “已支付”状态。

Lab 10 通过有缺陷的状态机绕过身份验证

Authentication bypass via flawed state machine

这题的意思是,登陆的时候就默认给了一个角色,给的还时 administrator ,然后再进行角色选择,所以在这个时候 丢包,并回到home页面我的角色就是 administrator。

特定领域的缺陷

In many cases, you will encounter logic flaws that are specific to the business domain or the purpose of the site. 在许多情况下,您会遇到特定于业务领域或站点用途的逻辑缺陷。

The discounting functionality of online shops is a classic attack surface when hunting for logic flaws. This can be a potential gold mine for an attacker, with all kinds of basic logic flaws occurring in the way discounts are applied. 在线商店的折扣功能是寻找逻辑缺陷时的典型攻击面。对于攻击者来说,这可能是一个潜在的金矿,在应用折扣的方式中会出现各种基本逻辑缺陷。

For example, consider an online shop that offers a 10% discount on orders over $1000. This could be vulnerable to abuse if the business logic fails to check whether the order was changed after the discount is applied. In this case, an attacker could simply add items to their cart until they hit the $1000 threshold, then remove the items they don’t want before placing the order. They would then receive the discount on their order even though it no longer satisfies the intended criteria. 例如,假设一家在线商店对超过 1000 美元的订单提供 10% 的折扣。如果业务逻辑无法检查应用折扣后订单是否发生更改,则这可能容易被滥用。在这种情况下,攻击者可以简单地将商品添加到购物车,直到达到 1000 美元阈值,然后在下订单之前删除他们不需要的商品。然后,即使订单不再满足预期标准,他们也会收到订单折扣。

You should pay particular attention to any situation where prices or other sensitive values are adjusted based on criteria determined by user actions. Try to understand what algorithms the application uses to make these adjustments and at what point these adjustments are made. This often involves manipulating the application so that it is in a state where the applied adjustments do not correspond to the original criteria intended by the developers. 您应特别注意根据用户操作确定的标准调整价格或其他敏感值的任何情况。尝试了解应用程序使用哪些算法来进行这些调整以及在什么时候进行这些调整。这通常涉及操纵应用程序,使其处于所应用的调整不符合开发人员预期的原始标准的状态。

To identify these vulnerabilities, you need to think carefully about what objectives an attacker might have and try to find different ways of achieving this using the provided functionality. This may require a certain level of domain-specific knowledge in order to understand what might be advantageous in a given context. To use a simple example, you need to understand social media to understand the benefits of forcing a large number of users to follow you. 要识别这些漏洞,您需要仔细考虑攻击者可能有什么目标,并尝试使用提供的功能找到实现此目的的不同方法。这可能需要一定水平的特定领域知识,以便理解在给定上下文中什么可能是有利的。举个简单的例子,你需要了解社交媒体,才能了解强迫大量用户关注你的好处。

Without this knowledge of the domain, you may dismiss dangerous behavior because you simply aren’t aware of its potential knock-on effects. Likewise, you may struggle to join the dots and notice how two functions can be combined in a harmful way. For simplicity, the examples used in this topic are specific to a domain that all users will already be familiar with, namely an online shop. However, whether you’re bug bounty hunting, pentesting, or even just a developer trying to write more secure code, you may at some point encounter applications from less familiar domains. In this case, you should read as much documentation as possible and, where available, talk to subject-matter experts from the domain to get their insight. This may sound like a lot of work, but the more obscure the domain is, the more likely other testers will have missed plenty of bugs. 如果不了解该领域,您可能会忽略危险行为,因为您根本不知道其潜在的连锁反应。同样,您可能很难将这些点连接起来,并注意到两个功能如何以有害的方式组合。为简单起见,本主题中使用的示例特定于所有用户都已经熟悉的域,即在线商店。然而,无论您是进行错误赏金狩猎、渗透测试,还是只是尝试编写更安全的代码的开发人员,您都可能在某些时候遇到来自不太熟悉的领域的应用程序。在这种情况下,您应该阅读尽可能多的文档,并在可能的情况下与该领域的主题专家交谈以获取他们的见解。这听起来可能需要大量工作,但领域越模糊,其他测试人员就越有可能错过大量错误。

Lab 11 业务规则执行存在缺陷

Flawed enforcement of business rules

从页面横栏,我们会看到一个优惠码,浏览到底部输入邮箱又可以获得一个优惠码。

优惠码不可以重复使用,但只是不可以同一个连续使用,两张优惠码可以交替使用。

这个 Lab 的逻辑大概率类似于:

if coupon != last_used_coupon:
    apply_discount()

开发者原本想防止:

NEWCUST5
NEWCUST5
NEWCUST5

于是他记录:

用户上一次使用的优惠券

然后做“不能连续重复使用”的判断。

但攻击者变成:

NEWCUST5
SIGNUP30
NEWCUST5
SIGNUP30

由于当前 coupon 永远不等于“上一次 coupon”,校验通过。

Lab 12 无限金钱逻辑缺陷

Infinite money logic flaw

正常逻辑中,系统认为:

买礼品卡 ≈ 充值

理论上:

支付金额 == 礼品卡价值

但开发犯了逻辑错误,他允许:

优惠券作用于礼品卡

这是大问题。

因为礼品卡本身就是“钱”。

同时,SIGNUP30 这个优惠券还存在一个逻辑缺陷:

它没有被正确标记为“已使用”。

所以你可以:

反复:
购买礼品卡
→ 使用 SIGNUP30
→ 打7折
→ 兑换礼品卡
→ 余额增加

提供加密预言机

Dangerous scenarios can occur when user-controllable input is encrypted and the resulting ciphertext is then made available to the user in some way. This kind of input is sometimes known as an “encryption oracle”. An attacker can use this input to encrypt arbitrary data using the correct algorithm and asymmetric key. 当用户可控的输入被加密并且生成的密文然后以某种方式提供给用户时,可能会发生危险的情况。这种输入有时被称为“加密预言”。攻击者可以使用此输入使用正确的算法和非对称密钥加密任意数据。

This becomes dangerous when there are other user-controllable inputs in the application that expect data encrypted with the same algorithm. In this case, an attacker could potentially use the encryption oracle to generate valid, encrypted input and then pass it into other sensitive functions. 当应用程序中有其他用户可控的输入需要使用相同算法加密数据时,这会变得危险。在这种情况下,攻击者可能会使用加密预言机生成有效的加密输入,然后将其传递给其他敏感函数。

This issue can be compounded if there is another user-controllable input on the site that provides the reverse function. This would enable the attacker to decrypt other data to identify the expected structure. This saves them some of the work involved in creating their malicious data but is not necessarily required to craft a successful exploit. 如果站点上存在另一个提供反向功能的用户可控输入,则此问题可能会更加复杂。这将使攻击者能够解密其他数据以识别预期的结构。这节省了他们创建恶意数据所涉及的一些工作,但不一定是成功利用漏洞所必需的。

The severity of an encryption oracle depends on what functionality also uses the same algorithm as the oracle. 加密预言机的严重性取决于哪些功能也使用与预言机相同的算法。

Lab 13 通过加密 Oracle 绕过身份验证

Authentication bypass via encryption oracle

先看看两个请求和响应:

image-20260524152406987

image-20260524152505703

网站把 1 的密文返回给了我们,而且页面会把错误的形式的邮箱,以报错的形式回显在页面上。

那这个报错不就是对密文进行了解码嘛。

所以,第一个请求相当于 加密器,第二个请求相当于 解密器。

我们试着把 stay-logged-in 的值输入,(当然,是作为 notification 的值。)

image-20260524153124266

知道了 stay-logged-in 的组成,所以我们伪造成 administrator:1779607792910

image-20260524154328219

被拼接了

发送到 Decoder ,对 stay-logged-in 的值进行 URL解码 和 Base64解码(AES 只能处理二进制),可以得到二进制数据 Invalid email address:,那就要还原为二进制数据,查看hex,然后把这 23个字节删除,最后编码回去。

image-20260524161010983

发送,

image-20260524154738010

报错:使用填充密码解密时,输入长度必须是16的倍数。

也就是说我们删除的字符数,不能是23,只能是16的倍数。

[!NOTE]

AES规则

每16 bytes 一个 block,只能以 数据块 为单位进行编码,解码。

对于 Invalid email address: administrator:timestamp ,第一个数据块包括 Invalid email a,也就是说,无论我们删除1个还是2个数据块,都无法保证 administrator:timestamp 的完整性,所以要补充一下数据,使得我们能既删除完整数据块,又能保证 administrator:timestamp 的完整性。

多填充9个字符,即 123456789administrator:timestamp

通过 加密器 加密后,发送到 Decoder,删除前两个数据块(32个字符),编码回去。

发送,

image-20260524154024043

修改成功:

image-20260524161658894

篡改cookie,修改登录状态,访问 /admin

image-20260524161641661

进行删除操作,

image-20260524161911892

成功,

image-20260524161930506

电子邮件地址解析器差异

Some websites parse email addresses to extract the domain and determine which organization the email owner belongs to. While this process may initially seem straightforward, it is actually very complex, even for valid RFC-compliant addresses. 一些网站解析电子邮件地址以提取域并确定电子邮件所有者属于哪个组织。虽然这个过程最初看起来很简单,但实际上非常复杂,即使对于有效的 RFC 兼容地址也是如此。

Discrepancies in how email addresses are parsed can undermine this logic. These discrepancies arise when different parts of the application handle email addresses differently. 电子邮件地址解析方式的差异可能会破坏这种逻辑。当应用程序的不同部分以不同方式处理电子邮件地址时,就会出现这些差异。

An attacker can exploit these discrepancies using encoding techniques to disguise parts of the email address. This enables the attacker to create email addresses that pass initial validation checks but are interpreted differently by the server’s parsing logic. 攻击者可以利用这些差异,使用编码技术来伪装部分电子邮件地址。这使得攻击者能够创建通过初始验证检查但由服务器的解析逻辑进行不同解释的电子邮件地址。

The main impact of email address parser discrepancies is unauthorized access. Attackers can register accounts using seemingly valid email addresses from restricted domains. This enables them to gain access to sensitive areas of the application, such as admin panels or restricted user functions. 电子邮件地址解析器差异的主要影响是未经授权的访问。攻击者可以使用来自受限制域的看似有效的电子邮件地址来注册帐户。这使他们能够访问应用程序的敏感区域,例如管理面板或受限的用户功能。

分割电子邮件原子:利用解析器绕过访问控制


Splitting the email atom: exploiting parsers to bypass access controls


Encoded-word 编码字

The more I started to look, the more the email RFC’s wanted to give. I had assumed before this research that emails were generally alphanumeric with dots in the local-part. I never imagined that a whole complex encoding system existed that allowed you to perform layers of encoding. Yet this is what I discovered. Scouring the RFC’s I noticed rfc2047 and encoded-word, this encoding system allows you to represent characters using hex and base64. 我越看,RFC 想要提供的电子邮件就越多。在这项研究之前,我曾假设电子邮件通常是字母数字,本地部分带有点。我从未想象过存在一个完整的复杂编码系统,允许您执行多层编码。但这就是我发现的。在搜索 RFC 时,我注意到了 rfc2047 和编码字,该编码系统允许您使用十六进制和 base64 表示字符。

If we use an encoded email as an example illustration: 如果我们使用编码的电子邮件作为示例说明:

image-20260524165738007

The ”=?” indicates the start of an encoded-word, then you specify the charset in this case UTF-8. Then the question mark separates the next command which is “q” which signifies “Q-Encoding” after that there’s another question mark that states the end of the encoding format and the beginning of the encoded data. Q-Encoding is simply hex with an equal prefix. In this example I use =41=42=43 which is an uppercase “ABC”. Finally, ?= indicates the end of the encoding. When parsed by an email library the email destination would be ABCUSER@psres.net! “=?”指示编码字的开始,然后在本例中指定字符集 UTF-8。然后问号分隔下一个命令,即“q”,表示“Q-Encoding”,之后还有另一个问号,表示编码格式的结束和编码数据的开始。 Q-Encoding 只是具有相同前缀的十六进制。在此示例中,我使用=41=42=43,它是大写“ABC”。最后,?=表示编码结束。当由电子邮件库解析时,电子邮件目的地将是 ABCUSER@psres.net

Armed with this information I started to look for real systems that parsed emails using this encoding. To help with this I came up with two probes that worked on most sites that had this behaviour: 有了这些信息,我开始寻找使用这种编码解析电子邮件的真实系统。为了帮助解决这个问题,我想出了两个适用于大多数具有此行为的网站的探测器:

image-20260524165750362

Initially I was using the charset “x” to reduce the size of the probe, however some systems reject unknown charsets and would fail. It’s best to use these two probes as I’ve found them to be the most common allowed charsets after testing lots of sites. Use the Collaborator to generate a payload and replace “collab” above with the generated one. Then if you get an SMTP interaction with the email in the RCPT TO command of the SMTP conversation: 最初,我使用字符集“x”来减小探测器的大小,但是有些系统拒绝未知的字符集并且会失败。最好使用这两个探针,因为在测试了大量站点后我发现它们是最常见的允许字符集。使用 Collaborator 生成有效负载并将上面的“collab”替换为生成的有效负载。然后,如果您在 SMTP 会话的 RCPT TO 命令中获得与电子邮件的 SMTP 交互:

abccollab@psres.net

This then proves the email parser is decoding the email with “encoded word”. 这证明电子邮件解析器正在使用“编码字”对电子邮件进行解码。

I found a bunch of sites with this behaviour and they all had one thing in common. Ruby. It appeared they all used the same Ruby Gem called “Mail” which has over 508 million downloads. I started to look at the source and I found that the library was decoding UTF-7! In my test bed I tried to reproduce this: 我发现了很多有这种行为的网站,它们都有一个共同点。红宝石。看来他们都使用了同一个 Ruby Gem,名为“Mail”,下载量超过 5.08 亿次。我开始查看源代码,发现该库正在解码 UTF-7!在我的测试台上,我尝试重现这一点:

image-20260524165804336

This is insane! Emails can have UTF-7 now! Then an idea popped into my head: if there is Q-Encoding and charsets, can you have both? The surprising answer to this question is a resounding yes. You can blend UTF-7 with Q-Encoding! 这太疯狂了!电子邮件现在可以使用 UTF-7 了!然后一个想法突然出现在我的脑海中:如果有 Q-Encoding 和字符集,你能同时拥有吗?这个问题令人惊讶的答案是肯定的。您可以将 UTF-7 与 Q-Encoding 混合!

image-20260524165816753

After that I started to play with base64 encoding because of course “encoded-word” supports that in emails! You simply use “b” instead of “q” in the encoding type and you can use it. 之后我开始使用 Base64 编码,因为“encoded-word”当然支持电子邮件中的编码!您只需在编码类型中使用“b”而不是“q”即可使用它。

image-20260524165826301

The preceding example uses base64 encoded string “foobar” which gets decoded by the parser. I know what you are thinking or maybe it’s just me but yes you can use UTF-7 and base64 encoded data: 前面的示例使用 base64 编码的字符串“foobar”,该字符串由解析器解码。我知道你在想什么,或者也许只是我的想法,但是你可以使用 UTF-7 和 base64 编码数据:

image-20260524165838934

In this example there is a base64 encoded address with a UTF-7 charset. First the email parser will decode the base64. Then the email parser will decode the UTF-7 charset. Finally the email will be decoded to foobar@psres.net. At this point you might have a few doubts about following the RFC to the letter. Especially when I tell you this works in the domain part too when I tested the Mail library. Note I’m using alphanumeric values here but you can of course encode any special characters too. 在此示例中,有一个采用 UTF-7 字符集的 Base64 编码地址。首先,电子邮件解析器将解码 Base64。然后电子邮件解析器将解码 UTF-7 字符集。最后,电子邮件将被解码为 foobar@psres.net。此时,您可能对严格遵循 RFC 有一些疑问。特别是当我告诉你当我测试邮件库时这也适用于域部分。请注意,我在这里使用字母数字值,但您当然也可以对任何特殊字符进行编码。

Lab 14 使用电子邮件地址解析差异绕过访问控制

Bypassing access controls using email address parsing discrepancies

注册邮箱为:

=?utf-7?q?attacker&AEA-exploit-0a74002804e5f290a4cd6cfe011d00a5.exploit-server.net&ACA-?=@ginandjuice.shop

具体构造方式参考上方材料。

如何防止业务逻辑漏洞

In short, the keys to preventing business logic vulnerabilities are to: 简而言之,防止业务逻辑漏洞的关键是:

You should identify what assumptions you have made about the server-side state and implement the necessary logic to verify that these assumptions are met. This includes making sure that the value of any input is sensible before proceeding. 您应该确定对服务器端状态所做的假设,并实现必要的逻辑来验证这些假设是否得到满足。这包括在继续之前确保任何输入的值都是合理的。

It is also important to make sure that both developers and testers are able to fully understand these assumptions and how the application is supposed to react in different scenarios. This can help the team to spot logic flaws as early as possible. To facilitate this, the development team should adhere to the following best practices wherever possible: 确保开发人员和测试人员能够完全理解这些假设以及应用程序在不同场景中应如何反应也很重要。这可以帮助团队尽早发现逻辑缺陷。为了促进这一点,开发团队应尽可能遵循以下最佳实践:

Due to the relatively unique nature of many logic flaws, it is easy to brush them off as a one-time mistake due to human error and move on. However, as we’ve demonstrated, these flaws are often the result of bad practices in the initial phases of building the application. Analyzing why a logic flaw existed in the first place, and how it was missed by the team, can help you to spot weaknesses in your processes. By making minor adjustments, you can increase the likelihood that similar flaws will be cut off at the source or caught earlier in the development process. 由于许多逻辑缺陷的相对独特性,很容易将它们视为人为错误造成的一次性错误并继续前进。然而,正如我们所证明的,这些缺陷通常是构建应用程序初始阶段的不良实践造成的。首先分析为什么存在逻辑缺陷,以及团队如何忽略它,可以帮助您发现流程中的弱点。通过进行细微的调整,您可以增加从源头消除类似缺陷或在开发过程的早期发现类似缺陷的可能性。

Next
API testing