通过 GET 参数利用 PHP

信息安全 php 开发 编码
2021-09-02 11:03:29

需要明确的是,这符合道德测试的利益,以确保代表我的工作获得申请。

既然已经不碍事了,下面是详细信息:

  1. 在 PHP 脚本中使用未经处理的 GET 参数来动态修改 HTML 页面。
  2. 仅将 a 之前的参数子字符串/写入 HTML 文件

我试图在<?php phpinfo() ?>呈现 HTML 页面时执行代码。

当我导航到:

[host]/index.php/someparam=<?php phpinfo() ?>

页面源代码显示代码已包含在注释中:

<!--?php phpinfo() ?-->

该代码仅在检测到时才包含在 html 注释<?中,即?>其本身就可以。

关于打败这个有什么想法吗?我试过了:

%3C%3F%70%68%70%20%70%68%70%69%6E%66%6F%28%29%20%3F%3E

这仍然导致:

<!--?php phpinfo() ?-->

base64 只是按原样呈现并且不被视为代码,十进制值不存在于源中的任何位置(甚至不包含在 html 注释中)。

2个回答

最简单的场景是尝试发送--><?php phpinfo();?><!--. 如果<?php标签被转义,那么这将导致

 <!-- -->
 <?php phpinfo();
 <!-- -->

(为清楚起见添加了换行符)。但是<?php ...?>在 HTML 页面中的存在可能还不够;PHP 代码需要在服务器端进行解释,而不仅仅是发送回客户端。

通过更仔细地检查结果字符串的开头:

 <!--?

很明显,不是 PHP 标记,而是<触发转义唯一标记,这可能是为了作为 HTML/XML/XSS 防御。这意味着您无法发送活动内容并使其执行或以客户端可执行形式呈现。

您可以再次尝试“预先转义”,通过发送

 < --><hr><!-- >

看看这是否会天真地转化为

 <!----><hr><!-- -->

它将被呈现为 HTML,或者被更彻底地改造成

 <!-- -- --><!-- hr --><!-- !-- -->

这没有任何用处。这完全取决于 HTML 打开标记检测是如何完成的,以及它是如何操作的。有时preg_replace与不正确、不完整或不够贪婪的正则表达式一起使用,它可能只去除第一个或最后一个标签,或者盲目地用最后一个结束去除第一个开头,忽略中间的任何内容。如果是这样,那么该页面很容易受到 Javascript 注入和各种相关攻击。

消毒代码是否可供检查?

朴素验证示例

例如,这段代码显然净化了 HTML 输出。

preg_replace("/<(.*)>/", "<!-- \\1 -->", $input);

但是(除了是一个经过深思熟虑的措施之外)缺乏不贪婪的运营商?使其容易受到简单的预转义攻击:

<?php
    $params = array(
            "<script>alert('FAIL');</script>",
            "< --><script>alert('Success');</script><!-- >",
    );
    foreach($params as $param)
            print preg_replace("/<(.*)>/", "<!-- \\1 -->", $param) . "\n\n\n";
?>

导致第一次天真的攻击失败,而第二次成功:

<!-- script>alert('FAIL');</script -->

<!--  --><script>alert('Success');</script><!--  -->

不幸的是,这个preg_replace选项经常被建议或实现为 HTML 注入攻击的“快速修复”,并且由于大多数“临时修复”不会这样做,它可能会成为永久性的。

更好的策略是过滤不属于原始参数的任何内容(例如[^A-Za-z0-9_],用任何内容替换),或者认为禁止字符的存在意味着以这种方式出现了一些邪恶的东西,因此最安全的反应是完全放弃请求(可能会通知用户,如果它偶然发生或由于问题而发生 - 例如,可能是语法不正确的链接 - 在其他地方;因此HTTP_REFERER强烈建议记录)。

看到这里,我唯一能想到的就是XSS 攻击您正在尝试的很可能会失败,不是因为该站点正在过滤某些输入,而是这种“功能”的实现方式。很可能是这样的:

echo '<!--'.$_GET['someparam'].'-->';

即使没有<!-- -->,脚本所做的就是获取您的输入,将其存储在变量中,然后将其打印回给您,PHP 解释器不会再次处理它。

可利用的情况是eval($_GET);,但这里显然不是这种情况。