六、strcmp比较字符串
<?php
$flag = "flag";
if (isset($_GET['a'])) {
if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。
//比较两个字符串(区分大小写)
die('Flag: '.$flag);
else
print 'No';
}
?>
本函数返回:
=0 如果两个字符串相等
<0 如果 string1 小于 string2
>0 如果 string1 大于 string2
题目要求我们满足(strcmp($_GET['a'], $flag) == 0)
才能得到flag,我们不可能输入一个和$flag一样的字符串。这里要注意一个问题,以上语句是用的==也就是弱类型比较,在弱类型里满足NULL==0,当strcmp接收到字符串以外的数据时会返回NULL(上古版本中会返回0)所以我们只需要输入a[]=1
使strcmp接收到一个不是字符串的数据就可以得到flag了
七、sha()函数比较绕过
<?php
$flag = "flag";
if (isset($_GET['name']) and isset($_GET['password']))
{
if ($_GET['name'] == $_GET['password'])
echo '<p>Your password can not be your name!</p>';
else if (sha1($_GET['name']) === sha1($_GET['password']))
die('Flag: '.$flag);
else
echo '<p>Invalid password.</p>';
}
else
echo '<p>Login first!</p>';
?>
做过CTF的对这类题肯定不陌生,md5(),sha1()这类函数都存在这个问题,当参数为一个数组时会返回false,所以我们只要构造两个不同的数组就可以了:name[]=1&password[]=2
八、SESSION验证绕过
<?php
$flag = "flag";
session_start();
if (isset ($_GET['password'])) {
if ($_GET['password'] == $_SESSION['password'])
die ('Flag: '.$flag);
else
print '<p>Wrong guess.</p>';
}
mt_srand((microtime() ^ rand(1, 10000)) % rand(1, 10000) + rand(1, 10000));
?>
乍一看以为是是什么碰撞随机数。。。不过这个题的确不是那种问题,这个只需要把cookies的值置为空让$_SESSION['password']为空我们再提交一个空的password就可以通过了。
九、密码md5比较绕过
<?php
//配置数据库
if($_POST[user] && $_POST[pass]) {
$conn = mysql_connect("********, "*****", "********");
mysql_select_db("phpformysql") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
//赋值
$user = $_POST[user];
$pass = md5($_POST[pass]);
//sql语句
// select pw from php where user='' union select 'e10adc3949ba59abbe56e057f20f883e' #
// ?user=' union select 'e10adc3949ba59abbe56e057f20f883e' #&pass=123456
$sql = "select pw from php where user='$user'";
$query = mysql_query($sql);
if (!$query) {
printf("Error: %s\n", mysql_error($conn));
exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {
//如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。
echo "<p>Logged in! Key:************** </p>";
}
else {
echo("<p>Log in failure!</p>");
}
}
?>
分析可知需满足(($row[pw]) && (!strcasecmp($pass, $row[pw])))
方可获得key。这里无法像七、一样利用md5()函数的漏洞,我们只有用sql注入的方法控制返回的pw的值才可以通过判断。
payload:?user=' union select 'e10adc3949ba59abbe56e057f20f883e' #&pass=123456
先用'闭合'同时保证不会返回其它结果,后面用一个联合查询控制返回的结果然后用#注释掉后面的内容,再输入对应的password就可以了。
十、urldecode二次编码绕过
<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("<p>not allowed!</p>");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "<p>Access granted!</p>";
echo "<p>flag: *****************} </p>";
}
?>
这个应该都能看出来怎么过吧,直接把hackerDJ的一部分二次url编码就好了,至于为什么要二次编码,因为会有一次自动解码。
payload:?id=%2568ackerDJ