PHP中一个有趣的preg_replace函数详解


Posted in PHP onAugust 15, 2018

0x01 起因

事情的起因是下午遇到了 preg_replace 函数,我们都知道 preg_replace 函数可能会导致命令执行。现在我们来一些情况。

0x02 经过

踩坑1:

测试代码大概是这样的:

foreach ($_GET as $regex => $value) {
 preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value);
}

测试过程中发现通过浏览器的方式传入数据的时候,会将 . + 等特殊字符转换为 _ 。

PHP中一个有趣的preg_replace函数详解

PHP中一个有趣的preg_replace函数详解

这里涉及到了php的一个特性

php自身在解析请求的时候,如果参数名字中包含空格、.、[等字符,会将他们转换成_。

<?php
$a = $_GET;
var_dump($a);
?>

PHP中一个有趣的preg_replace函数详解

经过我的fuzz,结果如下图:

PHP中一个有趣的preg_replace函数详解

踩坑2:

那我们知道 preg_replace 的 /e 修正符会将 replacement 参数当作 php 代码,并且以 eval 函数的方式执行,前提是 subject 中有 pattern 的匹配。既然是这样我们看一张图。

PHP中一个有趣的preg_replace函数详解

图中实际上通过 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()}}

PHP中一个有趣的preg_replace函数详解

PHP中一个有趣的preg_replace函数详解

0x04 后记

其实还有点小问题,我这边没有写,不过大家可以看看这个深入研究preg_replace与代码执行。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
从零开始 教你如何搭建Discuz!4.1论坛
Jul 07 PHP
显示youtube视频缩略图和Vimeo视频缩略图代码分享
Feb 13 PHP
PHP用星号隐藏部份用户名、身份证、IP、手机号等实例
Apr 08 PHP
php通过两层过滤获取留言内容的方法
Jul 11 PHP
PHP自定义函数获取URL中一级域名的方法
Aug 23 PHP
php强制下载文件函数
Aug 24 PHP
功能强大的php文件上传类
Aug 29 PHP
PHP入门教程之数学运算技巧总结
Sep 11 PHP
Zend Framework入门应用实例详解
Dec 11 PHP
php获取文章内容第一张图片的方法示例
Jul 03 PHP
PHP调用其他文件中的类
Apr 02 PHP
php微信扫码支付 php公众号支付
Mar 24 PHP
PHP使用curl_multi_select解决curl_multi网页假死问题的方法
Aug 15 #PHP
php+croppic.js实现剪切上传图片功能
Aug 14 #PHP
PHP设计模式之委托模式定义与用法简单示例
Aug 13 #PHP
PHP设计模式之建造者模式定义与用法简单示例
Aug 13 #PHP
PHP设计模式之装饰器模式定义与用法简单示例
Aug 13 #PHP
PHP实现的ID混淆算法类与用法示例
Aug 10 #PHP
PHP+ajax实现二级联动菜单功能示例
Aug 10 #PHP
You might like
学习php中的正则表达式
2014/08/17 PHP
PHP 数组基本操作小结(推荐)
2016/06/13 PHP
laradock环境docker-compose操作详解
2019/07/29 PHP
javascript类型转换示例
2014/04/29 Javascript
jQuery判断元素上是否绑定了指定事件的方法
2015/03/17 Javascript
JS获取CSS样式(style/getComputedStyle/currentStyle)
2016/01/19 Javascript
jQuery EasyUI封装简化操作
2016/09/18 Javascript
AngularJS实现用户登录状态判断的方法(Model添加拦截过滤器,路由增加限制)
2016/12/12 Javascript
Bootstrap源码解读模态弹出框(11)
2016/12/28 Javascript
JS跨域请求外部服务器的资源
2017/02/06 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
AngularJS 中ui-view传参的实例详解
2017/08/25 Javascript
Vue全家桶实践项目总结(推荐)
2017/11/04 Javascript
webpack 3.X学习之多页面打包的方法
2018/09/04 Javascript
vue2之简易的pc端短信验证码的问题及处理方法
2019/06/03 Javascript
微信小程序开发常见问题及解决方案
2019/07/11 Javascript
js布局实现单选按钮控件
2020/01/17 Javascript
微信小程序录音实现功能并上传(使用node解析接收)
2020/02/26 Javascript
Vue中keep-alive组件的深入理解
2020/08/23 Javascript
python压缩文件夹内所有文件为zip文件的方法
2015/06/20 Python
python运行其他程序的实现方法
2017/07/14 Python
python爬虫系列Selenium定向爬取虎扑篮球图片详解
2017/11/15 Python
python中print()函数的“,”与java中System.out.print()函数中的“+”功能详解
2017/11/24 Python
Anaconda 离线安装 python 包的操作方法
2018/06/11 Python
python读取文本中的坐标方法
2018/10/14 Python
Python实现带下标索引的遍历操作示例
2019/05/30 Python
python GUI库图形界面开发之PyQt5中QMainWindow, QWidget以及QDialog的区别和选择
2020/02/26 Python
缅甸网上购物:Shop.com.mm
2017/12/05 全球购物
澳大利亚男士西服品牌:M.J.Bale
2018/02/06 全球购物
美国爆米花工厂:The Popcorn Factory
2019/09/14 全球购物
师范生实习的个人自我鉴定
2013/10/20 职场文书
十佳青年事迹材料
2014/08/21 职场文书
党的群众路线对照检查材料
2014/08/27 职场文书
毕业实习证明(4篇)
2014/10/28 职场文书
奖励申请报告范文
2015/05/15 职场文书
Oracle11g R2 安装教程完整版
2021/06/04 Oracle