PHP中一个有趣的preg_replace函数详解
0x01 起因
事情的起因是下午遇到了 preg_replace 函数,我们都知道 preg_replace 函数可能会导致命令执行。现在我们来一些情况。
0x02 经过
踩坑1:
测试代码大概是这样的:
foreach ($_GET as $regex => $value) { preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value); }
测试过程中发现通过浏览器的方式传入数据的时候,会将 . + 等特殊字符转换为 _ 。
这里涉及到了php的一个特性
php自身在解析请求的时候,如果参数名字中包含空格、.、[等字符,会将他们转换成_。
<?php $a = $_GET; var_dump($a); ?>
经过我的fuzz,结果如下图:
踩坑2:
那我们知道 preg_replace 的 /e 修正符会将 replacement 参数当作 php 代码,并且以 eval 函数的方式执行,前提是 subject 中有 pattern 的匹配。既然是这样我们看一张图。
图中实际上通过 eval 执行的是 strtolower 函数。分别实际执行的是:
strtolower("JUST TEST"); strtolower("PHPINFO()"); strtolower("{${PHPINFO()}}");
第三个之所以可以执行代码,是因为我们通过复杂(花括号)语法的方式来让其代码执行。
踩坑3:
回到源代码中,我们再理解一下:
foreach ($_GET as $regex => $value) { preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value); }
这里的 replacement 是 strtolower(“\\1”) ,着重理解一下 \\1 。
每个这样的引用将被匹配到的第n个捕获子组捕获到的文本替换。 n可以是0-99,\0和\$0代表完整的模式匹配文本。
假设一个正则表达式是这样的:
preg_replace('/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
这里的 \$1\$2\$4 等同于上面的 \1\2\4 的作用,因此我们看一下是怎么选择匹配的。
$1 $2 $3 $4 '/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i'
0x03 解决
好了上面都已经铺垫完坑了,这里要开始解决了。
foreach ($_GET as $regex => $value) { preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value); }
我们想要让这部分代码达到代码执行的效果需要达到几个条件:
- pattern 部分的表达式需要命中 \$value 中的数据
- \1 中取出的数据复杂(花括号)语法的特征,来保证在双引号的包含下达到代码执行的效果
- 由于php的特性url会将 . 、 [ 、 + 等特殊字符转换为 _ 。
我们知道这里是通过 get 方式获取到 \$regex 和 \$value 的,要想在 replacement 部分通过 \1 截取到 pattern 正则匹配命中 \$value 中的数据,并且携带 \$ 、 { 、 ( 这里就涉及到正则表达式的使用了。
这里我选择了 \S ,也就是匹配任意的非空白字符,那么最后的payload长这样
\S*()={${phpinfo()}}
0x04 后记
其实还有点小问题,我这边没有写,不过大家可以看看这个深入研究preg_replace与代码执行。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。
相关推荐
-
php中preg_replace_callback函数简单用法示例
本文实例讲述了php中preg_replace_callback函数用法.分享给大家供大家参考,具体如下: mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] ) 本函数的行为几乎和 preg_replace() 一样,除了不是提供一个 replacement 参数,而是指定一个 callback 函数.该函数将以目标字符串中的匹配数组作为输入参数,并返回用于替换的
-
PHP 字符串正则替换函数preg_replace使用说明
1. preg_replace() $msg = preg_replace("/<style>.+<\/style>/is", "", $msg); -----删除<style></style>和中间的部分 $msg = preg_replace("/<[^>]+>/", "", $msg); -----是删除<>和中间的内容 i (PCRE_CAS
-
PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析
本文实例讲述了PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法.分享给大家供大家参考,具体如下: 环境错误级别:error_reporting =E_ALL 某天我在研究一下php下的正则替换函数perg_replace(), 示例: 代码: $subject="2222<b>a</b>2222fff222222222A22222"; $pattern = "/(a)/e&q
-
PHP正则替换函数preg_replace和preg_replace_callback使用总结
在编写PHP模板引擎工具类时,以前常用的一个正则替换函数为 preg_replace(),加上正则修饰符 /e,就能够执行强大的回调函数,实现模板引擎编译(其实就是字符串替换). 详情介绍参考博文:PHP函数preg_replace() 正则替换所有符合条件的字符串 应用举例如下: 复制代码 代码如下: <?php /** * 模板解析类 */ class Template { public function compile($template) { // if逻辑 $template
-
php正则preg_replace_callback函数用法实例
本文实例讲述了php正则preg_replace_callback函数的用法.分享给大家供大家参考.具体实现方法如下: php正则表达式功能强大,本范例演示了preg_replace_callback函数的用法 // Define a dummy text, for testing... $Text = "Title: Hello world!\n"; $Text .= "Author: Jonas\n"; $Text .= "This is a exam
-
php中使用preg_replace函数匹配图片并加上链接的方法
介绍:preg_replace 执行正则表达式的搜索和替换,如果只是单纯的匹配字符串建议使用str_replace(),因为其执行效率高的多.mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) 在 subject 中搜索 pattern 模式的匹配项并替换为 replacement.如果指定了 limit,则仅替换 limit 个匹配,如果省略 limit 或者其值为 -1,则所有
-
PHP 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
前面我们已经学习了正则表达式的基础语法,包括了定界符.原子.元字符和模式修正 符.实际上正则表达式想要起作用的话,就必须借用正则表达式处理函数.本节我们就来介绍一下PHP中基于perl的正则表达式处理函数,主要包含了分割, 匹配,查找,替换等等处理操作,依旧是配合示例讲解,让我们开始吧. 和正则表达式一样,正则表达式处理函数不能够独立使用,而这必须相结合,才能够完成特定的功能.在前面我们也说过,基于perl的正则表达式要快于POXIS正则表达式处理函数,所以我们只介绍以preg开头的基于perl
-
php正则之函数 preg_replace()参数说明
preg_replace 字符串比对解析并取代. 语法: mixed preg_replace(mixed pattern, mixed replacement, mixed subject); 返回值: 混合类型资料 函数种类: 资料处理 内容说明 本函数以 pattern 的规则来解析比对字符串 subject,欲取而代之的字符串为参数 replacement.返回值为混合类型资料,为取代后的字符串结果. 使用范例 下例返回值为 $startDate = 6/19/1969 复
-
PHP5.2下preg_replace函数的问题
preg_replace 使用的超过了php5.2默认允许的字节,也就是pcre.backtrack_limit和pcre.recursion_limit的大小的问题. Discuz!6.0.0正式版程序发布以来,大家都热火朝天的升级中,但是部分插件在6.0下出现了问题 比如http://www.discuz.net/viewthread.php?tid=559133这个银行插件 在php为5.2.0及以上的环境下安装以后会出现白屏的问题 从Discuz!用户的角度考虑,我们需要去协助插件作者解
-
PHP中一个有趣的preg_replace函数详解
0x01 起因 事情的起因是下午遇到了 preg_replace 函数,我们都知道 preg_replace 函数可能会导致命令执行.现在我们来一些情况. 0x02 经过 踩坑1: 测试代码大概是这样的: foreach ($_GET as $regex => $value) { preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value); } 测试过程中发现通过浏览器的方式传入数据的时候,会将 . + 等特殊字
-
基于Java中进制的转换函数详解
十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinaryString(int i) 十六进制转成十进制 Integer.valueOf("FFFF",16).toString() 八进制转成十进制 Integer.valueOf("876",8).toString() 二进制转十进制 Integer.valueOf(&qu
-
对numpy中的transpose和swapaxes函数详解
transpose() 这个函数如果括号内不带参数,就相当于转置,和.T效果一样,而今天主要来讲解其带参数. 我们看如下一个numpy的数组: `arr=np.arange(16).reshape((2,2,4)) arr= array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) ` 那么有: arr.transpose(2,1,0) array([[[ 0, 8], [ 4, 12]], [[ 1
-
浅谈Python中的zip()与*zip()函数详解
前言 1.实验环境: Python 3.6: 2.示例代码地址:下载示例: 3.本文中元素是指列表.元组.字典等集合类数据类型中的下一级项目(可能是单个元素或嵌套列表). zip(*iterables)函数详解 zip()函数的定义 从参数中的多个迭代器取元素组合成一个新的迭代器: 返回: 返回一个zip对象,其内部元素为元组:可以转化为列表或元组: 传入参数:元组.列表.字典等迭代器. zip()函数的用法 当zip()函数中只有一个参数时 zip(iterable)从iterable中依次取
-
angularjs指令中的compile与link函数详解
通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. angularjs里的指令非常神奇,允许你创建非常语义化以及高度重用的组件,可以理解为web components的先驱者. 网上已经有很多介绍怎么使用指令的文章以及相关书籍,相互比较的话,很少有介绍compile与link的区别,更别说pre-link与post-link了. 大部分教程只是简单的说下compile会在ng内部用到,而且建
-
Go语言中的流程控制结构和函数详解
这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和无条件跳转. if if也许是各种编程语言中最常见的了,它的语法概括起来就是:如果满足条件就做某事,否则做另一件事. Go里面if条件判断语句中不需要括号,如下代码所示: 复制代码 代码如下: if x > 10 { fmt.Println("x is greater than 10&
-
Node.js中使用计时器定时执行函数详解
如果你熟悉客户端JavaScript编程,你可能使用过setTimeout和setInterval函数,这两个函数允许延时一段时间再运行函数.比如下面的代码, 一旦被加载到Web页面,1秒后会在页面文档后追加"Hello there": 复制代码 代码如下: var oneSecond = 1000 * 1; // one second = 1000 x 1 ms setTimeout(function() { document.write('<p>Hello there.
-
C++类中的六大默认成员函数详解
在C++中,当你去创建一个类的时候,即便这个类是空类,也会自动生成下面6个默认成员函数,在本篇博客中,我将逐一分析下面6个默认成员函数. 构造函数 构造函数并不是去构造函数的函数,而是去对函数进行初始化的函数.构造函数的函数名与类名相同,当我们每次创建类对象的时候,就会自动调用构造函数.构造函数在对象的生命周期中只会调用1次. class Date { public: //构造函数 Date(int year = 2021, int month = 4, int day = 11) { _yea
-
JavaScript中的apply和call函数详解
第一次翻译技术文章,见笑了! 翻译原文: Function.apply and Function.call in JavaScript 第一段略. 每个JavaScript函数都会有很多附属的(attached)方法,包括toString().call()以及apply().听起来,你是否会感到奇怪,一个函数可能会有属于它自己的方法,但是记住,JavaScript中的每个函数都是一个对象.看一下 这篇文章 ,复习一下(refresher)JavaScript特性.你可能还想知道JavaScrip
-
Lua中的模块与module函数详解
很快就要开始介绍Lua里的"面向对象"了,在此之前,我们先来了解一下Lua的模块. 1.编写一个简单的模块 Lua的模块是什么东西呢?通常我们可以理解为是一个table,这个table里有一些变量.一些函数- 等等,这不就是我们所熟悉的类吗? 没错,和类很像(实际上我说不出它们的区别). 我们来看看一个简单的模块,新建一个文件,命名为game.lua,代码如下: 复制代码 代码如下: game = {} function game.play() print("那么
随机推荐
- 密码破解全教程
- Java的Struts2框架配合Ext JS处理JSON数据的使用示例
- javascript正则表达式模糊匹配IP地址功能示例
- php 特殊字符处理函数
- 浏览器兼容console对象的简要解决方案分享
- Nodejs极简入门教程(一):模块机制
- HTML5 canvas 9绘制图片实例详解
- asp下返回以千分位显示数字格式化的数值
- jQuery中选择器小问题(新人难免遇到)
- 简介内容超出部分文字隐藏省略的特效(可显示)
- android activity设置无标题实现全屏
- C# Socket网络编程实例
- C#中使用资源的方法分析
- 浅谈docker学习之docker数据卷(volume)
- vue iview实现动态路由和权限验证功能
- Python实现将HTML转成PDF的方法分析
- 从零开始的Socket编程学习
- Python 二叉树的层序建立与三种遍历实现详解
- angular 表单验证器验证的同时限制输入的实现
- 在Spring Boot框架中使用AOP的正确姿势