sqli-labs靶场 SQL注入学习 Less-1

GET - Error based - Single quotes - String

GET类型-基于报错的注入

类似于http://localhost/sqli-labs/Less-1/?id=1 的URL,通过查询字符串(/?id=1)中传递参数

开发人员直接将GET获取到的参数直接与SQL语句拼接,使得待执行的SQL语句可控,即可以构造非法的SQL语句,造成了SQL注入漏洞

在注入之前,先了解一下MySQL数据库中的元数据


information_schema下的表格

information_schema数据库是MySQL自带的一个虚拟信息数据库(物理上不存在),里面存储了数据库的元数据(库名、表名、列名、访问权限等)

  • schemata表:存储所有数据库的信息,其中一个字段为schema_name,记录了数据库名
  • tables表:存储数据库中表的信息,table_name列记录了表名,table_schema列记录了table_name中表名对应的数据库名
  • columns表:存储表中的列信息,有和tables表相同的table_schematable_namecolumn_name列记录了列名

注:有些数据库限制了只有root权限的用户才能访问information_schema


手工注入步骤:

1.判断是否可以注入:

i.单引号法

 SQL语法中的引号总是成对出现的,出现未成对的引号则报错

上面构成的SQL语句为

select id,username,password from users where id='1''

 ii.布尔法

 

'为闭合前面的单引号,--+注释掉后面的单引号

MySQL语法中,#和-- 用来注释单行(注意--后面还有一个空格),这里服务器会将+转化为空格

本该返回id=1的用户的信息,但什么都没有返回,说明用户输入的内容被当成SQL语句'执行

(1=2的结果为False,配合and整个where子句为False,查询条件为False)

上面构成的SQL语句为

select id,username,password from users where id=1 and 1=2

2.获取数据库指纹:

由于不同的数据库管理系统存在语法上的一些细微差异,其内部的元数据定义也可能不同。获取数据库指纹(即获取数据库管理系统的类型,如Oracle、MySQL、MariaDB、SQL Server等),能够帮助我们构造针对不同数据库的SQL语句。

有时可以通过报错让页面回显出数据库指纹

如上面的单引号法测试是否可以注入中,页面回显表明对方采用的是MySQL数据库

这里我们重点讲解手工注入的方法,故不展开数据库指纹的获取方法

3.获取元数据:

基于UNION的注入

由前面的SQL语句看出,网页请求中的select语句已经固定了(如select id,username,password),要查询我们想要的内容,可以利用UNION进行多条select语句查询

(或许你想说可以构造多条SQL语句(中间用分号;隔开),为什么要费劲用UNION去把查询语句合并起来呢?因为一般每次连接只能执行一条SQL语句)

注:UNION的语法规定前后两条select语句查询的字段数目要相同,查询的数据类型也要对应相同。

问题来了,如何判断前面那条固定的select语句查询了多少个字段呢?可以用ORDER BY

 

逐个尝试,发现到ORDER BY 4时报错,Unknown column '4' in 'order clause'

说明select语句查询了3个字段

 由于每列只能返回该列下的一条记录,而我们要获取的元数据肯定不只有一条,所以用GROUP_CONCAT()将多行的记录用逗号隔开,连成一行

a.获取数据库名

注:之所以设为id=0',是因为每次返回的记录只有一条,id=0才让固定的那个select语句查询为空,否则其将占据我们写的select语句的查询结果【自己尝试以发现区别】

select 1,1,group_concat(schema_name) 前面两个1是为了填充,使select查询3个字段

上面构成的SQL语句为

SELECT id,username,password
FROM users
WHERE id=0
UNION
SELECT 1,1,group_concat(schema_name)
FROM information_schema.schemata

b.获取表名

接下来我们试着获取security这个库下的表名

c.获取列名

接下来我们试着获取users这张表下的列名

 

4.获取用户数据 

SQL查询中需要指明在哪个数据库、哪个表、哪个列查询,所以我们才花大量精力去获取这些元数据,现在可以进行查询了

如:获取用户名和密码

此处仍然用到了group_concat()函数,也可以每次进行单条记录查询,用LIMIT

  • SELECT * FROM table_name LIMIT index,count
  • index为查询的索引值,即从哪里开始查询(默认从1开始)
  • count为查询的数量

如图返回第二条记录 


新手发文,如有错误,还望指正

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值