无参数RCE知识点

什么是无参数RCE?

   无参rce,就是说在无法传入参数的情况下,仅仅依靠传入没有参数的函数套娃就可以达到命令执行的效果

核心代码

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

 这段代码的核心就是只允许函数而不允许函数中的参数,就是说传进去的值是一个字符串接一个(),那么这个字符串就会被替换为空,如果替换后只剩下;,那么这段代码就会被eval执行

而且因为这个正则表达式是递归调用的,所以说像a(b(c()));第一次匹配后就还剩下a(b());,第二次匹配后就还剩a();,第三次匹配后就还剩;了,所以说这一串a(b(c())),就会被eval执行,但相反,像a(b('111'));这种存在参数的就不行,因为无论正则匹配多少次它的参数总是存在的。

那假如遇到这种情况,我们就只能使用没有参数的php函数。

没有参数的php函数

getallheaders()

这个函数的作用是获取http所有的头部信息,也就是headers,然后我们可以用var_dump把它打印出来,但这个有个限制条件就是必须在apache的环境下可以使用,其它环境都是用不了的

那我们用phpstudy搭建一个网站看看

代码如下

<?php
highlight_file(__FILE__);
if(isset($_GET['code'])){
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);}
else
    die('nonono');}
else
    echo('please input code');
?>

可以看到所有的头部信息都已经作为了一个数组打印了出来

在实际的运用中,我们肯定不需要这么多条,不然它到底执行哪一条呢?

所以我们需要选择一条出来然后就执行它,这里就需要用到php中操纵数组的函数了,这里常见的是利用end()函数取出最后一位,这里的效果如下图所示,而且它只会以字符串的形式取出而不会取出键,所以说键名随便取就行:

(这里由于我没有实操演示出来,所以借用大佬的看看,大佬链接附在结尾)

那我们把最前面的var_dump改成eval,不就可以执行phpinfo了吗,换言之,就可以实现任意php代码的代码执行了,那在没有过滤的情况下执行命令也就轻而易举了,具体效果如下图所示:

那自然执行whoami命令也是可以的

system("whoami");

get_defined_vars()

getallheaders()是有局限性的,因为如果中间件不是apache的话,它就用不了了,那我们就介绍一种更为普遍的方法get_defined_vars(),这种方法其实和上面那种方法原理是差不多的

可以看到,它并不是获取的headers,而是获取的四个全局变量$_GET $_POST $_FILES $_COOKIE,而它的返回值是一个二维数组,我们利用GET方式传入的参数在第一个数组中。这里我们就需要先将二维数组转换为一维数组,这里我们用到current()函数这个函数的作用是返回数组中的当前单元,而它的默认是第一个单元,也就是我们GET方式传入的参数,我们可以看看实际效果:

这里可以看到成功输出了我们二维数组中的第一个数据,也就是将GET的数据全部输出了出来,相当于它就已经变成了一个一维数组了,那按照我们上面的方法,我们就可以利用end()函数以字符串的形式取出最后的值,然后直接eval执行就行了,这里和上面就是一样的了:

那我们把var_dump改成eval即可执行我们的phpinfo代码

那同样也能执行whoami命令

总结一下,这种方法和第一种方法几乎是一样的,就多了一步,就是利用current()函数将二维数组转换为一维数组

session_id()

简单来说就是把恶意代码写到COOKIEPHPSESSID中,然后利用session_id()这个函数去读取它,返回一个字符串,然后我们就可以用eval去直接执行了,这里有一点要注意的就是session_id()要开启session才能用,所以说要先session_start(),这里我们先试着把PHPSESSID的值取出来:

(这里依旧是没有演示成功,依旧是借用大佬的看看)

直接出来就是字符串,那就非常完美,我们就不用去做任何的转换了,但这里要注意的是,PHPSESSIID中只能有A-Z a-z 0-9-,所以说我们要先将恶意代码16进制编码以后再插入进去,而在php中,将16进制转换为字符串的函数为hex2bin

那我们就可以开始构造了,首先把PHPSESSID的值替换成这个,然后在前面把var_dump换成eval就可以成功执行了,同时我们还要加上hex2bin函数

php函数直接读取文件

上面我们一直在想办法在进行rce,但有的情况下确实无法进行rce时,我们就要想办法直接利用php函数完成对目录以及文件的操作, 接下来我们就来介绍这些函数:

1.localeconv

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

解释见:PHP localeconv() 函数 | 菜鸟教程

我们在代码中将localeconv()的返回结果输出出来,它返回的是一个二维数组,而它的第一位居然是一个点   .  

那按照我们上面讲的,是可以利用current()函数将这个点取出来的,但这个点有什么用呢?点代表的是当前目录!我们可以利用这个点完成遍历目录的操作!相当于就是linux中的ls

 我们利用current函数把这个点取出来

完成目录遍历操作

2.scandir函数

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

3.current(pos)

pos()函数是current()函数的别名,两者是一样的

current() 函数返回数组中的当前元素(单元)。

每个数组中都有一个内部的指针指向它“当前的”元素,初始指向插入到数组中的第一个元素。

详情见:PHP current() 函数

4.dirname()和chdir()

chadir()这个函数是用来跳目录的,有时想读的文件不在当前目录下就用这个来切换,因为scandir()会将这个目录下的文件和目录都列出来,那么利用操作数组的函数将内部指针移到我们想要的目录上然后直接用chdir切就好了,如果要向上跳就要构造chdir('..')

首先我们可以利用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())))))));

即可进行文件读取

5.array_reverse()

array_reverse() 函数将原数组中的元素顺序翻转,创建新的数组并返回。

将整个数组倒过来,有的时候当我们想读的文件比较靠后时,就可以用这个函数把它倒过来,就可以少用几个next()

6.highlight_file()

打印输出或者返回 filename 文件中语法高亮版本的代码,相当于就是用来读取文件的

全文引用知识点见:

PHP Parametric Function RCE · sky's blog

https://www.cnblogs.com/pursue-security/p/15406272.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/247885.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

luceda ipkiss教程 49:以pcell的方式定义线路

在ipkiss中&#xff0c;通常以i3.Circuit来设计线路&#xff08;见教程2&#xff09;&#xff0c;以i3.Pcell的框架也可以来设计线路&#xff1a; 以SplitterTree为例&#xff1a; 线路仿真结果&#xff1a; 所有代码如下&#xff1a; from si_fab import all as pdk import…

CIDR(无类域间路由)与VLSM(可变长度子网掩码)的区别

CIDR和VLSM的介绍 CIDR CIDR&#xff08;Classless Inter-Domain Routing&#xff0c;无类域间路由&#xff09;是一种用于对互联网协议&#xff08;IP&#xff09;地址进行聚合和分配的标准。CIDR的引入旨在解决IPv4地址空间的不足和低效分配的问题。在传统的IP地址规划中&a…

《Java已死、前端已凉》:真相与焦虑的辩证

文章目录 Java 企业级支柱Java 在企业级应用中的地位后端开发的支柱Java生态系统的强大 前端&#xff1a;蓬勃发展的创新引擎新技术的涌现用户体验的重要性 Java的演进与创新云原生时代的 Java开发效率和生态系统 前端技术的未来走向WebAssembly 的崛起可访问性和国际化的重要性…

FPGA巩固基础:秒表的设计

设计要求&#xff1a; 6位8段数码管&#xff0c;低三位显示毫秒计数&#xff0c;最高位显示分钟&#xff0c;其余两位显示秒计数。 开始案件与暂停按键&#xff0c;复位按键直接全部归零。 扩展部分&#xff1a;每计满一次&#xff0c;led移位一次。 框图设计&#xff1a; …

功能测试转向自动化测试 。10 年 心路历程——愿测试人不再迷茫

十年测试心路历程&#xff1a; 由于历史原因&#xff0c;大部分测试人员&#xff0c;最开始接触都是纯功能界面测试&#xff0c;随着工作年限&#xff0c;会接触到一些常用测试工具&#xff0c;比如抓包&#xff0c;数据库&#xff0c;linux 等。 我大学学的计算机专业&#…

AI创作系统ChatGPT网站源码+搭建部署教程文档,AI绘画,支持TSS GPT语音对话功能

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

利用有限制通配符来提升API的灵活性

在Java中&#xff0c;有限制通配符&#xff08;bounded wildcard&#xff09;允许你在泛型中指定一个范围&#xff0c;从而提升API的灵活性。通配符使得你能够编写更通用、适用于多种类型的代码。以下是一个利用有限制通配符提升API灵活性的例子&#xff1a; 假设有一个简单的…

本地生活服务商被清退怎么办,仅需多来客一套系统就可恢复业务

除了区域服务商&#xff0c;今年全国本地生活服务商全军覆没。只怪某本地生活服务平台韭菜割的太快。专割服务商的韭菜。从公示的数据来看今年至少没收服务商的保证金高达近四个亿&#xff0c;这是什么概念&#xff1f;&#xff01; 最近的一文公告更是除了区域服务商&#xf…

【Oracle】创建表

目录 方法一&#xff1a;CREATE TABLE 语法 创建表示例1&#xff1a;创建stuinfo(学生信息表) 创建表示例2&#xff1a;添加stuinfo(学生信息表)约束 方法二&#xff1a;CREATE TABLE AS 语法 创建表示例3&#xff1a; 创建表示例4&#xff1a;实现对select查询的结果进行…

flowable之三 启动一个流程并跟踪

1. 背景介绍 当我们部署一个流程并启动后&#xff0c;Flowable会按照既定流程定义及进行节点处理以及自动流转&#xff0c;从一个节点执行到下一个节点&#xff0c;直至结束。在此过程中&#xff0c;系统如何处理BPMN XML文件&#xff1f;节点如何进行流转&#xff1f;本文对f…

「Swift」Xcode多Target创建

前言&#xff1a;我们日常开发中会使用多个环境&#xff0c;如Dev、UAT&#xff0c;每个环境对应的业务功能都不同&#xff0c;但每个环境之间都只存在较小的差异&#xff0c;所以此时可以使用创建多个Target来实现&#xff0c;每个Target对应这个一个App&#xff0c;可以实现一…

离散型概率密度函数的分布列⇔分布函数

目录 一、super误区 1.分布函数的定义 二、分布列⇒分布函数 二、分布列⇐分布函数 一、super误区 我在读定义的时候陷入了一个误区&#xff0c;与大家分享一下。 1.分布函数的定义 由于是离散型的概率密度函数&#xff0c;我把他抽象到数轴上理解&#xff1a; 如下分布…

【教3妹学编程-算法题】反转二叉树的奇数层

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 3妹&#xff1a;“你不是真正的快乐&#xff0c; 你的…

Python求小于m的最大10个素数

为了找到小于m的最大10个素数&#xff0c;我们首先需要确定m的值。然后&#xff0c;我们可以使用一个简单的算法来检查每一个小于m的数字是否是素数。 下面是一个Python代码示例&#xff0c;可以找到小于m的最大10个素数&#xff1a; def is_prime(n): if n < 1: …

JAVA 反射

JAVA 反射 动态语言 动态语言&#xff0c;是指程序在运行时可以改变其结构&#xff1a;新的函数可以引进&#xff0c;已有的函数可以被删除等结构上的变化。比如常见的 JavaScript 就是动态语言&#xff0c;除此之外 Ruby,Python 等也属于动态语言&#xff0c;而 C、C则不属于…

【Idea】SpringBoot项目中,jar包引用冲突异常的排查 / SM2算法中使用bcprov-jdk15to18的报错冲突问题

问题描述以及解决方法&#xff1a; 项目中使用了bcprov-jdk15to18 pom依赖&#xff0c;但是发现代码中引入的版本不正确。 追溯代码发现版本引入的是bcprov-jdk15on&#xff0c;而不是bcprov-jdk15to18&#xff0c;但是我找了半天pom依赖也没有发现有引入bcprov-jdk15on依赖。…

JMeter下载与安装

文章目录 前言一、安装java环境&#xff08;JDK下载与安装&#xff09;二、JMeter下载三、JMeter安装1.解压缩2.配置环境变量 四、JMeter启动&#xff08;启动成功则代表JMeter安装成功&#xff09;五、JMeter汉化&#xff08;将JMeter修改成中文&#xff09;1.方法一&#xff…

MFC画折线图,基于x64系统

由于项目的需要&#xff0c;需要画一个折线图。 传统的Teechart、MSChart、HighSpeedChart一般是只能配置在x86系统下&#xff0c;等到使用x64系统下运行就是会报出不知名的错误&#xff0c;这个地方让人很苦恼。 我在进行配置的过程之中&#xff0c;使用Teechart将x86配置好…

卫星影像5天一更新的地图网站

如果全球影像每5天一更新&#xff0c;并集多种地图数据源于一体的PB级海量地图数据该怎样去管理呢&#xff1f; 这是当我了解到SOAR网站之后&#xff0c;思考过的一个问题。 全球最大的在线地图网站 在SOAR的官方网站&#xff0c;据称它是世界上最大的在线地图网站。 它是集…

大数据Doris(三十六):Duplicate 模型(冗余模型)介绍

文章目录 Duplicate 模型(冗余模型)介绍 一、创建doris表 二、插入数据
最新文章