博客列表 >基于约束的SQL攻击

基于约束的SQL攻击

XuanGG的博客
XuanGG的博客原创
2018年03月28日 15:59:361012浏览
//注册代码

<?php  
// Checking whether a user with the same username exists  
$username = mysql_real_escape_string($_GET['username']);  
$password = mysql_real_escape_string($_GET['password']);  
          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')";  
    .  
    .  
  }  
}
//mysql_real_escape_string 来mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
//过滤\x00 \n \r  " '  \x1a

使用以下代码验证登录信息。

<?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){  
      return $username;//此处较原文有改动  
  }  
}  
return Null;  
?>

过滤了用户输入的参数,使用单引号来增加安全性,按理说应该不会出错,然而攻击者依然能够以任意用户身份进行登录。在谈论这种攻击手法之前,首先我们需要了解几个关键知识点。在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。换句话说"vampire"等同于"avampire  ",对于绝大多数情况来说都是成立的。例如以下语句的查询结果,与使用用户名"vampire"进行查询时的结果是一样的。
SELECT * FROM users WHERE username='avampire     ';
但也存在异常情况,最好的例子就是LIKE子句了。注意,对尾部空白符的这种修剪操作,主要是在字符串比较期间进行的。这是因为,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。在所有的INSERT查询中,SQL都会根据varchar(n)来限制字符串的最大长度。也就是说,如果字符串的长度大于n个字符的话,那么仅使用字符串的前n个字符。比如特定列的长度约束为5个字符,那么在插入字符串"avampire"时,实际上只能插入字符串的前5个字符,即"avampi"。现在,让我们建立一个测试数据库来演示具体攻击过程。执行set @@sql_mode=ANSI;将数据库设置成宽松模式,在这种模式下插入数据如果不符合定义类型或长度,对数据类型调整或截断保存并警告。
1.png

2.png

为了展示尾部空白字符的修剪情况,我们可以键入下列命令。

select * from users where username = 'avampire     '   #
空格会被截断
等同于 'avampire'


诺验证知道了 存在此漏洞  可以 在注册时 使用攻击者一模一样的用户名

只需要使用用户名vampire+若干个空格+1和一个随机密码进行注册即可。

需要注意的是,在执行SELECT查询语句时,SQL是不会将字符串缩短为25个字符的。因此,这里将使用完整的字符串进行搜索,所以不会找到匹配的结果。接下来,当执行INSERT查询语句时,它只会插入前25个字符。


而 insert 插入的时候 是会缩短为25字符 varchar(25) 

等同于:SELECT username FROM users WHERE username='vampire' AND password='dddd';

3.png

约束条件 : ascil 模式

服务端部限制用户名字符长度


判断查询条件 是 username and password 而不是username  然后password 进行二次验证


参考地址

实验地址

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议