- The Guide to Finding and Reporting Web Vulnerabilities
- About the Author
- About the Tech Reviewer
- Foreword
- Introduction
- Who This Book Is For
- What Is In This Book
- Happy Hacking!
- 1 Picking a Bug Bounty Program
- 2 Sustaining Your Success
- 3 How the Internet Works
- 4 Environmental Setup and Traffic Interception
- 5 Web Hacking Reconnaissance
- 6 Cross-Site Scripting
- 7 Open Redirects
- 8 Clickjacking
- 9 Cross-Site Request Forgery
- 10 Insecure Direct Object References
- 11 SQL Injection
- 12 Race Conditions
- 13 Server-Side Request Forgery
- 14 Insecure Deserialization
- 15 XML External Entity
- 16 Template Injection
- 17 Application Logic Errors and Broken Access Control
- 18 Remote Code Execution
- 19 Same-Origin Policy Vulnerabilities
- 20 Single-Sign-On Security Issues
- 21 Information Disclosure
- 22 Conducting Code Reviews
- 23 Hacking Android Apps
- 24 API Hacking
- 25 Automatic Vulnerability Discovery Using Fuzzers
Bypassing IDOR Protection
IDORs aren’t always as simple as switching out a numeric ID. As applications become more functionally complex, the way they reference resources also often becomes more complex. Modern web applications have also begun implementing more protection against IDORs, and many now use more complex ID formats. This means that simple, numeric IDORs are becoming rarer. How do we bypass these obstacles and find IDORs anyway?
IDOR 攻击不仅仅是简单地切换数字 ID 那么简单。随着应用功能的复杂化,它们引用资源的方式也变得更加复杂。现代 Web 应用程序也开始实施更多的防御措施来避免 IDOR 攻击,许多应用程序现在使用更复杂的 ID 格式,因此简单的数字 IDOR 攻击越来越少。我们如何绕过这些障碍并找到 IDOR 攻击呢?
IDORs can manifest in applications in different ways. Here are a few places to pay attention to, beyond your plain old numeric IDs.
IDOR(间接对象引用)可以以不同的方式在应用程序中表现出来。除了普通的数值 ID 之外,以下是需要注意的几个地方。
Encoded IDs and Hashed IDs
First, don’t ignore encoded and hashed IDs. When faced with a seemingly random string, always suspect that it is encoded and try to decode it. You should also learn to recognize the most common encoding schemes, like base64, URL encoding, and base64url. For example, take a look at the IDs of this endpoint:
首先,不要忽略编码和哈希 ID。当面对看似随机的字符串时,应该怀疑它是被编码了,尝试解码它。你也应该学习认识最常见的编码方案,比如 base64,URL 编码和 base64url。例如,看看这个端点的 ID:
- https://example.com/messages?user_id=MTIzNQ
- https://example.com/messages?user_id=MTIzNg
These user_id
s are just the base64url-encoded version of a user’s ID. MTIzNQ
is the base64url-encoded string of 1235 , and MTIzNg
is the encoded version of 1236 . Some applications use encoding schemes that you can easily reverse. In this case, you can simply encode your false IDs by using an online base64url encoder and executing the IDOR.
这些用户 ID 只是用户 ID 的 Base64 URL 编码版本。MTIzNQ 是 1235 的 Base64 URL 编码字符串,而 MTIzNg 是 1236 的编码版本。一些应用程序使用易于反转的编码方案。在这种情况下,您可以使用在线的 Base64 URL 编码器对假 ID 进行编码并执行 IDOR。
You might not be able to tell which encoding scheme the site is using at first. In this case, use the Smart Decode tool ( Figure 10-2 ) in Burp’s decoder, or simply try to decode the string with different schemes (URL encoding, HTML encoding, hex encoding, octal encoding, base64, base64url, and so on) to figure out the encoding scheme in use. Once you gain more experience reading encoded data, you’ll develop an intuition for knowing the encoding scheme.
一开始你可能无法确定网站所使用的编码方案。在这种情况下,请使用 Burp 的 Smart Decode 工具(图 10-2),或者试着用不同的方案(URL 编码、HTML 编码、十六进制编码、八进制编码、base64、base64url 等)来解码字符串,以确定所使用的编码方案。一旦你获得了更多阅读编码数据的经验,就会发展出对编码方案的直觉。
If the application is using a hashed or randomized ID, see if the ID is predictable. Sometimes applications use algorithms that produce insufficient entropy. Entropy is the degree of randomness of the ID. The higher the entropy of a string, the harder it is to guess. Some IDs don’t have sufficient entropy and can be predicted after careful analysis. In this case, try creating a few accounts to analyze how these IDs are created. You might be able to find a pattern that will allow you to predict IDs belonging to other users.
如果应用程序使用哈希或随机 ID,请查看 ID 是否可预测。有时应用程序使用产生不足熵的算法。熵是 ID 的随机程度。字符串的熵越高,猜测它就越难。有些 ID 没有足够的熵,经过仔细分析就可以预测。在这种情况下,试着创建一些帐户来分析这些 ID 是如何创建的。您可能会发现一个模式,允许您预测属于其他用户的 ID。
Leaked IDs
It might also be possible that the application leaks IDs via another API endpoint or other public pages of the application, like the profile page of a user. I once found an API endpoint that allowed users to retrieve detailed direct messages through a hashed conversation_id
value. The request looks like this:
该应用程序可能也有可能通过另一个 API 端点或其他应用程序的公共页面泄露 ID,比如用户的资料页面。我曾经发现一个 API 端点,允许用户通过哈希的 conversation_id 值检索详细的直接信息。请求的样子是这样的:
GET /messages?conversation_id=O1SUR7GJ43HS93VAR8xxxx
This seems safe at first glance, since the conversation_id
is a long, random, alphanumeric sequence. But I later found that anyone could request a list of conversation_id
s for each user, just by using their public user ID! The following request would return a list of conversation_id
s belonging to that user:
乍一看,这似乎是安全的,因为 conversation_id 是一个长的,随机的,字母数字序列。但我后来发现,任何人只需使用其公共用户 ID,就可以请求每个用户的会话 ID 列表!以下请求将返回属于该用户的会话 ID 列表:
GET /messages?user_id=1236
Since the user_id
is publicly available on each user’s profile page, I could read any user’s messages by first obtaining their user_id
on their profile page, retrieving a list of conversation_id
s belonging to that user, and finally loading the messages via their conversation_id
s.
由于每个用户的个人资料页面上都公开了 user_id,因此我可以通过首先获取其个人资料页面上的 user_id,检索属于该用户的会话 ID 列表,最后通过其会话 ID 加载消息,读取任何用户的消息。
Offer the Application an ID, Even If It Doesn’t Ask for One
In modern web applications, you’ll commonly encounter scenarios in which the application uses cookies instead of IDs to identify the resources a user can access.
在现代 Web 应用程序中,你经常会遇到这样的情况,即应用程序使用 Cookie 而不是 ID 来识别用户可以访问的资源。
For example, when you send the following GET request to an endpoint, the application will deduce your identity based on your session cookie, and then send you the messages associated with that user:
例如,当您向端点发送以下 GET 请求时,应用程序将根据您的会话 Cookie 推断您的身份,然后向您发送与该用户相关联的消息:
GET /api_v1/messages
Host: example.com
Cookies: session=YOUR_SESSION_COOKIE
Since you don’t know another user’s session cookies, you cannot use those session cookies to read their messages. This might make it seem like the application is safe from IDORs. But some applications will implement an alternative way of retrieving resources, using object IDs. They sometimes do this for the convenience of the developers, for backward compatibility, or just because developers forgot to remove a test feature.
由于您不知道另一个用户的会话 cookie,因此您不能使用那些会话 cookie 来读取他们的消息。这可能会让应用程序看起来免于 IDORs。但是,有些应用程序将实现一种替代的检索资源的方法,使用对象 ID。他们有时这样做是为方便开发人员,为了向后兼容性,或者只是因为开发人员忘记删除测试功能。
If no IDs exist in the application-generated request, try adding one to the request. Append id
, user_id
, message_id
, or other object references to the URL query, or the POST body parameters, and see if it makes a difference to the application’s behavior. For example, say this request displays your messages:
如果应用程序生成的请求中没有标识符,请尝试向请求中添加一个。将 id、user_id、message_id 或其他对象引用附加到 URL 查询或 POST 正文参数中,并查看对应用程序行为是否产生影响。例如,假设此请求显示您的消息:
GET /api_v1/messages
Then maybe this request would display another user’s messages instead:
那么也许这个请求会显示另一个用户的消息:
GET /api_v1/messages?user_id=ANOTHER_USERS_ID
Keep an Eye Out for Blind IDORs
Still, sometimes endpoints susceptible to IDOR don’t respond with the leaked information directly. They might lead the application to leak information elsewhere, instead: in export files, email, and maybe even in text alerts. For example, imagine that this endpoint on example.com allows users to email themselves a copy of a receipt:
然而,有时易受 IDOR 攻击的终端不会直接响应泄漏的信息。它们可能会导致应用程序在其他地方泄漏信息,例如在导出文件、电子邮件甚至文本警报中。例如,想象一下,在 example.com 上,这个终端允许用户将收据副本通过电子邮件发送给自己:
POST /get_receipt
(POST request body)
receipt_id=3001
This request will send a copy of receipt 3001 to the registered email of the current user. Now, what if you were to request a receipt that belongs to another user, receipt 2983?
这个请求将会把收据 3001 的副本发送至当前用户已注册的电子邮件。那么,如果你要请求属于另一个用户的收据,比如是收据 2983,该怎么办呢?
POST /get_receipt
(POST request body)
receipt_id=2983
While the HTTP response does not change, you may get a copy of receipt 2983 in your email inbox! Often a malicious request can cause an info leak sometime in the future. I once found an IDOR that led to an info leak one month later, in a monthly report.
如果 HTTP 响应不变,您可能会在电子邮件收件箱中收到 2983 号收据的副本!通常,恶意请求可能会在未来某个时候造成信息泄漏。我曾经发现一个 IDOR,在一个月后的月度报告中导致了信息泄漏。
Change the Request Method
If one HTTP request method doesn’t work, you can try plenty of others instead: GET, POST, PUT, DELETE, PATCH, and so on. Applications often enable multiple request methods on the same endpoint but fail to implement the same access control for each method. For example, if this GET request is not vulnerable to IDOR and doesn’t return another user’s resources
如果一个 HTTP 请求方法不可行,你可以试试其他的方法:例如 GET,POST,PUT,DELETE,PATCH 等等。许多应用程序常常在同一个终点上启用多个请求方法,但未能为每个方法实现相同的访问控制。例如,如果此 GET 请求不易受到 IDOR 攻击,并且不会返回另一个用户的资源。
GET example.com/uploads/user1236-01.jpeg
you can try to use the DELETE method to delete the resource instead. The DELETE method removes the resource from the target URL:
您可以尝试使用 DELETE 方法删除资源。DELETE 方法会从目标 URL 中删除资源。
DELETE example.com/uploads/user1236-01.jpeg
If POST requests don’t work, you can also try to update another user’s resource by using the PUT method. The PUT method updates or creates the resource at the target URL:
如果 POST 请求不起作用,您也可以尝试使用 PUT 方法更新另一个用户的资源。PUT 方法会在目标 URL 上更新或创建资源:
PUT example.com/uploads/user1236-01.jpeg
(PUT request body)
NEW_FILE
Another trick that often works is switching between POST and GET requests. If there is a POST request like this one
另一个经常起作用的魔术是在 POST 和 GET 请求之间切换。如果有像这个一样的 POST 请求。
POST /get_receipt
(POST request body)
receipt_id=2983
you can try rewriting it as a GET request, like this:
你可以尝试将它改写为 GET 请求,就像这样:
GET /get_receipt?receipt_id=2983
Change the Requested File Type
Switching the file type of the requested file sometimes leads the server to process the authorization differently. Applications might be flexible about how the user can identify information: they could allow users to either use IDs to reference a file or use the filename directly. But applications often fail to implement the same access controls for each method of reference.
请求文件切换文件类型有时会导致服务器以不同的方式处理授权。应用程序可能灵活地确定用户如何识别信息:它们可以允许用户使用 ID 引用文件或直接使用文件名。但是,应用程序往往未能为每种引用方法实施相同的访问控制。
For example, applications commonly store information in the JSON file type. Try adding the .json extension to the end of the request URL and see what happens. If this request is blocked by the server
例如,应用程序通常将信息存储在 JSON 文件类型中。尝试在请求 URL 的末尾添加“.json”扩展名,看看会发生什么。如果服务器阻止此请求。
GET /get_receipt?receipt_id=2983
then try this one instead:
那就试试这个:
GET /get_receipt?receipt_id=2983.json
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论