preg_replace

preg_replace 函数执行一个正则表达式的搜索和替换。

语法:

参数:

0x01 /e修饰符

在php5+,若正则表达式pattern有/e修饰符,并且成功匹配,就会把replacement的值当作php代码执行,例如:

preg_replace('/(abc)/e', 'phpinfo();', '123abc');

preg_replace相关问题-LMLPHP

这种危险的做法在php5.5+会发出警告,在php7已经废除

preg_replace相关问题-LMLPHP

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")执行,也就是:

而\1变成\1

\1也就是匹配到的第一个子组

先不看结果,理想情况是

${phpinfo()}是将phpinfo()当作一个变量,此时匹配就变成:

preg_replace('/(.*)/ei', 'strtolower("\\1")', ${phpinfo()});

.*全部匹配${phpinfo()},由于这里只有一组匹配项,所以\1=phpinfo(),转换为小写不影响,成功构造出phpinfo()

而由于php的特性,包括空格 + [ ] . 等都会转化成_

preg_replace相关问题-LMLPHP

preg_replace相关问题-LMLPHP

可以用\S匹配非空白字符

preg_replace相关问题-LMLPHP

05-16 03:25