Once More
啊拉?又是php审计。已经想吐了。
hint:ereg()函数有漏洞哩;从小老师就说要用科学的方法来算数。
查看源码:
<?php
if (isset ($_GET['password'])) {
if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
{
echo '<p>You password must be alphanumeric</p>';
}
else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
{
if (strpos ($_GET['password'], '*-*') !== FALSE)
{
die('Flag: ' . $flag);
}
else
{
echo('<p>*-* have not been found</p>');
}
}
else
{
echo '<p>Invalid password</p>';
}
根据题目可知本题是代码审计,想拿到flag需满足三个条件
ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE//输入必须是数字及字母组成
strlen($_GET['password']) < 8 && $_GET['password'] > 9999999//输入长度小于8且值大于999999
strpos ($_GET['password'], '*-*') !== FALSE//输入要包含 *-*
解法一
这里我们需要构造一个password同时满足上面三个条件,输入只能是数字及字母且要包含 *-*
,明显相互矛盾。第二个条件可以用科学计数法满足1e9
。
ereg()用途
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。可选的输入参数规则包含一个数组的所有匹配表达式,他们被正则表达式的括号分组。
strpos() 函数
strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写)
ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配。
这样我们就可以构造 password=1e9%00*-*
不过你不能直接在输入框里输入,不然%就会被url解析为%25,所以我们只能在url里面传参
解法二
ereg()只能处理字符串,遇到数组做参数时返回NULL,判断用的是 === ,要求类型也相同,而NULL跟FALSE类型是不同的,strpos()的参数同样不能为数组,否则返回NULL,而判断用的是 !== ,所以这里这样也可以得到flag。