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。