简析一道程序逻辑存在问题的CTF练习题首席安全官频道

前言

最近做了一道程序逻辑存在问题的CTF练习题,首席安全官频道在这里跟大家分享一下解题思路和解题过程。

题目链接:

解题思路

看到这道题时,我的第一反应就是查看网页源代码,右键查看网页源代码,发现网页源代码中有这样一行代码:

<a href="index.txt">

根据以往的经验我可以推断出这是程序的源代码,访问/index.txt,果然,这是程序的源代码:

简析一道程序逻辑存在问题的CTF练习题

简析一道程序逻辑存在问题的CTF练习题

既然程序的源代码都给我们了,那我们只要审计一下源码,找出其中存在的漏洞就可以了。

这样一来,这道题就简单多了。

我们先来了解一下程序的处理过程:

$user = $_POST[user];
$pass = md5($_POST[pass]);

首先,程序先声明了两个变量,其中:

user变量是用户登录时输入的用户名;

pass变量是用户登录时输入的密码的MD5密文(注:数据库中存储的是密码的MD5密文)。

$sql = "select pw from php where user='$user'";
$query = mysql_query($sql);

sql变量是一条SQL语句:从php表中检索用户登陆时输入的用户名的密码(pw列)

query变量则是执行sql变量的SQL语句

$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
 
if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {
echo "<p>Logged in! Key:************** </p>";
}
else {
  echo("<p>Log in failure!</p>");

}

接着声明row变量是把sql变量的SQL语句执行后返回的结果转换为数组

如果row变量中pw的内容和用户登陆时输入的密码的MD5密码相同,则输出“Logged in!”并输出key

否则输出“Log in failure!”

因此,我们只需要让输入的密码的MD5密文和数据库检索出来的密码匹配就可以绕过验证,得到我们的key

但是,我们知道,正常的输入肯定是没办法通过验证的,那要怎么办呢?

解题过程

大家可能会注意到,这道题没有过滤SQL注入,所以我们可以尝试通过SQL注入来解出这道题:

用户名改为’ union select ‘c4ca4238a0b923820dcc509a6f75849b’ –,密码输入1即可绕过验证得到key

解释一下:

其中,c4ca4238a0b923820dcc509a6f75849b是1的MD5密文;

通过这样一改,SQL语句执行时就会变成从php表中检索密码(pw列)是c4ca4238a0b923820dcc509a6f75849b的用户的密码(pw列)

很明显,这个用户的密码的MD5密文就是c4ca4238a0b923820dcc509a6f75849b,明文密码是1

这时,我们输入的密码的MD5密文和从数据库中检索出来的密码相匹配,也就绕过了验证,得到了key

简析一道程序逻辑存在问题的CTF练习题

简析一道程序逻辑存在问题的CTF练习题

逻辑漏洞挖掘经验

因为我也是最近才开始研究Web安全的,所以很少挖到逻辑漏洞,没什么经验,所以这里就跟大家简单地说几句就行。

挖掘逻辑漏洞时,最好就是读懂程序的源代码,然后找找其中有没有什么函数有漏洞或者是说这个程序的逻辑有没有缺陷,而且要反复试验,说不定本来你的思路是对的,就因为没有耐心,与这个漏洞失之交臂。

总结

大家可以看到,逻辑漏洞的危害还是挺大的,所以防范逻辑漏洞非常有必要,下面是本人总结的一些防范逻辑漏洞的方法:

1、开发人员在开发一套建站系统或网站时,一定要反复地去检查程序的逻辑是否清晰,源代码是否存在漏洞

2、切忌不要使用存在漏洞的函数

3、源码写错是非常致命的,所以开发人员一定要掌握程序中函数的语法,如果忘记了或不太清楚,建议翻阅相关书籍或者是百度

各种类型的逻辑漏洞具体防范方法请参考此文章:Web安全测试中常见逻辑漏洞解析(实战篇)

*本文作者:J1anCan,转载请注明来自 FreeBuf.COM

2017-10-10 12:05 阅读:137