SQL约束攻击
最近在刷bugku的ctf题的时候,遇到一道SQL约束攻击的题目,那就正好借着这个题目,来深入学习下SQL约束攻击。
贴个题目的链接:http://118.89.219.210:49163/index.php
简介:
关于SQL的攻击行为,注入可以说是接触最多,也是容易利用且危害较大那种,但是SQL约束攻击,其实并不常见,说实在的我是第一次遇到这种类型的问题,但是它的严重性并不比注入低。 首先了解几个关键知识点:
-
在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。换句话说“admin”等同于“admin ”,对于绝大多数情况来说都是成立的(诸如WHERE子句中的字符串或INSERT语句中的字符串)例如以下语句的查询结果,与使用用户名“admin”进行查询时的结果是一样的。
SELECT * FROM users WHERE username='admin ';
-
贴两段代码:
1.注册:
<?php // Checking whether a user with the same username exists $username = mysql_real_escape_string($_GET['username']); $password = mysql_real_escape_string($_GET['password']); $query = "SELECT * FROM users WHERE username='$username'"; $res = mysql_query($query, $database); if($res) { if(mysql_num_rows($res) > 0) { // User exists, exit gracefully } else { // If not, only then insert a new entry $query = "INSERT INTO users(username, password) VALUES ('$username','$password')"; } }
2.登录:
<?php $username = mysql_real_escape_string($_GET['username']); $password = mysql_real_escape_string($_GET['password']); $query = "SELECT username FROM users WHERE username='$username' AND password='$password' "; $res = mysql_query($query, $database); if($res) { if(mysql_num_rows($res) > 0){ $row = mysql_fetch_assoc($res); return $row['username']; } } return Null;
-
根据代码,我们可以看到开发人员有一些安全的考虑,使用mysql_real_escape_string()过滤用户输入参数,使用单引号(’)来增加安全性。
-
当我们检索“admin”的,将返回两个用户。第二个用户名实际上是“admin+若干空格”。现在,如果使用用户名“admin”和“admin+若干空格”的密码登录的话,则所有搜索该用户名的SELECT查询都将返回第一个数据记录,也就是“admin”的数据记录。这样的话,攻击者就能够以“admin”身份登录。这个攻击已经在MySQL和SQLite上成功通过测试。
-
但是正因为上述的几个关键知识点,我们可以使用“admin+若干空格”绕过第一步用户是否存在的检验而成功注册,而当登录时,“admin”等同于“admin ”,于是“admin ”则可以以“admin”成功登录系统。