如何利用PHP查询字符串解释器来绕过IDPS以及WAF

如何绕过PHP查询字符串解释器

本文的内容主要参考或者说翻译自 Abusing PHP query string parser to bypass IDS, IPS, and WAF

我们知道PHP通过向url中增加query参数来获取 $_GET 的值,也可以从HTTP request中增加 $_POST 的值,当这些内容发送到后端后,会首先被转换成数组元素,例如 /?foo=bar 会变成 Array([foo] => "bar") ,而这项工作就是由 query string parser 来完成的。

查询字符串解释器, query string parser 首先会删除一些参数中的字符或者用下划线 _ 来进行替代。

例如 /?$20news[id%00=42 会被转换成 Array([news_id] => 42)

如果IDPS or WAF定义了 new_id 的参数不能为非数字的符号就可以用以上的方法进行绕过

Figure 1: Example1

Figure 1: Example1

此时, %20news[id%00 将会被存储到 $_GET["new_id"] 中去

Why?

PHP需要将所有的参数都转换成合法的变量名,为了保证变量名可以用, query string parser 会做两件事情:

  1. 移除开头的空格
  2. 将一些字符转换为下划线(包括空格)

例如:

用户输入 URL解码后 PHP实际存储变量名
%20foo_bar%00 foo_bar foo_bar
foo%20bar%00 foo bar foo_bar
foo%5bbar foo[bar foo_bar

[What does a bash sequence ‘\033999D’ mean and where is it explained?

<?php
foreach ([
             "{chr}foo_bar",
             "foo{chr}bar",
             "foo_bar{chr}"
             ] as $k => $arg) {

    for ($i = 0; $i <= 255; ++$i) {
        echo "\033[999D\033[K\r";
        echo "[" . $arg . "] check " . bin2hex(chr($i)) . "";
        parse_str(str_replace("{chr}", chr($i), $arg) . "=bla", $o);
        usleep(5000);
        // 找到parse_str结果是 foo_bar 所对应的字符
        if (isset($o["foo_bar"])) {
            echo "\033[999D\033[K\r";
            echo $arg . " -> " . bin2hex(chr($i)) . " (" . chr($i) . ")\n";
        }
    }
    echo "\033[999D\033[K\r";
    echo "\n";
}

\033 是C语言风格的八进制字符,表示一个转义符号, [999D 表示将cursor光标回退999列,作用是强制将光标返回到开头, [k 表示清空当前行的内容, \r 还是和我们平常见到的一样的作用,就是将光标返回到一行的开头

这种编码主要和终端模拟器又关系,不同的终端模拟器使用不同的库可能效果就不一样,比如 ANSI X3.64 以及 ECMA-48 两种标准。

parse_str 方法会被用在 get, post, cookie 的参数获取上,通过三种形式来观察 parse_str 的行为,我们可以看到以下的符号(除去那些分隔符)可以被 parse_str 方法错误的解释为 foo_bar

Figure 2: parse_str.php

Figure 2: parse_str.php

Figure 3: Characters pass the parse_str 1

Figure 3: Characters pass the parse_str 1

Figure 4: Characters pass the parse_str 2

Figure 4: Characters pass the parse_str 2

Licensed under CC BY-NC-SA 4.0
Last updated on Jun 15, 2022 15:30 +0100
comments powered by Disqus
Cogito, ergo sum
Built with Hugo
Theme Stack designed by Jimmy