sql注入及sqli-labs靶场前几关讲解

sql注入简介

SQL注入是一种常见的web安全漏洞。sql注入是通过恶意的sql查询或者添加语句插入到应用的输入参数中,再在后台sql服务器解析执行进行的攻击。

sql注入原因

在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的"数据"拼接到SQL语句中,被当作是SQL语句的一部分执行,从而导致数据库受损。是目前黑客对数据库进行攻击的最常用手段之一。

sql注入攻击对象

数据库

漏洞原因分析

web分别前端和后端,前端负责进行展示后端负责处理来自前端的请求并提供前端展示的资源。后端有资源就要有储存资源的地方——如mysql数据库。服务器需要使用SQL语句这一语法结构进行查询获取数据。

当我们访问动态网页时,Web服务器会向数据访问层发起sql查询请求,如果权限验证通过就会执行sql语句。这种网站内部直接发送的sql请求一般不会有危险,但实即情况是很多时候都需要结合用户的输入数据动态构造sql语句,如果用户输入的数据被构造成恶意的sql代码,web应用未对动态构造的sql语句使用使用的参数进行审查,就有可能导致sql注入漏洞。

web程序三层架构

三层架构是将整个业务应用划分为:

  • 界面层

  • 业务逻辑层 

  • 数据访问层

由数据库驱动的Web应用程序依次从三层架构的思想也分为了三层:

  • 表示层

  • 业务逻辑层

  • 数据访问层

sql注入及sqli-labs靶场前几关讲解_第1张图片

sql注入危害

猜解后台数据库,盗取网站敏感信息

绕过认证,例如绕过验证登录后台网站

注入可以借助数据库的存储过程进行提权等

mysql数据库

数据库

数据库的功能就是用来组织很多很多的数据。这些数据通常是存储在外存(磁盘)。数据库提供的核心功能,也就是针对数据的增删查改。数据库是一个软件,能够帮助我们在磁盘上管理数据即对数据进行增删查改。另外并不是所有的数据库都是把数据放在磁盘的。

数据表

数据表是一个临时保存数据的网络虚拟表(表示内存中数据的一个表)。它无须代码就可以简单的绑定数据库。数据表是由表名、表中的字段、表的记录三部分组成

数据库字段

字段的概念是一个成员,它表示与对象或类关联的变量。数据库字段比如说是一张二维表,有姓名性别年龄。这些就都是这些表的一个字段。

sqli-labs靶场通关详解

这里全篇以sql-labs靶场为例,对sql注入有一个更深刻的了解和认知。

mysql数据结构

系统数据库information_schema数据库中含有很重要的三张表:schemata,tables和columns。

schemata表中存储了Mysql中所有数据库的信息,包括数据库名,编码类型等,show databases的结果取之此表。

tables表中的schema_name字段为数据库名。表中存储了Mysql中所有数据库的表的信息(索引根据数据库名),show tables from schema_name的结果取之此表。 tables表有table_name和table_schema两个字段,分别为表名和表所在数据库。

columns表中存储了Mysql中所有表的字段信息,show columns from schema_name.table_name的结果取之此表。表中有column_name、table_name和table_schema三个字段,分别为字段名、字段所在表名和表所在数据库。

hackbar

hackbar插件

我们可以在火狐浏览器中安装一个hackbar插件

hackbar是浏览器中的一个插件,包含一些黑客常用的工具,比如SQL injection XSS和加密等。它的功能类似于地址栏,但是它里面的数据不受服务器的相应触发的重定向等其他变化的影响。

hackbar使用

打开一个网页按F12即可看到有hackbar选项。

sql注入及sqli-labs靶场前几关讲解_第2张图片

Load URL:复制地址栏中的地址

Split URL:剪切地址

Execute:执行hackbar中的网址

Encyption:四种加密方式

Encoding:三种编码方式

SQL:提供一些方便的查询语句

xss:提供一些XSS工具语句

Post data:以post的方式执行数据

less1-GET - Error based - Single quotes - string 基于错误的GET单引号字符型注入

字符型和数字型

没有对输入的语句进行运算即为字符型

对输入的语句进行运算了则为数字型

比如我们输入id=1 and 1=2

如果报错就是数字型不报错就是字符型

搭建靶场网上教程一搜一大把这里就不写详细过程了。打开sqli-labs靶场第一关。

sql注入及sqli-labs靶场前几关讲解_第3张图片

判断一下是否存在注入,如果存在的话是什么类型的注入。

看这个页面它提示你输入数字值的id作为参数,我们在这里输入?id=1

sql注入及sqli-labs靶场前几关讲解_第4张图片

页面出现了id=1时的用户名和密码,我们换几个id数字出现返回的结果也不一样。这证明我们输入的内容被执行了,带到了数据库里面查询了。说明存在注入漏洞。

sql注入及sqli-labs靶场前几关讲解_第5张图片
sql注入及sqli-labs靶场前几关讲解_第6张图片

接下来判断漏洞类型是字符型还是数字型。

尝试用单引号闭合出现报错。

sql注入及sqli-labs靶场前几关讲解_第7张图片

刚学的时候我会有疑问,为什么输入这样然后报错了就能确定是字符型注入?

字符型注入:当输入的参数为字符串,如果存在注入漏洞,则为字符型注入。

数字型注入:数字型不需要单引号闭合,而字符型一般需要。

本来语句是一个完整的语句,它是用单引号闭合的,然后我们输入的单引号参数,导致多出了一个单引号而让语句闭合不了,产生报错,所以我们可以判断是单引号闭合。从刚才的报错语句中我们可以猜出部分查询语句'1''和limit 0,1。其中1'是我们刚才输入的参数,它导致闭合不了所以报错了。

测试?id=1' and'1'='1

and后面肯定为真,如果是单引号字符注入不会报错。

?id=1'and '1'='2

and后面的一定为假,如果是数字型这个会被运算然后报错

如果是字符型不会被运算不会报错但是页面回显不正常。

综上所述这关为字符型。

验证一下我们在刚才输入的参数后面加上--+。--+是可以将后面的语句注释掉。一般字符型需要--+注释而数字型不需要--+注释。我们可以看到--+将我们输入的参数'注释掉了页面不再报错。

sql注入及sqli-labs靶场前几关讲解_第8张图片

因为我们的页面存在回显,我们就可以用联合查询语句来查询。

联合查询就是两个sql语句一起查询,两张表具有相同的列数且字段名是一样的。

我们首先要知道表格有几列,一般先尝试3,如果报错就是超过了列数,如果回显正常则没有超过列数。

sql注入及sqli-labs靶场前几关讲解_第9张图片
sql注入及sqli-labs靶场前几关讲解_第10张图片

我们由此可以看出有三列。

然后我们判断是第几列有回显。就是看看表格里面那一列是在页面显示的。这里注意id后面的数字要采用一个不存在的数字比如-1或者0这些。这是因为如果用存在的id会优先执行前面的语句,导致后面的查询无法回显。

sql注入及sqli-labs靶场前几关讲解_第11张图片

然后我们获取当前数据库名。

sql注入及sqli-labs靶场前几关讲解_第12张图片

union操作符与select

两个查询返回的列数必须相同,两个select语句对应列所返回的数据类型必须相同。

通常利用联合查询的特点,使原查询左边为空,是我们定义的查询结果返回出来。

就比如该表有三个字段,界面显示第2.3个字段。我们就要构造select*from users where id= - union select 1,2,3 from users 

然后2.3随便一个可以替换成任意想要的结果。这就是上面查数据库,将3位置换成了我们要查询的结果。

几个常用函数

concat()函数:用于连接字符串

group_concat(column_name):将字段的所有数据用,连接作为字符串输出。

然后我们爆表。

sql注入及sqli-labs靶场前几关讲解_第13张图片

接着爆字段名。我们通过上面查询知道当前数据库有四个表,根据表名知道可能用户的账号和密码在users表内。然后我们要做的是得到该表下的字段以及内容。

sql注入及sqli-labs靶场前几关讲解_第14张图片

通过上述操作我们可以得到两个敏感字段username和password、接下来我们要得到这两个字段里面对应的内容。

sql注入及sqli-labs靶场前几关讲解_第15张图片

我们爆出了用户名和密码这关就算完成了。查询语句不会的可以百度搜索一下。查询语句不唯一。

less2-GET - Error based - lntiger based基于错误的GET整型注入

第一步先判断是什么类型的注入。

先尝试用单引号闭合。报错。

sql注入及sqli-labs靶场前几关讲解_第16张图片

输入id=1'and'1'='1。仍然报错说明不是字符型。

sql注入及sqli-labs靶场前几关讲解_第17张图片

再测试id=1 and 1=2。页面回显不正常,由此可以判断是数字型。

sql注入及sqli-labs靶场前几关讲解_第18张图片

后面的步骤同第一关

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

先用单引号闭合测试报错。

sql注入及sqli-labs靶场前几关讲解_第19张图片

我们用id=1' and '1'='1判断回显正常说明可能是单引号闭合,排除数字型。

sql注入及sqli-labs靶场前几关讲解_第20张图片

用--+将'注释测试报错,排除单引号闭合。那就有可能是跟单引号相关的闭合方式。

sql注入及sqli-labs靶场前几关讲解_第21张图片

这里猜测用')闭合

sql注入及sqli-labs靶场前几关讲解_第22张图片
sql注入及sqli-labs靶场前几关讲解_第23张图片

由此判断闭合方式为')

后面的步骤同上。

less4-GET - Error based - Double Quotes - string基于错误的GET双引号)字符型注入

先尝试单引号闭合报错

sql注入及sqli-labs靶场前几关讲解_第24张图片

用id=1' and '1'='1.回显如下排除数字型注入。

sql注入及sqli-labs靶场前几关讲解_第25张图片

用--+注释'报错,证明不是单引号闭合应该是其他。

sql注入及sqli-labs靶场前几关讲解_第26张图片

尝试")闭合

sql注入及sqli-labs靶场前几关讲解_第27张图片
sql注入及sqli-labs靶场前几关讲解_第28张图片

由此可以判断为")字符型注入,后面操作同第一关。

less5-GET - Double lnjection - Single Quotes - string双注入GET字符型注入

先输入id=1'发现报错

sql注入及sqli-labs靶场前几关讲解_第29张图片

然后还是用上面的方法测试最后判断出是单引号闭合,字符型注入。

然后我们想要知道表格有几列,发现页面没有回显。

sql注入及sqli-labs靶场前几关讲解_第30张图片

这里我们想到了类似是布尔盲注,报错注入,时间延迟型盲注。下面我先来介绍一下分别是什么。

布尔盲注

适用环境:页面只有成功失败这两种情况,可以使用布尔盲注。

盲注步骤:

  • 使用 length()函数 判断查询结果的长度

  • 使用 substr()函数 截取每一个字符,并穷举出字符内容

?id=1' and length(database())=1 --+

sql注入及sqli-labs靶场前几关讲解_第31张图片
sql注入及sqli-labs靶场前几关讲解_第32张图片
sql注入及sqli-labs靶场前几关讲解_第33张图片

页面异常显示表明我们猜解的长度有误。页面如果显示you are in...显示正常表示我们猜解的长度正确。

可以依次猜解1.2.3直到正确。

sql注入及sqli-labs靶场前几关讲解_第34张图片
sql注入及sqli-labs靶场前几关讲解_第35张图片

猜测到8的时候回显正常,证明数据库字符长度为8.

我们查询到的结果由一个一个字符组成,每一个字符可以是数字、英文字母、特殊符号,总共有95种可能,对应的ascll编码是32-126.

使用MySQL的 substr()函数截取查询结果的第一个字符,使用 ascii()函数 将截取的字符转换成 ASCLL编码,依次判断是否等于32,33,34……126。

sql注入及sqli-labs靶场前几关讲解_第36张图片

SCLL'编码 115 对应的字符是 's',确定第一个字符是:s

然后猜解后面字符

sql注入及sqli-labs靶场前几关讲解_第37张图片

报错注入

正常情况页面只能返回用户信息不能返回其他信息。

报错注入payload

?id=1' and updatexml(1,concat(0x7e,version()),3) --+
sql注入及sqli-labs靶场前几关讲解_第38张图片

我们也可以利用报错注入显示数据库内的所有数据。

0x7e等价于~

sql注入及sqli-labs靶场前几关讲解_第39张图片

参数2包含特殊符号 ~,触发数据库报错,并将参数2的内容显示在报错信息中。

updatexml()函数的报错内容长度不能超过32个字符,我们可以用一下两种方式解决一下这个问题:

limit分页

sql注入及sqli-labs靶场前几关讲解_第40张图片

substr()截取字符

时间盲注(延时注入)

适用于页面不会返回错误信息,只会回显一种界面。其主要特征是利用sleep函数,制造时间延迟,由回显时间来判断是否报错。

利用sleep()或benchmark()等函数让mysql执行时间变长经常与if(expr1,expr2,expr3)语句结合使用,通过页面的响应时间来判断条件是否正确。if(expr1,expr2,expr3)含义是如果expr1是True,则返回expr2,否则返回expr3。

因为我们要用到这个时间盲注的时候,由于页面无法返回正确的值,所以我们只能通过if加sleep函数解决问题。

if(expr1,expr2,expr3)含义是如果expr1是True,则返回expr2,否则返回expr3。

sleep(x)函数:延迟x秒后回显

if(1=1,1,sleep(1)):1=1成立正确,结果返回1,否则延迟1秒回显。

这里有报错,我们可以利用报错注入。

先判断有几列,输入为4的时候,报错了。所以为4.

sql注入及sqli-labs靶场前几关讲解_第41张图片
sql注入及sqli-labs靶场前几关讲解_第42张图片

然后利用报错注入爆出表名

sql注入及sqli-labs靶场前几关讲解_第43张图片
sql注入及sqli-labs靶场前几关讲解_第44张图片

爆出其他与这个操作基本相同不再展示

我们还可以使用布尔盲注。先用布尔布尔盲注判读数据库有几位。

sql注入及sqli-labs靶场前几关讲解_第45张图片
sql注入及sqli-labs靶场前几关讲解_第46张图片

判断出数据库名有8位,我们可以利用burpsuite来一位一位爆破出数据库名。

sql注入及sqli-labs靶场前几关讲解_第47张图片
sql注入及sqli-labs靶场前几关讲解_第48张图片
sql注入及sqli-labs靶场前几关讲解_第49张图片
sql注入及sqli-labs靶场前几关讲解_第50张图片
sql注入及sqli-labs靶场前几关讲解_第51张图片

由此可以直到第一位是s

也可以用时间盲注 ,可以看到第一位是s有明显的延迟,当我换成a就没有延迟,所以可以判断第一位是s。

sql注入及sqli-labs靶场前几关讲解_第52张图片

sqlmap的详解我后面会再出一篇文章写。

less6-GET - Double lnjection - Double Quotes - string双注入GET双引号字符型注入

上面同样方法测试,双引号包裹后可以闭合。其他的操作同上面一关。

less7-GET - Dump into outfile - string导出文件GET字符型注入

输入id=1测试

sql注入及sqli-labs靶场前几关讲解_第53张图片

输入id=1’测试发现报错,但是没有具体的报错信息。

sql注入及sqli-labs靶场前几关讲解_第54张图片

经过测试我们发现闭合方式是'))

它只有正常显示和不正常两种状态而且没有报错信息。我们其实可以使用时间盲注和布尔盲注来爆。操作和上面关卡方法相同。但是它的页面提示有use outfile...。那就说明它开了读写权限,这关我们用sql注入读写文件来尝试一下。outfile函数可以将sql语句的结果导出再文件中

我们先查询一下导出的目录位置

我们可以查询到导出的目录位置在D:\phpstudy_pro

你可能感兴趣的:(初学者靶场通关,sql,数据库,java)