PHP 审计中的一些小操作
字数 1300 2025-08-05 11:39:26

PHP 审计中的实用技巧与漏洞利用方法

前言

本文总结了PHP代码审计中的多个实用技巧和常见漏洞模式,这些技巧在实际审计过程中能够帮助发现潜在的安全问题。

1. for循环中的count()陷阱

问题描述

count()函数出现在for循环条件中时,每次循环都会重新计算数组长度,如果循环体内修改了数组,可能导致意外行为。

示例代码

$a = array("a","b","c");
for ($i=0; $i < count($a); $i++) { 
    if(intval($a[$i])<1){
        unset($a[$i]);
    }
}
var_dump($a);

执行流程分析

  1. 初始count($a)为3
  2. 第一次循环($i=0): 删除$a[0],数组变为["b","c"]
  3. 第二次循环($i=1): count($a)为2,删除$a[1],数组变为["c"]
  4. 第三次循环($i=2): count($a)为1,不满足条件,循环结束

审计建议

检查for循环中是否使用了count()等动态计算函数,并确认循环体内是否修改了被计数的变量。

2. 全局变量覆盖漏洞

漏洞模式

foreach($_REQUEST as $_k=>$_v) {
    if(strlen($_k)>0 && preg_match('/^(cfg_|GLOBALS)/',$_k) && !isset($_COOKIE[$_k])) {
        exit('Request var not allow!');
    }
}
foreach(Array('_GET','_POST','_COOKIE') as $_request) {
    foreach(
$$
_request as $_k => $_v) ${$_k} = $_v;
}

绕过方法

构造请求参数:_POST[GLOBALS][xixi] = 1

执行流程

  1. 第一次foreach处理_GET时,设置${_POST}['GLOBALS']['xixi'] = 1
  2. 第二次foreach处理_POST时,设置${GLOBALS}['xixi'] = 1
  3. 成功覆盖$GLOBALS变量

修复建议

确保过滤所有可能的危险变量名,包括_POST_COOKIE

3. 富文本编辑器中的XSS绕过

漏洞场景

BBcode到HTML的转换过程中,通过嵌套标签绕过引号转义。

示例代码

$video_tag = '<iframe url="\1"></iframe>';
$url_tag = '<a href="\1">\2</a>';

$content = "[video][url=onload=alert(1);//]xixi[/url][/video]";

$content = preg_replace("/
$$
video
$$
(.*?)
$$
\/video
$$
/",$video_tag,$content);
$content = preg_replace("/
$$
url=(.*?)
$$
(.*?)
$$
\/url
$$
/",$url_tag,$content);

echo $content;

输出结果

<iframe url="<a href=onload=alert(1);//>xixi</a>"></iframe>

审计建议

检查BBcode到HTML的转换逻辑,确保属性值被正确转义。

4. 文件上传黑名单绕过技巧

4.1 NTFS ADS技巧

  • 使用文件名如a.php:$data绕过黑名单检测
  • 文件名a.php:b.jpg会使文件内容为空,可用于后续文件操作

4.2 .htaccess与getimagesize绕过

  • XBM格式只需包含以下两行即可通过getimagesize检测:
#define test_width 16
#define test_height 7
  • 由于#在.htaccess中是注释,可直接添加在文件开头

5. Windows下PHP文件操作特性

5.1 通配符使用

  • 在Windows下,PHP文件操作可使用<<<作为通配符

5.2 短文件名

  • 文件名超过6位时,可使用~1表示后续字符
  • 例如abcdefghijk.txt可表示为abcdef~1.txt

6. parse_str函数特性

特殊字符处理

parse_str会将某些特殊字符转换为下划线:

  • abc.123=1abc_123=1
  • abc 123=1abc_123=1
  • abc[123=1abc_123=1

绕过WAF的可能性

如果先检测$_GET再调用parse_str,可能导致检测与实际解析结果不一致。

Fuzz脚本示例

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

总结

本文介绍了PHP审计中的多个实用技巧,包括循环计数问题、全局变量覆盖、XSS绕过、文件上传绕过、文件操作特性和字符串解析特性。在实际审计过程中,这些技巧可以帮助发现潜在的安全问题。

PHP 审计中的实用技巧与漏洞利用方法 前言 本文总结了PHP代码审计中的多个实用技巧和常见漏洞模式,这些技巧在实际审计过程中能够帮助发现潜在的安全问题。 1. for循环中的count()陷阱 问题描述 当 count() 函数出现在for循环条件中时,每次循环都会重新计算数组长度,如果循环体内修改了数组,可能导致意外行为。 示例代码 执行流程分析 初始 count($a) 为3 第一次循环( $i=0 ): 删除 $a[0] ,数组变为 ["b","c"] 第二次循环( $i=1 ): count($a) 为2,删除 $a[1] ,数组变为 ["c"] 第三次循环( $i=2 ): count($a) 为1,不满足条件,循环结束 审计建议 检查for循环中是否使用了 count() 等动态计算函数,并确认循环体内是否修改了被计数的变量。 2. 全局变量覆盖漏洞 漏洞模式 绕过方法 构造请求参数: _POST[GLOBALS][xixi] = 1 执行流程 第一次foreach处理 _GET 时,设置 ${_POST}['GLOBALS']['xixi'] = 1 第二次foreach处理 _POST 时,设置 ${GLOBALS}['xixi'] = 1 成功覆盖 $GLOBALS 变量 修复建议 确保过滤所有可能的危险变量名,包括 _POST 和 _COOKIE 。 3. 富文本编辑器中的XSS绕过 漏洞场景 BBcode到HTML的转换过程中,通过嵌套标签绕过引号转义。 示例代码 输出结果 审计建议 检查BBcode到HTML的转换逻辑,确保属性值被正确转义。 4. 文件上传黑名单绕过技巧 4.1 NTFS ADS技巧 使用文件名如 a.php:$data 绕过黑名单检测 文件名 a.php:b.jpg 会使文件内容为空,可用于后续文件操作 4.2 .htaccess与getimagesize绕过 XBM格式只需包含以下两行即可通过 getimagesize 检测: 由于 # 在.htaccess中是注释,可直接添加在文件开头 5. Windows下PHP文件操作特性 5.1 通配符使用 在Windows下,PHP文件操作可使用 < 或 << 作为通配符 5.2 短文件名 文件名超过6位时,可使用 ~1 表示后续字符 例如 abcdefghijk.txt 可表示为 abcdef~1.txt 6. parse_ str函数特性 特殊字符处理 parse_str 会将某些特殊字符转换为下划线: abc.123=1 → abc_123=1 abc 123=1 → abc_123=1 abc[123=1 → abc_123=1 绕过WAF的可能性 如果先检测 $_GET 再调用 parse_str ,可能导致检测与实际解析结果不一致。 Fuzz脚本示例 总结 本文介绍了PHP审计中的多个实用技巧,包括循环计数问题、全局变量覆盖、XSS绕过、文件上传绕过、文件操作特性和字符串解析特性。在实际审计过程中,这些技巧可以帮助发现潜在的安全问题。