挖洞姿势 | 深度聊聊PHP下的“截断”问题
字数 1074 2025-08-18 11:37:28

PHP下的"截断"问题深度解析

0x00 前言

本文详细分析PHP环境下的截断问题,包括%00截断和iconv函数截断两种主要类型,适用于PHP安全研究人员和Web应用开发者。

0x01 %00截断原理

漏洞触发条件

  • PHP版本低于5.3.4
  • 涉及文件操作函数(include/require/file_get_contents等)

示例代码分析

// test.php
<?php include"1.txt\000.jpg"; ?>

// 1.txt
<?php echo 'helloworld'; ?>

在PHP<5.3.4环境下,上述代码会输出"helloworld",因为\000(空字符)截断了后续字符。

PHP内核执行过程

  1. 编译过程

    • 通过zend_compile_file获取文件内容
    • 使用zendparse进行语法和词法解析
    • lex_scan扫描token
  2. 执行过程

    • zend_execute执行编译后的代码
    • 通过ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER处理include操作

漏洞修复机制

PHP 5.3.4+版本中,当检测到文件名strlen长度与语法分析长度不一致时(存在截断字符),会输出"打开文件失败"。

0x02 %00截断利用方式

两种主要利用方式

  1. URL中加入%00

    • 示例:http://xxxx/shell.php%00.jpg
    • Web服务器将%00解码为ASCII NULL字符
  2. BurpSuite十六进制编辑

    • 将"shell.php .jpg"中间空格(0x20)改为0x00
    • 使用二进制编辑工具直接修改

受影响函数

  • include/require
  • file_get_contents
  • file_exists
  • 所有URL参数可控的场景

0x03 iconv函数截断

前置知识

  • PHP中所有字符都是二进制串
  • chr()函数根据ASCII值返回字符
  • PHP5.4前,iconv遇到非法字符会截断

漏洞原理

$a = 'shell.php'.chr($k)."1.jpg";
iconv("UTF-8","gbk",$a);  // 在chr(128)-chr(255)间会截断

实际案例(SiteStar Pro)

  1. 文件上传时检查后缀名正则:
if(!preg_match('/\.('.PIC_ALLOW_EXT.')$/i', $file_info["name"])) {
    // 错误处理
}
  1. 漏洞触发点:
$struct_file['name'] = iconv("UTF-8", "gb2312", $struct_file['name']);
  • 上传shell.php{%80-%99}.jpg会被截断为shell.php

0x04 防御建议

  1. 升级PHP至5.3.4+版本
  2. 对用户输入进行严格过滤
  3. 避免直接使用用户提供的文件名进行文件操作
  4. 对iconv函数转换结果进行验证
  5. 实施白名单机制检查文件扩展名

0x05 总结

PHP截断问题主要分为两类:

  1. %00截断:影响PHP<5.3.4,通过空字符截断文件名
  2. iconv截断:影响PHP<5.4.0,编码转换时截断非法字符

理解这些漏洞原理有助于开发更安全的PHP应用,并有效防御相关攻击。

PHP下的"截断"问题深度解析 0x00 前言 本文详细分析PHP环境下的截断问题,包括%00截断和iconv函数截断两种主要类型,适用于PHP安全研究人员和Web应用开发者。 0x01 %00截断原理 漏洞触发条件 PHP版本低于5.3.4 涉及文件操作函数(include/require/file_ get_ contents等) 示例代码分析 在PHP <5.3.4环境下,上述代码会输出"helloworld",因为\000(空字符)截断了后续字符。 PHP内核执行过程 编译过程 : 通过 zend_compile_file 获取文件内容 使用 zendparse 进行语法和词法解析 lex_scan 扫描token 执行过程 : zend_execute 执行编译后的代码 通过 ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER 处理include操作 漏洞修复机制 PHP 5.3.4+版本中,当检测到文件名strlen长度与语法分析长度不一致时(存在截断字符),会输出"打开文件失败"。 0x02 %00截断利用方式 两种主要利用方式 URL中加入%00 : 示例: http://xxxx/shell.php%00.jpg Web服务器将%00解码为ASCII NULL字符 BurpSuite十六进制编辑 : 将"shell.php .jpg"中间空格(0x20)改为0x00 使用二进制编辑工具直接修改 受影响函数 include/require file_ get_ contents file_ exists 所有URL参数可控的场景 0x03 iconv函数截断 前置知识 PHP中所有字符都是二进制串 chr() 函数根据ASCII值返回字符 PHP5.4前,iconv遇到非法字符会截断 漏洞原理 实际案例(SiteStar Pro) 文件上传时检查后缀名正则: 漏洞触发点: 上传 shell.php{%80-%99}.jpg 会被截断为 shell.php 0x04 防御建议 升级PHP至5.3.4+版本 对用户输入进行严格过滤 避免直接使用用户提供的文件名进行文件操作 对iconv函数转换结果进行验证 实施白名单机制检查文件扩展名 0x05 总结 PHP截断问题主要分为两类: %00截断:影响PHP <5.3.4,通过空字符截断文件名 iconv截断:影响PHP <5.4.0,编码转换时截断非法字符 理解这些漏洞原理有助于开发更安全的PHP应用,并有效防御相关攻击。