PHP 的 %00 截断的原理

当 PHP 脚本在调用某些文件操作函数(如 include()require()file_get_contents() 等)时,底层会调用 C 语言的库函数。在 C 语言中,字符串是以空字节(null byte)作为结束符的,即十六进制的 0x00。当 C 语言函数读取到 0x00 时,就会认为字符串已经结束

而 PHP 脚本在处理用户输入时,并不会像 C 语言那样将 %00 解析为空字节,它会将其当作普通的字符串。但是,当这个字符串被传入底层 C 语言函数进行文件操作时,C 语言会截断这个字符串,只处理 %00 之前的部分

假设服务器上有一个 PHP 脚本,其代码如下:

<?php
$file = $_GET['file'];
include($file . ".php");
?>

这段代码的本意是让用户通过 file 参数指定一个文件名,然后脚本会在文件名后面自动加上 .php 后缀,再包含这个文件

现在,如果攻击者想要利用这个漏洞来包含一个图片文件 shell.jpg(其中包含恶意 PHP 代码),他可以构造一个带有 %00 截断的 URL:

http://example.com/index.php?file=shell.jpg%00

当 PHP 脚本接收到这个 URL 时:

  1. PHP 层
    • $file 的值是 shell.jpg%00
    • $file . ".php" 拼接后的字符串是 shell.jpg%00.php
  2. C 语言底层
    • include() 函数将 shell.jpg%00.php 这个字符串传递给底层的 C 语言文件操作函数时,C 语言会把 %00 识别为空字节(\0
    • 根据 C 语言的字符串处理规则,它会认为字符串在 shell.jpg 处就已经结束了
    • 最终,操作系统实际打开的文件名是 shell.jpg,而不是 shell.jpg.php

这样一来,攻击者就成功绕过了 .php 后缀的限制,实现了对 shell.jpg 的文件包含,从而执行了图片中的恶意代码

Copyright © 版权信息 all right reserved,powered by Gitbook该文件修订时间: 2025-09-25 03:12:54

results matching ""

    No results matching ""