源码:
<?php
$flag="flag";
if(isset($_GET['password']))
{
if(ereg("^[a-zA-Z0-9]+$",$_GET['password'])===FALSE)
{
echo'<p>Youpasswordmustbealphanumeric</p>';
}
elseif(strlen($_GET['password'])<8&&$_GET['password']>9999999)
{
if(strpos($_GET['password'],'*-*')!==FALSE)//strpos—查找字符串首次出现的位置
{
die('Flag:'.$flag);
}
else
{
echo('<p>*-*havenotbeenfound</p>');
}
}
else
{
echo'<p>Invalidpassword</p>';
}
}
?>
函数释义:
字体示例:该函数返回成功设置的变量数目。
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。可选的输入参数规则包含一个数组的所有匹配表达式,他们被正则表达式的括号分组。
strpos()函数查找某字符串在另一字符串中第一次出现的位置(区分大小写)。
解题过程:
思路1:
ereg("^[a-zA-Z0-9]+$",$_GET['password'])
正则匹配可以用%00绕过,ereg正则函数,限制了password的格式,一个或者多个数字、大小写字母;
strlen($_GET['password'])<8&&$_GET['password']>9999999
长度小于8且长度大于9999999,构造10的7次方大于9999999,即1e7;
strpos($_GET['password'],'*-*')!==FALSE)//strpos—查找字符串首次出现的位置
strpos函数查找某字符串在另一字符串中第一次出现的位置(区分大小写),本题中需要匹到"*-*"才能输出flag,因此密码里面需要有*-*;
构造payload为?password=1e7%00*-*
http://localhost:63342/php_bugs-master/5.1.php?password=1e7%00*-*
得到flag:
刚开始打开php文件提示404,重新建了一个php文件把代码复制过去就又可以了。
注意不可以改变payload的顺序,因为首先要满足ereg函数的匹配,*-*用%00截断绕过,测试如下,未能获取到flag:
思路2:
if(ereg("^[a-zA-Z0-9]+$",$_GET['password'])===FALSE)
ereg()只能处理字符串,而password是数组,所以返回的是null,三个等号的时候不会进行类型转换。所以null!==false
if(strpos($_GET['password'],'*-*')!==FALSE)
strpos() 的参数同样不能够是数组,所以返回的依旧是null,null!==false也正确。
http://localhost:63342/php_bugs-master/5.1.php?password[]=
得到flag:
参考链接:
https://github.com/bowu678/php_bugs