preg_replace相关问题
preg_replace
preg_replace 函数执行一个正则表达式的搜索和替换。
语法:
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int >&$count ]] ) : mixed
参数:
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。
$replacement: 用于替换的字符串或字符串数组。
$subject: 要搜索替换的目标字符串或字符串数组。
$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
$count: 可选,为替换执行的次数。
0x01 /e修饰符
在php5+,若正则表达式pattern有/e修饰符,并且成功匹配,就会把replacement的值当作php代码执行,例如:
preg_replace('/(abc)/e', 'phpinfo();', '123abc');
这种危险的做法在php5.5+会发出警告,在php7已经废除
0x02经典漏洞
<?php
$str = addslashes($_GET['option']);
$file = file_get_contents('./option.php');
$file = preg_replace('|\$option=\'.*\';|',"\$option='$str';",$file);
file_put_contents('xxxxx/option.php',$file);
解法这篇文章写的很详细:
链接
0x03
代码如下:
foreach ($_GET as $regex => $value) {
preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value);
}
例如?a=abc
就会在abc当中匹配a,匹配成功,并且是/e修饰符,就会将strtolower("\1")执行,也就是:
eval(strtolower("\1"));
而\1变成\1
每个这样的引用将被匹配到的第n个捕获子组捕获到的文本替换。 n可以是0-99,\0和$0代表完整的模式匹配文本。
\1也就是匹配到的第一个子组
先不看结果,理想情况是
.*?=${phpinfo()}
${phpinfo()}是将phpinfo()当作一个变量,此时匹配就变成:
preg_replace('/(.*)/ei', 'strtolower("\\1")', ${phpinfo()});
.*全部匹配${phpinfo()},由于这里只有一组匹配项,所以\1=phpinfo(),转换为小写不影响,成功构造出phpinfo()
而由于php的特性,包括空格 + [ ] . 等都会转化成_
可以用\S匹配非空白字符
最新文章
- C#问题
- Linux for QQ 安装
- 计算机网络(1)-----网络层IP协议概述
- Redis持久化-数据丢失及解决(转载)
- selectors实现高并发
- 转:Android 设置屏幕不待机
- HDU 1312 http://acm.hdu.edu.cn/showproblem.php?pid=1312
- ORM之四:调用入口与调用示例
- 【OpenGL游戏开发之二】OpenGL常用API
- uva - Broken Keyboard (a.k.a. Beiju Text)(链表)
- 命令行启动Hololens Emulator,可解决内存不足的问题
- caffe 中 python 数据层
- HDU1875 畅通工程再续【最小生成树】
- Android Rom build.prop文件详解
- ubuntu 安装cuda 9.1 pytorch 0.3.0
- 关于sql 注入,感觉比较全的一篇文章
- POJ1065--Wooden Sticks(动态规划)
- keystone v3.0与2.0的区别
- Spring Boot 应用系列 2 -- Spring Boot 2 整合MyBatis和Druid
- mysql状态查看 QPS/TPS/缓存命中率查看【转】