SQL约束攻击
Dec 20, 2017 09:54 · 107 words · 1 minute read
感觉最终的效果和万能密码的差不多。
简介
sql约束攻击也是针对数据库的攻击,它的作用类似于万能密码,可以实现登录任意账号,但是原理不同。
利用条件
- 注册时可以输入任意长度或者大于数据库字段限制的长度的用户名。
产生背景
假设后台处理用户注册的代码如下
<?php
//此处省略的是连接数据的代码
$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) {
// 用户名已存在
}
else {
// 将用户数据插入数据库
$query = "INSERT INTO users(username, password) VALUES ('$username','$password')";
mysql_query($query);
}
后台处理用户登录的代码如下
//此处省略的是连接数据的代码
$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$query = "SELECT * FROM users WHERE username='$username' and password='$password'";
$res = mysql_query($query);
if($res){
if(mysql_num_rows($res)>0){
echo "成功登陆"
}else{
echo "登录失败";
}
}
可以看到这两段代码都对传入的数据做了转义,万能密码肯定是不行的。但是这样就没有办法了?这里就可以用到sql约束攻击。
漏洞原理
在mysql的select语句中,下面两条语句是相同的
select * from user where username='username';
select * from user where username='username ';
亲测有效
原因就是在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。
在创建数据表的时候会用varchar(30)来限制存入数据的数据长度,如果数据长度大于30,那么大于30的部分就会被丢弃,最终存入数据库的就是原本数据的前30位。
假如用户的用户名为admin,那么我们注册一个名字大于30并且前几位等于admin的用户。例:
admin 1
注意要在最后添加一个字符,不然注册的时候会提示用户名已存在。
那么最终存入数据库的用户名就是admin加上一串空格。
现在再去登录admin用户,输入自己注册时的密码,就可以成功登录了。登陆后搜索该用户名的SELECT查询都将返回第一个数据记录,也就是原始用户的数据记录。这样的话,攻击者就能够以原始用户身份登录。
防御手法
限制用户注册的用户名长度。