一次对PHP正则绕过的思考历程
字数 1271 2025-08-09 09:46:33

PHP正则表达式绕过技术深度解析

0x00 前言

本文详细分析PHP中基于正则表达式的安全过滤机制存在的多种绕过方法,涵盖XSS防护和PHP标签过滤的绕过技术。这些技术在实战渗透测试和CTF比赛中具有重要应用价值。

0x01 目标函数分析

过滤函数代码

function checkstr($str) {
    // 第一层过滤:拦截特定HTML标签和PHP标签
    if (preg_match("/<(\/?)(script|i?frame|style|html|\?php|body|title|link|meta)([^>]*?)>/is", $str, $match)) {
        return false;
    }
    // 第二层过滤:拦截HTML标签中的on事件属性
    if (preg_match("/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/is", $str, $match)) {
        return false;
    }
    return true;
}

第一层过滤分析

正则表达式:/<(\/?)(script|i?frame|style|html|\?php|body|title|link|meta)([^>]*?)>/is

  • 修饰符

    • i:不区分大小写
    • s:使.匹配包括换行符在内的所有字符
  • 分组解析

    1. (\/?):匹配可选的/字符(用于闭合标签)
    2. (script|i?frame|style|html|\?php|body|title|link|meta):匹配黑名单标签
    3. ([^>]*?):非贪婪匹配任意非>字符,直到遇到>

拦截目标

  • <script></script>
  • <iframe><frame>
  • <?php ... ?>等PHP标签
  • 其他黑名单中的HTML标签

第二层过滤分析

正则表达式:/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/is

  • 分组解析
    1. (<[^>]*):贪婪匹配<后所有非>字符
    2. on[a-zA-Z]+\s*=:匹配on开头的事件属性
    3. ([^>]*>):匹配剩余部分直到>

拦截目标

  • ``
  • <tag onxxxx="malicious code">
  • 其他包含on事件的HTML标签

0x02 绕过技术详解

2.1 绕过PHP标签过滤

场景:文件写入漏洞,需要写入PHP代码

方法1:使用替代PHP标签

<?= phpinfo(); ?>  <!-- 短标签语法 -->
<? phpinfo(); ?>   <!-- 需要开启short_open_tag -->

方法2:省略闭合标签

<?php phpinfo();   // 不闭合,避免匹配到?>

方法3:使用__halt_compiler()

<?php phpinfo();__halt_compiler();

方法4:伪协议编码绕过

php://filter/write=convert.base64-decode/resource=shell.php&c=PD9waHAgcGhwaW5mbygpOz8+

2.2 绕过XSS过滤

方法1:使用非事件属性执行JS

<object data=javascript:alert(1)>

方法2:利用标签属性优先级

"/onerror=alert(1);>

原理:双引号的优先级高于>,使正则匹配失败但浏览器仍能解析

2.3 正则回溯绕过

条件

  1. preg_match返回值未使用全等(===)判断
  2. 输入字符串能导致大量回溯

方法1:针对非贪婪匹配的回溯

<?php //[大量a字符]?>

方法2:针对贪婪匹配的回溯


原理:当回溯次数超过pcre.backtrack_limit(默认100万)时,preg_match返回false

0x03 防御建议

  1. 替代方案

    • 使用htmlspecialchars()进行HTML实体编码
    • 对文件名进行重命名(如MD5+时间戳)
  2. 正则改进

    • 避免使用非贪婪匹配*?在关键位置
    • preg_match返回值使用全等判断===
  3. 配置调整

    • 禁用不必要的PHP标签类型
    • 限制输入长度防止回溯攻击

0x04 总结

本文详细分析了PHP正则过滤机制的多种绕过技术,包括:

  • PHP标签的替代写法
  • HTML标签解析差异利用
  • 正则引擎回溯特性攻击
  • 编码转换绕过

这些技术展示了黑名单过滤的固有弱点,强调了使用白名单和编码转换等更安全方法的重要性。

PHP正则表达式绕过技术深度解析 0x00 前言 本文详细分析PHP中基于正则表达式的安全过滤机制存在的多种绕过方法,涵盖XSS防护和PHP标签过滤的绕过技术。这些技术在实战渗透测试和CTF比赛中具有重要应用价值。 0x01 目标函数分析 过滤函数代码 第一层过滤分析 正则表达式: /<(\/?)(script|i?frame|style|html|\?php|body|title|link|meta)([^>]*?)>/is 修饰符 : i :不区分大小写 s :使 . 匹配包括换行符在内的所有字符 分组解析 : (\/?) :匹配可选的 / 字符(用于闭合标签) (script|i?frame|style|html|\?php|body|title|link|meta) :匹配黑名单标签 ([^>]*?) :非贪婪匹配任意非 > 字符,直到遇到 > 拦截目标 : <script> 、 </script> <iframe> 、 <frame> <?php ... ?> 等PHP标签 其他黑名单中的HTML标签 第二层过滤分析 正则表达式: /(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/is 分组解析 : (<[^>]*) :贪婪匹配 < 后所有非 > 字符 on[a-zA-Z]+\s*= :匹配 on 开头的事件属性 ([^>]*>) :匹配剩余部分直到 > 拦截目标 : `` <tag onxxxx="malicious code"> 其他包含 on 事件的HTML标签 0x02 绕过技术详解 2.1 绕过PHP标签过滤 场景 :文件写入漏洞,需要写入PHP代码 方法1:使用替代PHP标签 方法2:省略闭合标签 方法3:使用 __halt_compiler() 方法4:伪协议编码绕过 2.2 绕过XSS过滤 方法1:使用非事件属性执行JS 方法2:利用标签属性优先级 原理 :双引号的优先级高于 > ,使正则匹配失败但浏览器仍能解析 2.3 正则回溯绕过 条件 : preg_match 返回值未使用全等( === )判断 输入字符串能导致大量回溯 方法1:针对非贪婪匹配的回溯 方法2:针对贪婪匹配的回溯 原理 :当回溯次数超过 pcre.backtrack_limit (默认100万)时, preg_match 返回 false 0x03 防御建议 替代方案 : 使用 htmlspecialchars() 进行HTML实体编码 对文件名进行重命名(如MD5+时间戳) 正则改进 : 避免使用非贪婪匹配 *? 在关键位置 对 preg_match 返回值使用全等判断 === 配置调整 : 禁用不必要的PHP标签类型 限制输入长度防止回溯攻击 0x04 总结 本文详细分析了PHP正则过滤机制的多种绕过技术,包括: PHP标签的替代写法 HTML标签解析差异利用 正则引擎回溯特性攻击 编码转换绕过 这些技术展示了黑名单过滤的固有弱点,强调了使用白名单和编码转换等更安全方法的重要性。